.
+-- MyPack
| +-- Lib1
| | +-- include
| | | +-- Lib1.h
| | +-- src
| | | +-- Lib2.cpp
| | +-- CMakeLists.txt
| +-- Lib2
| | +-- include
| | | +-- Lib2.h
| | +-- src
| | | +-- Lib2.cpp
| | +-- CMakeLists.txt
| +-- CMakeLists.txt
+-- SubProject1
| +-- CMakeLists.txt
+-- SubProject2
| +-- CMakeLists.txt
+-- CMakeLists.txt
Hi all.
I'm new to CMake and I'm trying to obtain something like the following. Considering the above directory tree of my C++ project:
I have a directory (let's say "MyPack") that contains several subdirectories (Lib1, Lib2...) and each one represents a C++ Library that I wrote.
How can I setup everything so I can write find_package(MyPack)
in the other subprojects?
Every subproject is a stand-alone project, and does not depend on other subprojects, but just on libraries in "MyPack".
Your drawing is a bit confusing because there is a CMakeLists.txt after Lib2 which belongs to no folder... Anyway: is MyPack
in the 2nd case:
The top directory CMakeLists.txt gives you access to targets of Lib1 and Lib2 that you can use in SubProject1 and SubProject2 if you have something like this:
project(MyPack)
add_subdirectory(Lib1) # Building Lib1
add_subdirectory(Lib2) # Building Lib2
add_subdirectory(SubProject1) # you can use Lib1 & Lib2 targets here
add_subdirectory(SubProject2) # you can use Lib1 & Lib2 targets here
If it is the 1st case, MyPack is only Lib1 and Lib2 :
Using find_package(MyPack) means that you need to create a Config file and install() your project:
project(MyPack)
add_subdirectory(Lib1)
add_subdirectory(Lib2)
in Lib1/CMakeLists.txt:
add_library(lib1 "")
add_library(MyPack::lib1 ALIAS lib1)
[...]
include(GNUInstallDirs)
install(
TARGETS lib1
EXPORT MyPackTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
in Lib2/CMakeLists.txt:
add_library(lib2 "")
add_library(MyPack::lib2 ALIAS lib2)
[...]
include(GNUInstallDirs)
install(
TARGETS lib2
EXPORT MyPackTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
Now you have lib1 and lib2 in the export MyPackTargets. You have to install that export as well.
anywhere after above:
install(
EXPORT MyPackTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyPack
NAMESPACE MyPack::
FILE MyPackTargets.cmake # Not sure if this is still needed
)
include(CMakePackageConfigHelpers)
configure_package_config_file(
"Config.cmake.in"
"MyPackConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyPack
PATH_VARS
CMAKE_INSTALL_LIBDIR
)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/MyPackConfigVersion.cmake
VERSION 1.0.0
COMPATIBILITY SameMajorVersion
)
### Install Config and ConfigVersion files
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/MyPackConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/MyPackConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/MyPack"
)
create a file Config.cmake.in with:
@PACKAGE_INIT@
include( "${CMAKE_CURRENT_LIST_DIR}/MyPackTargets.cmake" )
Now if you build and install your project MyPack, find_package(MyPack) from other project should find it and import the targets you've created.
Here is some documentation: https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html