Show Menu
Cheatography

C++ (cmake) Cheat Sheet (DRAFT) by

A cheat sheet on making cmake files

This is a draft cheat sheet. It is a work in progress and is not finished yet.

add_ex­ecu­table

add_executable(executable_name,
main.cpp,
source_file.cpp
...
)
Defines a new executable build target named <ex­ecu­tab­le_­nam­e>.
Lists the source files that will be compiled and linked to produce the binary.
The target name can later be referenced by target­_li­nk_­lib­raries, target­_in­clu­de_­dir­ect­ories, etc.

add_li­brary vs add_ex­ecu­table

add_library(library_name
    source_file.cpp
    ...
)

add_executable(executable_name
    main.cpp
    ...
)
An executable has a main() function, can be run directly, and is always the end of the dependency chain.

A library has no main() function, cannot run on its own, and exists only to be linked against by other targets.

PRIVATE vs PUBLIC only matters for libraries — execut­ables are always PRIVATE.

Choosing PRIVATE vs PUBLIC for Libraries

target_link_libraries(my_library
    PUBLIC  qt5::Core       # appears in my headers, must be passed on
    PRIVATE internal_helper # only in my .cpp files, stays hidden
)
Ask yourself: do my header files expose this dependency to the outside world?

If the dependency appears in your headers, anything linking against you will also need it — use PUBLIC.

If the dependency only appears in your .cpp files, it stays hidden inside — use PRIVATE.
 

target­_in­clu­de_­dir­ect­ories

target_include_directories(executable_name PRIVATE
include_directory
...
)
Specifies include direct­ories for a given target, making headers in those direct­ories available via
#include
.
PRIVATE
means the direct­ories are only used when building this target, not propagated to depend­ents.
Other scope options are
PUBLIC
(propa­gated to depend­ents) and
INTERFACE
(only propag­ated, not used by the target itself).

CMake File Traversal

# root CMakeLists.txt
include(cmake/opencv.cmake)        # register libraries first
add_subdirectory(src/libs/logger)  # process logger/CMakeLists.txt
add_subdirectory(src/tests)        # process tests/CMakeLists.txt
The root CMakeL­ist­s.txt is the entry point and orches­trates the entire build.

include() pulls in .cmake files early to register libraries and settings before any targets are defined.

add_su­bdi­rec­tory() tells CMake to go into a folder and process the CMakeL­ist­s.txt there before contin­uing.

Leaf CMakeL­ist­s.txt files define targets with add_ex­ecu­table or add_li­brary and have no further add_su­bdi­rec­tory() calls.

CMAKE_­CUR­REN­T_S­OUR­CE_DIR

target_include_directories(executable_name PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}      # this CMakeLists.txt's folder
    ${CMAKE_CURRENT_SOURCE_DIR}/..   # one folder up
    ${CMAKE_CURRENT_SOURCE_DIR}/include  # subfolder
)
A built-in CMake variable that always points to the directory containing the currently processed CMakeL­ist­s.txt.

Use it to build paths to files relative to the current CMakeL­ist­s.txt location.

/.. moves up one directory, making it useful for refere­ncing files in a parent folder.
 

target­_li­nk_­lib­raries

target_link_libraries(executable_name PRIVATE
library_name
...
)
Specifies which libraries an executable or library target should be linked against.

PRIVATE
means the libraries are only used when building this target, not propagated to depend­ents.

Without this, the linker would not know where to find the implem­ent­ations of external code your target depends on.

PRIVATE / PUBLIC

target_link_libraries(target_name
    PRIVATE private_dependency  # stays hidden inside this target
    PUBLIC  public_dependency   # passed on to anything linking against this target
)
Controls whether depend­encies are propagated to targets that link against this one.

Use PRIVATE when a dependency only appears in .cpp files (hidden inside the implem­ent­ation), use PUBLIC when a dependency appears in header files (exposed to the outside world).

Execut­ables are always PRIVATE since nothing ever links against them.