tags:

views:

429

answers:

4

As a follow up question to my last one, is there any simple way to tell if a given C library is installed on a given machine (not programattically, just as a once off sort of thing)? I need to use libuuid, but I'm not sure if it's installed on the machines in question. The only two ways I can think of are:

1) Try to compile the code there (more work than I'd like to do)

2) Try something like "man libuuid" although seems like this wouldn't always be reliable if for some reason the manpages didn't get installed.

Is there some better other way?

+7  A: 

Have you considered using autoconf? It's designed to check and see whether the build environment is set up correctly.

Mehrdad Afshari
Not really familiar with it at all, and from looking at the command arguments, I'm not really sure how it helps me solve my problem. Additional info would definitely be appreciated.
Morinar
Look at the documentation I've linked to. Your problem is the basic use-case for `autoconf`. `autoconf` will take a `configure.ac` file and outputs a `configure` shell script.
Mehrdad Afshari
@Morinar - Using autoconf and automake are not intuitive, and unclear at first, and you may feel like beating your head against a wall and/or writing your own auto configuration tool, but after a while you'll figure out how they work. As someone who very recently had to go through this process, I assure you this is the best way to do this kind of thing.
Chris Lutz
@Chris Lutz, it's the best way but unfortunately it's still a horrible way.
dreamlax
@dreamlax - No argument there. @Mehrdad - Perhaps your answer would be improved if you posted a sample showing how to use `autoconf` ? Obviously you can't explain `autoconf` in a single StackOverflow answer, but you could at least get him started.
Chris Lutz
Chris: I agree but I don't think I'm able to describe that better than the documentation does, especially since I don't know what the actual goal is. I mean I've no idea what the OP wants to do if the library was unavailable.
Mehrdad Afshari
A: 

The autotools, as mentioned, checks for symbols within libraries. The way it does it is somewhat simple. As you mention in 1), autoconf, and its result the configure script, basically creates a dummy c program and attempts to link with the library in question. If it works, the library works, if it fails, obviously it wont work. Autoconf looks for specific symbols/function names in the library though.

KFro
What autoconf does is sensible: you are not merely looking for a particular (library) file - you are looking for a particular function that is normally found in that library. Anyone can create a library called libuuid.so (libuuid.a); if the library doesn't contain the function you are looking for, that library is no help whatsoever.
Jonathan Leffler
+1  A: 

The simplest way is to invoke ld with the -l option. This will effectively test the existence of the library, searching the standard library locations automatically:

$ ld -luuid
ld: warning: cannot find entry symbol _start; not setting start address
$ echo $?
0

$ ld -luuidblah
ld: cannot find -luuidblah
$ echo $?
1

# so...
$ ld -luuid 2>/dev/null && echo "libuuid exists" || echo "libuuid not found"

EDIT

As dreamlax pointed out, this does not work for all unix variants. I don't know if it will work on all unixes (I've tested linux and OpenBSD) but you can try this instead:

$ echo "int main(){}" | gcc -o /dev/null -x c - -luuid 2>/dev/null
$ echo $?
0

$ echo "int main(){}" | gcc -o /dev/null -x c - -luuidblah 2>/dev/null
$ echo $?
1
mhawke
That's not consistent. On my Mac, `ld` returns 1 in both cases.
dreamlax
@dreamlax: that's a shame. Still should be possible to decide by looking at the stderr of the command, and this may not be a problem for the OP given his unix targets are AIX, Sun, and HP (mentioned in his previous question).
mhawke
Your second solution (OS X here too) suffers from the same problem. I would call this the fault of OS X's `ld` but it's still a problem.
Chris Lutz
Or might it be a problem with the Mach-O format? I don't really know enough about these things.
dreamlax
That tells you whether the library is in the standard places; it does not tell you whether the library is in non-standard places. And it is not clear whether it works for 'semi-standard' places like /usr/local/lib.
Jonathan Leffler
Considering the experiences of others on different platforms, its seems that this is not the right soluion. @Jonathan Leffler: without some prior knowledge, how are you going to find it in non-standard places anyway? `ld` by itself will search the standard directories, whatever is set in the LD_LIBRARY_PATH environment variable as well as user supplied paths specified in the `-L` option to ld/gcc. But you'd still need to know where these non-standard places are. `gcc -print-search-dirs` will report the library paths searched, and maybe a solution can be crafted using that.
mhawke
+1  A: 

Here's what I did using autoconf, which I'm showing here as a solid example for whoever else might come by next:

I created the file configure.ac which contained the following:

AC_INIT(package, 1.1, email)
AC_CHECK_LIB(uuid, uuid_generate_random, [echo "libuuid exists"], [echo "libuuid missing"])

I then ran the following commands in order (same folder I made configure.ac):

autoconf
./configure

At the end of the configure, it spat back whether or not it had found uuid_generate_random in the uuid library. Seemed to work perfectly (although unfortunately, two of the OSes were missing the library, but that's a whole other problem).

For anybody who may find this after the fact, the AC_INIT arguments here are throwaways and you can copy them wholesale. The arguments to AC_CHECK_LIB are: library name, the name of a function in that library, what to do on success, what to do on failure.

Even though Mehrdad's answer wasn't quite as helpful as I would have liked (i.e. to not have spent time trolling the docs) it seems to be the correct one and I'll be accepting it. mhawke: I really liked your answer, but I wasn't quite sure how to test to make sure it worked. It seemed to on SunOS, but always said no on the other two (AIX, HPUX) and I couldn't seem to come up with a library off the top of my head I could guarantee it would find.

Thanks for the help guys.

Morinar