[CMake] How to get a list of all the static libraries that a target will link against ?

Glenn Coombs glenn.coombs at gmail.com
Wed Jul 23 05:10:39 EDT 2014


I think I have found a way to work round this.  Instead of trying to get a
list of all the static libraries that a target will link against I will
modify the various libraries so that they add their library dependencies
like this:

    target_link_libraries(mtx_wrapper PUBLIC

$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:-Wl,-whole-archive>
        ${MTXSIM_LIBRARIES}

$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:-Wl,-no-whole-archive>
        $<$<STREQUAL:$<CXX_COMPILER_ID>,GNU>:dl>
        $<$<STREQUAL:$<CXX_COMPILER_ID>,Clang>:dl>

This should mean that all the dependent libraries get wrapped inside
-whole-archive/-no-whole-archive pairs when the target being linked is a
shared library.  And if the target being linked is an executable then the
-whole-archive/-no-whole-archive options should automatically be omitted.
Initial tests indicate that this approach will work but I have encountered
a bug which slightly complicates the issue:

http://www.cmake.org/Bug/view.php?id=15034

Essentially, the -no-whole-archive option sometimes gets omitted unless
prefixed by some other command.

--
Glenn



On 21 July 2014 19:24, Angeliki Chrysochou <angeliki.chrysochou at gmail.com>
wrote:

> Well try it and see if it works. If you set this variable in a specific
> CMakeLists file, it will affect the specific add_library (or
> add_executable) that is in that CMakeLists file. With this way you can
> control which libraries/executables will be linked with these flags, and
> this is the level of control you have.
>
> Cheers!
> Angeliki
>
>
>
> On Mon, Jul 21, 2014 at 7:05 PM, Glenn Coombs <glenn.coombs at gmail.com>
> wrote:
>
>> The problem is that I need to add both -whole-archive and
>> -no-whole-archive options.  And I need to control exactly where they occur
>> so that only my libraries occur inside the whole archive section.  I'd be
>> happy to be proven wrong but I don't think setting CMAKE_EXE_LINKER_FLAGS
>> will give me that level of control.
>>
>> --
>> Glenn
>>
>>
>> On 21 July 2014 09:57, Angeliki Chrysochou <angeliki.chrysochou at gmail.com
>> > wrote:
>>
>>> Hi Glenn,
>>>
>>> Adding linker flags exactly in target_link_libraries is not a very good
>>> practice in my opinion. To add specific linker flags to an executable, you
>>> can use the variable CMAKE_EXE_LINKER_FLAGS, which you can edit before
>>> calling add_executable. You could set this variable accordingly in your
>>> static and dynamic CMakeLists.txt to include the flags you wish in the
>>> following way:
>>>
>>> set(CMAKE_EXE_LINKER_FLAGS "-whole-archive")
>>>
>>> If you set this variable to include more custom linker flags which you
>>> want to preserve across libraries, then you should set it in the following
>>> way to preserve its old value:
>>>
>>> set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -whole-archive")
>>>
>>> If you want to edit linker flags for a shared library or a module target
>>> you can use these cmake variables (set them before add_library):
>>>
>>> CMAKE_SHARED_LINKER_FLAGS
>>> CMAKE_MODULE_LINKER_FLAGS
>>>
>>> Be aware that variables have CMakeLists.txt file scope, so if you set
>>> different values in one CMakeLists.txt then they might get overwritten or
>>> appended (depending on the way you edit the variable).
>>>
>>> All the best,
>>> Angeliki
>>>
>>>
>>>
>>>
>>>
>>> On Sat, Jul 19, 2014 at 2:39 PM, Glenn Coombs <glenn.coombs at gmail.com>
>>> wrote:
>>>
>>>> Don't all shout at once :-)  I'm guessing there are no easy solutions
>>>> then...
>>>>
>>>> --
>>>> Glenn
>>>>
>>>>
>>>> On 28 June 2014 14:33, Glenn Coombs <glenn.coombs at gmail.com> wrote:
>>>>
>>>>> I have a project which compiles and links into both a stand alone
>>>>> executable and a dynamic shared library.  The library and the executable
>>>>> link against the same project libraries but have different object files
>>>>> containing their entry points: main.o for the executable and dll_main.o for
>>>>> the library.  My project heirarchy looks like this (simplified a bit for
>>>>> brevity):
>>>>>
>>>>> CMakeLists.txt
>>>>>     mtx_source/CMakeLists.txt
>>>>>     mtx_wrapper/CMakeLists.txt
>>>>>     testbench/CMakeLists.txt
>>>>>
>>>>> The top level CMakeLists.txt calls add_subdirectory on the various
>>>>> project specific library folders which each build a static library.  The
>>>>> testbench folder is the one that builds both the executable and the dynamic
>>>>> library.  When building the dynamic library I need to use the linker
>>>>> options -whole-archive and -no-whole-archive to force my static project
>>>>> libraries to be included into the dynamic library. The problem is how to
>>>>> insert the -whole-archive and -no-whole-archive options so that they select
>>>>> the correct set of libraries.  Currently in the testbench CMakeLists.txt
>>>>> file I have these lines:
>>>>>
>>>>> set(libs
>>>>>     VLC
>>>>>     mvea
>>>>>     ${SYSTEMC_SUPPORT_LIBRARIES}
>>>>>     ${DEVIFSLAVE_LIBRARIES}
>>>>>     ${SYSTEMC_LIBRARIES}
>>>>>     ${SIM_UTILS_LIBRARIES}
>>>>>     ${HWDEBUG_LIBRARIES}
>>>>> )
>>>>>
>>>>> if (NOT STUB_OUT_MTX)
>>>>>     list(APPEND libs mtx_wrapper)
>>>>> endif()
>>>>>
>>>>> set(libs_dll ${libs} transif_slave)
>>>>>
>>>>> if (UNIX)
>>>>>     list(INSERT libs_dll 0 -Wl,-whole-archive)
>>>>>     list(APPEND libs_dll   -Wl,-no-whole-archive)
>>>>> endif()
>>>>>
>>>>> add_library ( csim_dll SHARED ${sources_dll} ${headers_dll} )
>>>>> add_executable( testbench       ${sources}     ${headers}     )
>>>>>
>>>>> target_link_libraries(csim_dll  ${libs_dll} ${PTHREADS_LIBRARIES} )
>>>>> target_link_libraries(testbench ${libs}     ${PTHREADS_LIBRARIES} )
>>>>>
>>>>> which produces the following link line:
>>>>>
>>>>> /usr/bin/g++-4.7  -fPIC -m32  -m32 -m32 -fPIC -m32 -O3  -O3
>>>>> -DHIDEBUG
>>>>> -Wl,-Bsymbolic
>>>>> -shared -Wl,-soname,libtopazhp.so
>>>>> -o libtopazhp.so
>>>>> CMakeFiles/csim_dll.dir/dll_main.cpp.o
>>>>> CMakeFiles/csim_dll.dir/main_common.cpp.o
>>>>> -lm -lrt -lm -lrt
>>>>> -Wl,-whole-archive
>>>>> ../mvea/VLC/libVLC.a
>>>>> ../mvea/libmvea.a
>>>>> ../systemCSupport/libsystemc_support.a
>>>>> ../devif_slave/libDevifSlave.a
>>>>> ../systemC/libsystemc.a
>>>>> ../sim_utils/libsim_utils.a
>>>>> ../hwdebug/libhwDebug.a
>>>>> ../mtx_wrapper/libmtx_wrapper.a
>>>>> ../transif/libtransif_slave.a
>>>>> -Wl,-no-whole-archive
>>>>> -lpthread -lz
>>>>> ../systemC/libpthreads_dummy.a
>>>>> ../external_mtx/src/external_mtx-build/metag/libmetag.a
>>>>> ../external_mtx/src/external_mtx-build/metagcopro/libmetagcopro.a
>>>>> ../external_mtx/src/external_mtx-build/metac/vmetastub/libvmetastub.a
>>>>> ../external_mtx/src/external_mtx-build/metac/insim/libinsimfpu.a
>>>>> ../external_mtx/src/external_mtx-build/mtx/insim-mtxg/libinsim-mtxg.a
>>>>> ../external_mtx/src/external_mtx-build/mtx/libmtxc.a
>>>>> -ldl -lm -lrt -lm -lrt
>>>>>
>>>>> The problem is that the 6 external_mtx libraries should have been
>>>>> included inside the -whole-archive section.  These libraries are specified
>>>>> in the mtx_wrapper folder with a target_link_libraries(mtx_wrapper
>>>>> ${METASIM_LIBRARIES}) command.  I have managed to wrap the direct library
>>>>> dependencies inside the -whole-archive but I need to ensure that any
>>>>> sub-dependencies are included as well (and any dependencies they might have
>>>>> recursively).  Any system dynamic libaries (-ldl -lm -lrt etc.) must appear
>>>>> after the -no-whole-archive option otherwise the link fails.  The
>>>>> mtx_wrapper library can be built in two ways and only one of them will add
>>>>> the extra METASIM libraries as a dependency, the other way fakes that code
>>>>> internally.  Adding the METASIM libraries via target_link_libraries()
>>>>> inside the mtx_wrapper CMakeLists.txt correctly handles that dependency
>>>>> when linking the standalone executable but is not working for linking the
>>>>> dynamic library.
>>>>>
>>>>> Is there an easy way to get cmake to handle all this ?  Is there a way
>>>>> to get a list of all the static libraries (libXXX.a) that will be included
>>>>> on the link line for a target ?
>>>>>
>>>>> --
>>>>> Glenn
>>>>>
>>>>>
>>>>
>>>> --
>>>>
>>>> Powered by www.kitware.com
>>>>
>>>> Please keep messages on-topic and check the CMake FAQ at:
>>>> http://www.cmake.org/Wiki/CMake_FAQ
>>>>
>>>> Kitware offers various services to support the CMake community. For
>>>> more information on each offering, please visit:
>>>>
>>>> CMake Support: http://cmake.org/cmake/help/support.html
>>>> CMake Consulting: http://cmake.org/cmake/help/consulting.html
>>>> CMake Training Courses: http://cmake.org/cmake/help/training.html
>>>>
>>>> Visit other Kitware open-source projects at
>>>> http://www.kitware.com/opensource/opensource.html
>>>>
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://public.kitware.com/mailman/listinfo/cmake
>>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20140723/6b782a07/attachment.html>


More information about the CMake mailing list