cmakelinkerincludeinclude-path

CMake: How to prevent 'target_link_libraries' from adding visual studio project reference to a static library?


I just started participating in my first cmake project. The project that has many static libraries and a single executable that link them all.

Currently, a typical CMakeLists.txt for one of the static libraries 'this_lib' has this form:

target_include_directories(
    this_lib
    PUBLIC
    $<INSTALL_INTERFACE:include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    ${Boost_INCLUDE_DIRS}
)

target_link_libraries (this_lib PUBLIC
    lib1
    lib2
    lib3
    lib4
    lib5
    ${Boost_LIBRARIES}
)

target_link_libraries adds additional include directories and project dependencies in the form of a visual studio ProjectReference entry in the generated vcxproj file. As a result, the 'this_lib' is not compiled concurrently with the rest of the libraries which greatly increases compile time.

So is there a way to configure target_link_libraries so it will not add a Project Reference in Visual Studio?

This is what I tried so far:

If I move the parameters from target_link_libraries to target_include_directories, I get compilation errors (missing include) because it seems target_link_libraries operates recursively, meaning it adds include directories of linked libraries as well.


Solution

  • This seems to be a known issue.

    A quick fix for this problem is to use OPTIMIZE_DEPENDENCIES properties that was introduced in version 3.19.

    When this property is set to true, some dependencies for a static or object library may be removed at generation time if they are not necessary to build the library, since static and object libraries don't actually link against anything.

    The documentation is unclear as to how this property is actually set. But I managed to get it working using set_target_properties:

    add_library(this_lib STATIC <list of files>)
    
    set_target_properties(this_lib PROPERTIES OPTIMIZE_DEPENDENCIES ON <other properties>)
    

    Or alternatively for all projects at the top level CMakeLists.txt

    set(CMAKE_OPTIMIZE_DEPENDENCIES 1)
    

    I can clearly see that most of the dependencies are removed.