June 20, 2016

Git branching fswatch to test c compilation

Sometimes you'll need to work an a specific branch from a git repository to help people test their software. I tried to work and play a bit with the fswatch program. I had some issues and decided to assist a little with a specific issue. To work on git branches you'll need some help if you're not used to git, or if you don't remember the commands by heart. Here's discussion on branching. To get things going on the fswatch project clone the project and get your specific branch

$ git clone https://github.com/emcrisostomo/fswatch.git
$ git branch -v -a # listing all branches
* hotfix/1.9.3
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/feature/improve-filters
  remotes/origin/gh-pages
  remotes/origin/hotfix/1.9.3
  remotes/origin/master
$ git checkout -b hotfix/1.9.3
$ git fetch origin
$ git pull origin hotfix/1.9.3
From https://github.com/emcrisostomo/fswatch
 * branch            hotfix/1.9.3 -> FETCH_HEAD
Updating a79113a..28b8998
Fast-forward
 libfswatch/NEWS                              | 4 ++++
 libfswatch/m4/libfswatch_version.m4          | 2 +-
 libfswatch/src/libfswatch/c/cevent.h         | 4 ++--
 libfswatch/src/libfswatch/c/cmonitor.h       | 2 +-
 libfswatch/src/libfswatch/c/libfswatch.h     | 1 +
 libfswatch/src/libfswatch/c/libfswatch_log.h | 2 +-
 m4/fswatch_version.m4                        | 2 +-

 7 files changed, 11 insertions(+), 6 deletions(-)

This gives you the branch 1.9.3 to check errors against. For fswatch you'll need to build and configure.


$ ./autogen.sh 
$ ./configure 
$ make
$ sudo make install

The above builds fswatch. To use the installed build with your test program, fire up gcc (not g++) as we're testing for plain c compatibility. Remember to point gcc and ld to the installed version of libfswatch.

$ gcc -I /usr/local/include -o "fswatch_test" fswatch_test.c /usr/local/lib/libfswatch.a 
In file included from fswatch_test.c:3:
In file included from /usr/local/include/libfswatch/c/libfswatch.h:33:
/usr/local/include/libfswatch/c/cevent.h:94:59: error: must use 'enum' tag to refer to type
      'fsw_event_flag'
  FSW_STATUS fsw_get_event_flag_by_name(const char *name, fsw_event_flag *flag);
                                                          ^
/usr/local/include/libfswatch/c/cevent.h:105:39: error: must use 'enum' tag to refer to type
      'fsw_event_flag'
  char *fsw_get_event_flag_name(const fsw_event_flag flag);
                                      ^
/usr/local/include/libfswatch/c/cevent.h:118:5: error: must use 'enum' tag to refer to type
      'fsw_event_flag'
    fsw_event_flag * flags;
    ^
In file included from fswatch_test.c:3:
In file included from /usr/local/include/libfswatch/c/libfswatch.h:35:
/usr/local/include/libfswatch/c/cfilter.h:47:5: error: must use 'enum' tag to refer to type
      'fsw_filter_type'
    fsw_filter_type type;
    ^
/usr/local/include/libfswatch/c/cfilter.h:57:5: error: must use 'enum' tag to refer to type
      'fsw_event_flag'
    fsw_event_flag flag;
    ^
In file included from fswatch_test.c:3:
/usr/local/include/libfswatch/c/libfswatch.h:102:37: error: must use 'enum' tag to refer to
      type 'fsw_monitor_type'
  FSW_HANDLE fsw_init_session(const fsw_monitor_type type = system_default_monitor_type);
                                    ^
/usr/local/include/libfswatch/c/libfswatch.h:102:59: error: C does not support default
      arguments
  FSW_HANDLE fsw_init_session(const fsw_monitor_type type = system_default_monitor_type);
                                                          ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 errors generated.

Sadly, there are still some errors in the plain C compilation of the branch. The last two are based on one of the main differences between plain C and C++. As C does not support default variable assignments to function parameters.

The other issues are based on the same issue, that the enum tag should be used (like the struct tag) when using enums as parameters. Which makes you wonder if the program was ever tested for C compatibility using gcc? most likely it was tested using g++ which compiles like a charm.

[Edit Wed 6 July 2016]

Fixing the issues in the C branch and linking with the correct lib will ensure the test program runs as expected, and prints the callback. To correctly build the test program all you need is:


$ gcc -I /usr/local/include -o "fswatch_test" fswatch_test.c /usr/local/lib/libfswatch.dylib

Notice the difference in the command above, we link against the *.dylib version instead of the static *.a lib. This will ensure that all the missing c++ symbols are found dynamically. Next, well test the program. Start a new shell and start the fswatch_test program. Then in a different terminal touch the file watched by the test program

In terminal 1
$ ./fswatch_test

In terminal 2
$ touch ~/Documents/src/bash/map_network_drives.sh 
$ touch ~/Documents/src/bash/map_network_drives.sh 

In terminal 1
my_callback: 1
my_callback: 1
^C

The program seems to be running, the callback is called at every touch. Now we need to create a patch against the origin to get the fixes into the main branch. But first lets the the changes into the hotfix branch.

$ git add libfswatch/src/libfswatch/c/cevent.h 
$ git add libfswatch/src/libfswatch/c/cfilter.h 
$ git add libfswatch/src/libfswatch/c/libfswatch.h 
$ git commit -m "Fixed headers for c compilation"
[hotfix/1.9.3 f9222ae] Fixed headers for c compilation
 3 files changed, 6 insertions(+), 6 deletions(-)
$ git push --set-upstream origin hotfix/1.9.3

There, the changes should now be in the hotfix branch safely tugged away. This means we can create a pull request, done by clicking the 'compare & pull request" button in the branch. Then all we have to do is wait. The patching thing is handled by git so we won't have to do it the diff way. Changes to the fswatch_test.c are pushed to the playground repository.



No comments: