[CMake] Re: Lib dependencies discovery

Matthew Woehlke mw_triad at users.sourceforge.net
Tue Apr 24 20:04:15 EDT 2007


Pascal Fleury wrote:
> How do I figure out that mylib.(a|lib) needs, e.g., the ws2_32.lib on Windows 
> or the sockets.so on linux ? I just found the mylib_LIB_DEPENDS variable in 
> the cache, but it is in a section that says internal, and it does not seem to 
> be the portable way to do it.

The autotools way would be to write a test program, and use TRY_COMPILE 
to walk a list of libraries that might allow the program to compile. 
 From that, you set a variable to the name of the library that provides 
the needed feature, and then use either LINK_LIBRARIES (not preferred) 
or TARGET_LINK_LIBRARIES.

In my project, I wrote this macro:

MACRO(CHECK_LIBRARY LIB_NAME LIB_DESC LIB_TEST_SOURCE)
     SET(HAVE_${LIB_NAME})
     MESSAGE(STATUS "Checking for ${LIB_DESC} library...")
     TRY_COMPILE(HAVE_${LIB_NAME} ${CMAKE_BINARY_DIR}/.cmake_temp
                 ${CMAKE_SOURCE_DIR}/cmake/${LIB_TEST_SOURCE})
     IF(HAVE_${LIB_NAME})
         # Don't need one
         MESSAGE(STATUS "Checking for ${LIB_DESC} library... none needed")
     ELSE(HAVE_${LIB_NAME})
         # Try to find a suitable library
         FOREACH(lib ${ARGN})
             TRY_COMPILE(HAVE_${LIB_NAME} ${CMAKE_BINARY_DIR}/.cmake_temp
                         ${CMAKE_SOURCE_DIR}/cmake/${LIB_TEST_SOURCE}
                         CMAKE_FLAGS -DLINK_LIBRARIES:STRING=${lib})
             IF(HAVE_${LIB_NAME})
                 MESSAGE(STATUS "Checking for ${LIB_DESC} library... 
${lib}")
                 SET(HAVE_${LIB_NAME}_LIB ${lib})
             ENDIF(HAVE_${LIB_NAME})
         ENDFOREACH(lib)
     ENDIF(HAVE_${LIB_NAME})
     # Unable to find a suitable library
     IF(NOT HAVE_${LIB_NAME})
         MESSAGE(STATUS "Checking for ${LIB_DESC} library... not found")
     ENDIF(NOT HAVE_${LIB_NAME})
ENDMACRO(CHECK_LIBRARY)

...the LIB_NAME param controls the name of the variable(s) that are set 
if it finds the library. LIB_DESC is used for the status messages. An 
example usage might be:

CHECK_LIBRARY(SCK socket scktest.c socket xnet ws2_32)

(xnet is IIRC the lib used on Solaris, which illustrates why you 
probably shouldn't just use something based on IF(UNIX)/IF(WIN32).)


I don't know if there is a canonical better way; there is 
CHECK_FUNCTION_EXISTS, but I can imagine that tripping up on some 
platform where the function seems to exist but can't be called.

There certainly might be a module for any particular library you are 
interested in.

-- 
Matthew
PIE INCOMING!!!



More information about the CMake mailing list