Overlapping dependencies between libraries in CMake

One other solution is to add a guard at the top of the subdirectory-CMakeLists.txt:

if(TARGET targetname)
    return()
endif(TARGET targetname)

Which will cause cmake to do nothing the second time the subdirectory is added (if targetname is being defined in that file, of course).

This will lead to the lib beeing build in an sort-of-arbitrary place (depending on which module added it first) in the build/ tree, but it will be built only once and linked everywhere.

In your example, you would add

if(TARGET lib1)
    return()
endif(TARGET lib1)

at the top of lib1/CMakeFiles.txt


With CMake, library dependencies are transitive, so you shouldn't call add_subdirectory twice in test/CMakeFiles.txt (nor do you need to list lib1 as a dependency of test since it is already a dependency of lib2's).

So you could modify test's CMakeFiles.txt to:

cmake_minimum_required(VERSION 2.8.7)  # Prefer the most current version possible
project(test)

add_subdirectory(../lib2 ${CMAKE_CURRENT_BINARY_DIR}/lib2)

add_executable(test main.cpp)
target_link_libraries(test lib2)

Also, you should probably remove the cmake_minimum_required calls from your non-project CMakeFiles.txt files (the lib ones). For further info, run:

cmake --help-policy CMP0000


This setup will still cause all libs to be recompiled if you add a similar test2 subdirectory and project which depends on lib1 and lib2. If you really don't want to have a top-level CMakeFiles.txt in projects/, then you're stuck with what you're doing, or you could use either the export or install command.

export would create a file which could be included by other projects and which imports the targets into the project which calls include.

install could install the libraries to another common subdirectory of projects/. Depending on your source directory structure, this could have the benefit of only making the intended library API headers available to dependent projects.

However, both of these options require the dependent library projects to be rebuilt (and installed) if they are modified, whereas your current setup includes all the dependent targets in your project, so any change to a source file in a dependent library will cause your test target to go out of date.

For further details about export and install, run:

cmake --help-command export
cmake --help-command install

Tags:

Cmake