[CMake] Configuration dependent link

Stephan Menzel stephan.menzel at gmail.com
Thu Nov 12 04:50:19 EST 2015


Hey all,

I have a few more findings about this before I finally give up and resort
my old self made approach: It looks to me like the imported target
mechanism is not propagating properties the way it could and probably
should. Es specially not like it is described here:
https://cmake.org/cmake/help/v3.4/command/target_link_libraries.html

As an example consider the following example in which I try to create an
imported target out of boost, taking the FindBoost Module as import:

set(BOOST_REQUIRED_COMPONENTS
    atomic
    chrono
    date_time
    filesystem
    iostreams
    log
    math_tr1
    program_options
    random
    regex
    serialization
    signals
    system
    unit_test_framework
    thread
)

find_package(Boost ${Boost_REQUIRED_VERSION} REQUIRED COMPONENTS
    ${BOOST_REQUIRED_COMPONENTS}
)

add_library(sys::boost SHARED IMPORTED GLOBAL)

function(add_boost_imported_target component_name)
    if (NOT DEFINED component_name)
        message(SEND_ERROR "Error, the variable 'component_name' is not
defined!")
    else()
        boost_target_name(${component_name} target prefix)

        add_library(${target} SHARED IMPORTED GLOBAL)

        set_property(TARGET ${target} PROPERTY
INTERFACE_LINK_LIBRARIES_DEBUG ${${prefix}_LIBRARY_DEBUG})
        set_property(TARGET ${target} PROPERTY
INTERFACE_LINK_LIBRARIES_RELEASE ${${prefix}_LIBRARY_RELEASE})
        set_property(TARGET ${target} PROPERTY
INTERFACE_LINK_LIBRARIES_RELWITHDEBINFO ${${prefix}_LIBRARY_RELEASE})
        set_property(TARGET ${target} PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR})
        set_property(TARGET ${target} PROPERTY INCLUDE_DIRECTORIES
${Boost_INCLUDE_DIR})

        target_link_libraries(sys::boost INTERFACE ${target})
    endif()
endfunction(add_boost_imported_target)

foreach (comp ${BOOST_REQUIRED_COMPONENTS})
    add_boost_imported_target(${comp})
endforeach()


Now as far as I can tell this should give me an IMPORTED target called
sys::boost and create a number of sub-targets for each boost components.
This appeared necessary to me as there is no way to have one sys::boost
with multiple IMPLIBs on it.

Alas, the target doesn't contain any libs at all:

get_target_property(libs sys::boost LINK_LIBRARIES_DEBUG)
message ("boost link:  ${libs}")

will yield empty output. However the manual clearly states that

"Usage requirements are propagated by reading the INTERFACE_ variants of
target properties from dependencies and appending the values to the non-
INTERFACE_ variants of the operand."

So INTERFACE_LINK_LIBRARIES_DEBUG of, say, sys::boost_atomic should appear
as LINK_LIBRARIES_DEBUG of sys::boost_atomic. Which is not the case and in
my opinion a bug.

Which means I cannot have imported targets depending on each other (and
propagating their libs) to create a structure with multiple implibs, nor
can I put multiple implibs in one imported target. At least not for MSVC.
As much as I liked the approach of IMPORTED libs, this forces me to go back
to the self made scripts.
I just wanted to put it out here in case anybody attempts the same.

Cheers,
Stephan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20151112/17d4cd2a/attachment.html>


More information about the CMake mailing list