Saturday, March 8, 2008

Problems Compiling CFEngine With Static Libraries

Here's a little weekend trick for you :)

I ran into this while compiling the latest version of cfengine. If you've ever built it, you know that two of its prerequisites are having access to includes and library files from openssl and Berkely db during configure and compile time. We visited the one program with a heavy take on building the db package in a previous post.

So, with the assumption that you've already installed Berkeley db and openssl and are now ready to configure cfengine, the first hurdle is easy enough to get around. If your libraries and includes are in standard places (like /usr/lib and /usr/include) it isn't even a hurdle at all. However, if you've built your Berkeley db and openssl software into special directories, you'll need to pass at least one of these two options to configure:

host # ./configure --with-berkeleydb=/some/dir/db --with-openssl=/some/dir/openssl

That part's simple to figure out, because

host # ./configure --help

will tell you what flags you need to pass after you get the error during configuration. Of course, reading the INSTALL and/or README file first would help with that, too ;)

The second hurdle is a little less obvious, and may not happen to everyone. It has to do with how you compiled your Berkeley db and openssl source. If you compiled them to have shared libraries, you won't run into this issue. However, if you compiled them with static libraries, the cfengine "make" process will balk when it gets to the point that it call those libraries. You would see an error similar to:

Undefined error dlopen -- undefined symbol...blah, blah, blah

This is because it won't, or can't, deal with the static libraries you've compiled for db and openssl.

The good news is that you can get around this fairly easily by setting the following two variables in your shell and just restarting the "make."

host # BERKELEY_DB_LIB="/some/dir/db/lib/libdb-4.5.a -lrt"
host # OPENSSL_LIB_LIB="/some/dir/openssl/lib/libcrypto.a -ldl"

and then running make with the -e flag, which will give your environment variables (set above) precedence over variables set in the Makefile.

It's important to note that some systems (generally older ones, like Solaris 2.6) don't have the -lrt (librt) library. In these cases, just use -ldl for both the db and openssl evironment variables.

After that, it's all icing :)


, Mike