Transitive target_include_directories on OBJECT libraries

后端 未结 4 1294
北恋
北恋 2021-01-01 12:18

Here is snippet from make CMakeLists.txt:

add_library(foo-object OBJECT src/foo.cpp)
target_include_directories(foo-object PUBLIC include)
add_library(foo SH         


        
相关标签:
4条回答
  • 2021-01-01 12:34

    For me something like the following seems to be working:

    add_library(foo_objects OBJECT src/foo.cpp src/foo.hpp)
    set_property(TARGET foo_objects PROPERTY POSITION_INDEPENDENT_CODE ON)
    target_include_directories(foo_objects PUBLIC
        "$<BUILD_INTERFACE:src>"
        "$<INSTALL_INTERFACE:include>")
    
    add_library(foo_shared SHARED)
    add_library(foo_static STATIC)
    target_link_libraries(foo_shared PUBLIC foo_objects)
    target_link_libraries(foo_static PUBLIC foo_objects)
    
    0 讨论(0)
  • 2021-01-01 12:35

    It seems that transitive properties only work when targets are linked through a chain of target_link_library calls. In your case, you do not have such a link between foo-object and foo.

    If you add a source file to foo, that one should also not be able to see the include directory from foo-object.

    This might be an oversight in the design of OBJECT libraries, as it essentially breaks the transitive properties for those.

    0 讨论(0)
  • 2021-01-01 12:41

    Hm, at the moment I came up with following:

    add_library(foo-object OBJECT src/foo.cpp)
    target_include_directories(foo-object PUBLIC include)
    
    get_property(object_include_dirs TARGET foo-object PROPERTY INCLUDE_DIRECTORIES)
    get_property(object_link_libs TARGET foo-object PROPERTY LINK_LIBRARIES)
    
    add_library(foo SHARED $<TARGET_OBJECTS:${PROJECT_NAME}-object>)
    target_include_directories(foo PUBLIC ${object_include_dirs})
    target_link_libraries(foo PUBLIC ${object_link_libs})
    
    add_library(foo_static STATIC $<TARGET_OBJECTS:${PROJECT_NAME}-object>)
    target_include_directories(foo_static PUBLIC ${object_include_dirs})
    target_link_libraries(foo_static PUBLIC ${object_link_libs})
    

    but come on, there must be better way :/

    0 讨论(0)
  • 2021-01-01 12:47

    On CMake <3.12, use the following:

    add_library(foo SHARED $<TARGET_OBJECTS:${PROJECT_NAME}-object>)
    target_include_directories(foo
        PRIVATE
        $<TARGET_PROPERTY:${PROJECT_NAME}-object,INTERFACE_INCLUDE_DIRECTORIES>)
    

    On CMake >=3.12, take a look at this answer (thanks @ian5v for the suggestion)


    How it works:

    target_include_directories(...)

    ...

    PUBLIC and INTERFACE items will populate the INTERFACE_INCLUDE_DIRECTORIES property of <target>.

    Therefore ${PROJECT_NAME}-object has INTERFACE_INCLUDE_DIRECTORIES set on it. We need to fetch this property and insert it into our own include path.

    This looks like a job for "generator expressions"!. In particular, $<TARGET_PROPERTY:tgt,prop> looks like it will come in handy here.

    Our tgt will be ${PROJECT_NAME}-object, and we're trying to extract all of the values of INTERFACE_INCLUDE_DIRECTORIES, so INTERFACE_INCLUDE_DIRECTORIES will be prop.

    This comes out to $<TARGET_PROPERTY:${PROJECT_NAME}-object,INTERFACE_INCLUDE_DIRECTORIES>, which is exactly what we've used in the code above.

    0 讨论(0)
提交回复
热议问题