Issue
I have two separate projects, A and B. Both have large folder structures, lots of dependencies and both have their own CMakelists.txt structures as well. Neither depend on each other. I am adding new functionality to project A that depends on a header from project B, along with the network of files in Project B that header depends on. I am at a loss for the correct way to link these with cmake. I added to header as an include where necessary in my code, but am not sure the correct way to link it. Do I use target_include_directories and add the binaries from project B, or the source code, or both? Project A won't be building B as it is already set up, with the binaries and source in separate subdirectories. I just need A to be able to call the functionality from B. I am not very familiar with cmake yet, so any pointers would be appreciated. Thanks.
Solution
Project B should export its targets.
That way, in project A, you could do something like this:
find_package(B REQUIRED)
target_link_libraries(A PUBLIC B::B)
And when invoking CMake, add B's build directory in the prefix path:
# in A/build
cmake .. -DCMAKE_PREFIX_PATH=/path/to/B/build
But in order for that to work, you must change your B CMake files to export your targets (as it should):
include(GNUInstallDirs)
add_library(B INTERFACE)
add_library(B::B ALIAS B)
target_link_libraries(B PUBLIC dependency-of-B)
target_compile_features(B INTERFACE cxx_std_17) # or any language version
# Set B include directory. Will add include directory for both B and A
target_include_directories(B PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/your-include-dir>
)
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/B-config.cmake" DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
install(TARGETS B EXPORT B-targets)
# install package
install(EXPORT B-targets
FILE B-targets.cmake
NAMESPACE B::
DESTINATION share/cmake/B
)
# export build tree
export(
EXPORT B-targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/B-targets.cmake"
NAMESPACE B::
)
With B-config.cmake
:
include(CMakeFindDependencyMacro)
# All find_package we used in CMakeLists.txt should also be there
find_dependency(dependency1 REQUIRED)
find_dependency(dependency2 REQUIRED)
include("${CMAKE_CURRENT_LIST_DIR}/B-targets.cmake")
If you have many target in B, you should install(TARGETS other-target EXPORT B-targets)
I strongly recommend looking at example of libraries that export their targets so you can base your work on it. For example, the glm
library export its targets and always worked well. I also added target exportation in msdfgen
project.
Answered By - Guillaume Racicot