CMake¶
Debuging¶
- Debug output:
-LAH --debug-output --trace-expand
- Variable changes in cmake:
variable_watch(CMAKE_INSTALL_LIBDIR)
Dependency graph — [1]:¶
Option 1:
Option 2:
Main commands¶
add_executable
(tests testmain.cpp)
oradd_library
(catch INTERFACE)
target_compile_features
(catch INTERFACE cxx_std_11)
set_target_properties
(myTarget PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO)
target_include_directories
(catch INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_definitions
(tests PRIVATE CATCH_CONFIG_CONSOLE_WIDTH=60)
target_link_libraries
(<target> <PRIVATE|PUBLIC|INTERFACE> <item>... [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
Create proxy targets¶
Src.
find_package (libjpeg)
if (NOT TARGET libjpeg::libjpeg)
find_package (JPEG REQUIRED)
add_library (libjpeg::libjpeg INTERFACE IMPORTED)
target_link_libraries (libjpeg::libjpeg PUBLIC JPEG::JPEG)
message (STATUS "using system provided JPEG library")
else()
message (STATUS "using conan provided JPEG library")
endif()
target_link_libraries (your_project_target PRIVATE libjpeg::libjpeg)
CMake for monorepos¶
The problem¶
Sometimes the default CMake approach is too monolithic. This is especially relevant in case of monorepos (which tend to be large and include sub-project of multiple teams, which you do not want to build at all).
- For example, with the default cmake, given a monorepo, I cannot build a specific (single) sub-project. I can only build the entire repo.
- Another (even more important) consequence is that the decision as to whether to add
add_subdirectory(dependencyA)
in the givenCMakeLists.txt
or not, is not local. I know that my target depends ondependencyA
, but I do not know (locally, in the givenCMakeLists.txt
) whether it has already been included or not by a parentCMakeLists.txt
. - Finally, with the default cmake approach I have to remember both: (1) target name
(to specify it in
target_link_libraries()
) and (2) target path (to specify it inadd_subdirectory()
). Alternatively, we could auto-generate target names based on its path, and require to remember only paths.
The goal¶
The goal is to be able to write CMakeLists in this way:
-
Adding an executable:
-
Adding a library:
-
And configure in this way:
A prototype¶
Implementation of the functions is pretty straighforward — we just need:
- to maintain a list of processed directories (
processed_paths
) - and to introduce our own
depends_upon(directory)
that willadd_subdirectory(directory)
only if it has not yet been added in theprocessed_paths
: