Rupert Madden-Abbott
Rupert Madden-Abbott

Reputation: 13278

How to store C library dependencies in version control?

Coming from a Rails background, I am used to being able to specify the dependencies of my application in a Gemfile which is checked into my git repo. When my app gets pulled, the user just needs to run bundle install and they have all of the necessary dependencies.

In this answer, the community seems to agree that C libraries should not get checked into source control. This makes sense (after all the Gems themselves aren't checked in under Rails) but it still creates a problem. If I write some code and include a new dependency on a user created library, how can I express this dependency in the source control?

Upvotes: 3

Views: 668

Answers (2)

Jack Kelly
Jack Kelly

Reputation: 18667

Obviously, things in the C world are a little different because you don't need the source at runtime. The general way things are done on GNU/Linux (and many other *ix) systems is that some configuration step is performed using a configuration script or program. The most common of these is the famous configure script, generated by GNU autoconf. The autotools generate a lot of cache files and copy a lot of auxiliary scripts into your source tree, so remember to set up .gitignore or you'll go crazy.

A great many libraries install control files for pkg-config in $prefix/lib/pkgconfig or $prefix/share/pkgconfig. These are read by the pkg-config tool to check for the existence of libraries and get the correct compiler and linker flags for that library. They're plain text, so have a look in /usr/lib/pkgconfig to get an idea of what these look like.

In autoconf, a file configure.ac is compiled into configure by invoking the macro processor m4 (through a wrapper called autoconf). To check for a library which works with pkg-config, things are really easy. You add something like the following to configure.ac

# Checks for libraries.
PKG_CHECK_MODULES([GLib], [glib-2.0])

This will check that pkg-config is installed and then use it to check for the package glib-2.0, printing the message Checking for GLib... along the way. It will also set the shell variables GLib_CFLAGS and GLib_LIBS, and arrange for them to be substituted into any files created by AC_CONFIG_FILES (such as your Makefile, from Makefile.in). If it doesn't find glib, configure will fail with an error. Have a look at /usr/share/aclocal/pkg.m4 to find the definition of PKG_CHECK_MODULES, which supports a few other options. Documentation is in the pkg-config(1) man page.

If your dependant library doesn't have pkg-config support, sometimes the library vendor provides an autoconf macro. Old versions of SDL, for example, provided AM_PATH_SDL, but new versions just use pkg-config.

If there's no support from the vendor, sometimes there's third-party support at the autoconf archive. The autoconf archive is available as a package in Debian GNU/Linux and MacPorts (and probably many other systems), which means that any needed definitions can be used without copying .m4 files around by hand.

If none of the above are true, then check for a header using something like AC_CHECK_HEADER and check for the library using something like AC_CHECK_LIB.

Upvotes: 3

Navaneeth K N
Navaneeth K N

Reputation: 15501

the community seems to agree that C libraries should not get checked into source control.

Depends on the library you use. For example, when I use Sqlite, I check in the sqlite files on my version control and build it with my source files. This is easy as sqlite comes with one source file and a header. This won't be practical if the library has more files.

but it still creates a problem. If I write some code and include a new dependency on a user created library, how can I express this dependency in the source control?

On Linux, this is handled using autotools. Using that, you can specify the packages to use with and the configure will try to find it when building. If you are looking for a cross platform solution, CMake is the best tool. These tools can find the packages installed on standard locations (/usr/lib & /usr/include) and also provides a way to adjust the search patch.

Upvotes: 2

Related Questions