cmake and shared libraries existing also in standard locations

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
Report Content as Inappropriate

cmake and shared libraries existing also in standard locations

René J.V. Bertin


I just had a run-in with a cmake-based project that found the correct libpng binary during the configure phase but for a rather nasty reason tried to link to another version installed elsewhere. That was on Linux, but there's no guarantee that the same issue cannot occur on OS X.

- find(PNG) correctly set PNG_LIBRARIES to `$prefix/lib/libpng.dylib:$prefix/lib/libz.dylib`
- however, the compiler/linker command had `-lpng -lz` instead, and no preceding -L$prefix/lib and thus found libpng in a standard location (I learned that CMake calls those "implicit link directories").

Normally this would have been fine because "base" sets LIBRARY_PATH to $prefix/lib, and indeed that suffices with gcc. Not so with clang (tested only with 4.0).

When diagnosing this I noticed that
- gcc translates LIBRARY_PATH=/path to -L/path BEFORE the first -lfoo option on the actual linker commandline
- clang does something similar, but adds the -L/path AFTER the -lfoo options given by the user.

IOW, with clang, LIBRARY_PATH only affects the search path for libraries added automatically, not those specified by the user.

To cut a long story short, it is possible to deactivate this automatic libspec rewriting (see the `CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES` documentation) by setting policy CMP0060 to NEW.

I've done this in the still-pending update to my cmake-1.1 PG by adding `-DCMAKE_POLICY_DEFAULT_CMP0060=NEW` to the default configure.args list.

In the case of the project in question (and linking to libpng in general), one also avoids the issue by using `PNG::PNG` instead of `${PNG_LIBRARIES}`.