[CMake] Handling library interdependencies

Mark Lohry mlohry at gmail.com
Wed Jun 17 11:53:54 EDT 2009


Thanks guys, you've helped me to find the real problem :) explicitly linking
the libraries got rid of a lot of the chaff.

Looks like the core error on linking has to do with just one of the
libraries. lib1 contains two subdirectories (sublib1 & sublib2) with just a
handful of files, which are to be built into the lib1 library. These two
subdirectories have no CMakeLists.txt of their own; lib1/CMakeLists.txt
explicitly includes their code for compiling to lib1 ( sources list is like
= src1.cxx sublib1/src2.cxx sublib2/src3.cxx ).

When linking the executables to the library, the build fails, with all the
errors of the form

"in function (some func in lib1 ) undefined reference to (function in
sublib1 or sublib2)" or
"in function (some func in sublib1 or sublib2 )undefined reference to
(function in sublib1 or sublib2)" or
"in function (some func in src ) undefined reference to (function in sublib1
or sublib2)",

despite these subdirectory sources having been compiled and linked into the
static library. Any thoughts on why these subdirectories wouldn't be linking
correctly?




On Wed, Jun 17, 2009 at 12:10 AM, Michael Wild <themiwi at gmail.com> wrote:

>
> On 17. Jun, 2009, at 1:22, Mark Lohry wrote:
>
>  Thanks for the reply.
>>
>> I added "add_dependencies( lib1 lib2 )", "add_dependencies( lib2 lib1 )",
>> and "add_dependencies( execthing lib1 lib2 )" in their appropriate places,
>> and changed the libraries to STATIC, but no change.
>>
>
> First off, you're creating a cyclic dependency between lib1 and lib2. Never
> a good thing. Second, how do your libraries relate to each other? Does lib2
> use symbols from lib1? Or is it the other way round? If lib1 uses symbols
> from lib2 and lib2 from lib1, you have a design issue.
>
> For the moment, assume that lib2 uses symbols from lib2, in that case in
> lib/lib2/CMakeLists.txt you would do:
>
> include_directories( ${proj_SOURCE_DIR}/lib )
> set( lib2_SRCS
>  ..... bunch of c++ sources )
> add_library( lib2 SHARED ${lib2_SRCS} )
> # THIS ONE IS IMPORTANT!
> target_link_libraries( lib2 lib1 )
>
>
> The target_link_libraries command automatically adds a dependency of lib2
> on lib1.
>
>
>> Yes, everything compiles when i build the libraries and executables
>> separately; it fails on the link step after this, with "undefined
>> reference"
>> to every library function used.
>>
>
> Is this Windows or some kind of Unix system? If the former, have you
> exported your symbols in the library using __declspec(dllexport)? You can
> get started here: http://msdn.microsoft.com/en-us/library/9h658af8.aspx and
> http://msdn.microsoft.com/en-us/library/9h658af8.aspx
>
>
>> I'm unfamiliar with 'nm', can you be more specific as to what I should be
>> looking for?
>>
>
>
> Again, are you using Windows? In that case the tool you're looking for is
> dumpbin.exe (http://msdn.microsoft.com/en-us/library/c1h23y6c(VS.80).aspx<http://msdn.microsoft.com/en-us/library/c1h23y6c%28VS.80%29.aspx>),
> especially the options /SYMOBOLS and /EXPORTS should be of interest.
>
>
> HTH
>
> Michael
>
>
>>
>> On Tue, Jun 16, 2009 at 4:55 PM, Tyler Roscoe <tyler at cryptio.net> wrote:
>>
>>  On Tue, Jun 16, 2009 at 03:41:51PM -0500, Mark Lohry wrote:
>>>
>>>> I have a number of subdirectories, each containing source to be built
>>>>
>>> into
>>>
>>>> their own libraries, which contain many interdependencies. I'm trying to
>>>> build an executable to link against these libraries, and I'm getting a
>>>> console full of "undefined reference to..." errors on linking step. The
>>>> libraries and executable source all compile individually without issue.
>>>>
>>>> Structure is like so:
>>>>
>>>> # top-level CMakeLists.txt
>>>> project( proj )
>>>> ADD_SUBDIRECTORY( lib )
>>>> ADD_SUBDIRECTORY( src )
>>>>
>>>>
>>>> # /lib/CMakeLists.txt
>>>> ADD_SUBDIRECTORY( lib1 )
>>>> ADD_SUBDIRECTORY( lib2 )
>>>>
>>>>
>>>> # /lib/lib1/CMakeLists.txt
>>>> include_directories( ${proj_SOURCE_DIR}/lib )
>>>> set( lib1_SRCS
>>>>  ..... bunch of c++ sources )
>>>> add_library( lib1 SHARED ${lib1_SRCS} )
>>>>
>>>>
>>>> # /lib/lib2/CMakeLists.txt
>>>> include_directories( ${proj_SOURCE_DIR}/lib )
>>>> set( lib2_SRCS
>>>>  ..... bunch of c++ sources )
>>>> add_library( lib2 SHARED ${lib2_SRCS} )
>>>>
>>>>
>>>> # src/CMakeLists.txt
>>>> include_directories( ${proj_SOURCE_DIR}/lib )
>>>> set( execthing_SRCS
>>>> .... bunch of C++ sources )
>>>> add_executable( execthing ${execthing_SRCS} )
>>>> target_link_libraries( execthing lib1 lib2 )
>>>>
>>>
>>> This all looks reasonable to me, so the devil is probably in the
>>> details. Are you sure all your paths make sense? Can you use nm or
>>> dumpbin or whatever to see the "undefined" symbols in the libraries
>>> where you expect to find them?
>>>
>>> So if you build the libraries individually and then build the executable
>>> individually, everything works? You might try playing with some explicit
>>> add_dependencies() to see if there's some kind of build order problem.
>>> CMake should be smart enough to figure this out from your
>>> target_link_libraries, but maybe you have something strange going on
>>> under the covers?
>>>
>>> tyler
>>>
>>>  _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Please keep messages on-topic and check the CMake FAQ at:
>> http://www.cmake.org/Wiki/CMake_FAQ
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.cmake.org/mailman/listinfo/cmake
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20090617/d6856bee/attachment.htm>


More information about the CMake mailing list