Zum Inhalt

CMake Cheatsheet

Überblick

CMake ist ein plattformübergreifendes Build-System-Generator, der plattformunabhängige Konfigurationsdateien verwendet, um native Build-Tool-Dateien (Makefiles, Visual Studio-Projekte, Xcode-Projekte usw.) zu generieren.

Installation

Paketmanager

[Placeholder for text 2]

[Placeholder for text 3]

[Placeholder for text 4]

[Placeholder for text 5]

[Placeholder for text 6]

[Placeholder for text 7]

[Placeholder for text 8]

[Placeholder for text 9]

[Placeholder for text 10]

[Placeholder for text 11]

[Placeholder for text 12]

[Placeholder for text 13]

[Placeholder for text 14]

[Placeholder for text 15]

[Placeholder for text 16]

[Placeholder for text 17]

[Placeholder for text 18]

[Placeholder for text 19]

[Placeholder for text 20]

Would you like me to fill in the other placeholders? If you provide the specific text for each section, I can translate them accordingly.```bash

Ubuntu/Debian

sudo apt install cmake

macOS

brew install cmake

CentOS/RHEL

sudo yum install cmake

Windows (Chocolatey)

choco install cmake

From source

wget https://cmake.org/files/v3.25/cmake-3.25.0.tar.gz tar -xzf cmake-3.25.0.tar.gz cd cmake-3.25.0 && ./bootstrap && make && sudo make install

## Basic Concepts

### Key Terms
CMakeLists.txt # Configuration file Target # Executable, library, or custom target Generator # Tool that creates build files Cache # Stored configuration variables Out-of-source # Build directory separate from source
### Project Structure
project/ ├── CMakeLists.txt ├── src/ │ ├── main.cpp │ └── utils.cpp ├── include/ │ └── utils.h └── build/ # Out-of-source build directory
## Basic CMakeLists.txt

### Minimal Example
```cmake
cmake_minimum_required(VERSION 3.10)
project(MyProject)

set(CMAKE_CXX_STANDARD 17)

add_executable(myapp main.cpp)

Simple Library

cmake_minimum_required(VERSION 3.10)
project(MyProject VERSION 1.0.0)

# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Add library
add_library(mylib utils.cpp network.cpp)

# Add executable
add_executable(myapp main.cpp)

# Link library to executable
target_link_libraries(myapp mylib)

Variables

Built-in Variables

# Project information
$\\\\{PROJECT_NAME\\\\}
$\\\\{PROJECT_VERSION\\\\}
$\\\\{PROJECT_SOURCE_DIR\\\\}
$\\\\{PROJECT_BINARY_DIR\\\\}

# System information
$\\\\{CMAKE_SYSTEM_NAME\\\\}        # Linux, Windows, Darwin
$\\\\{CMAKE_SYSTEM_VERSION\\\\}
$\\\\{CMAKE_SYSTEM_PROCESSOR\\\\}

# Compiler information
$\\\\{CMAKE_CXX_COMPILER\\\\}
$\\\\{CMAKE_CXX_COMPILER_ID\\\\}    # GNU, Clang, MSVC
$\\\\{CMAKE_CXX_COMPILER_VERSION\\\\}

# Build information
$\\\\{CMAKE_BUILD_TYPE\\\\}         # Debug, Release, RelWithDebInfo
$\\\\{CMAKE_CURRENT_SOURCE_DIR\\\\}
$\\\\{CMAKE_CURRENT_BINARY_DIR\\\\}

Setting Variables

# Set variable
set(SOURCES main.cpp utils.cpp)
set(MY_VAR "value")

# List operations
list(APPEND SOURCES network.cpp)
list(REMOVE_ITEM SOURCES main.cpp)
list(LENGTH SOURCES NUM_SOURCES)

# String operations
string(TOUPPER $\\\\{PROJECT_NAME\\\\} PROJECT_NAME_UPPER)
string(REPLACE "old" "new" NEW_STRING $\\\\{OLD_STRING\\\\})

# Cache variables
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries")

Targets

Executables

# Simple executable
add_executable(myapp main.cpp)

# Executable with multiple sources
add_executable(myapp
    main.cpp
    utils.cpp
    network.cpp
)

# Executable with variable sources
set(SOURCES main.cpp utils.cpp)
add_executable(myapp $\\\\{SOURCES\\\\})

Libraries

# Static library
add_library(mylib STATIC utils.cpp network.cpp)

# Shared library
add_library(mylib SHARED utils.cpp network.cpp)

# Header-only library
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE include/)

# Object library
add_library(mylib OBJECT utils.cpp network.cpp)
add_executable(myapp main.cpp $<TARGET_OBJECTS:mylib>)

Target Properties

# Set target properties
set_target_properties(myapp PROPERTIES
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED ON
    OUTPUT_NAME "my_application"
)

# Include directories
target_include_directories(myapp
    PRIVATE include/
    PUBLIC $\\\\{CMAKE_CURRENT_SOURCE_DIR\\\\}/public_include/
)

# Compile definitions
target_compile_definitions(myapp
    PRIVATE DEBUG_MODE
    PUBLIC API_VERSION=2
)

# Compile options
target_compile_options(myapp
    PRIVATE -Wall -Wextra
    PUBLIC -fPIC
)

# Link libraries
target_link_libraries(myapp
    PRIVATE mylib
    PUBLIC pthread
)

Finding Packages

find_package

# Find required package
find_package(Threads REQUIRED)
target_link_libraries(myapp Threads::Threads)

# Find optional package
find_package(OpenSSL)
if(OpenSSL_FOUND)
    target_link_libraries(myapp OpenSSL::SSL OpenSSL::Crypto)
    target_compile_definitions(myapp PRIVATE HAVE_OPENSSL)
endif()

# Find package with components
find_package(Boost REQUIRED COMPONENTS system filesystem)
target_link_libraries(myapp Boost::system Boost::filesystem)

# Find package with version
find_package(Qt5 5.10 REQUIRED COMPONENTS Core Widgets)
target_link_libraries(myapp Qt5::Core Qt5::Widgets)

pkg-config

find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)

target_include_directories(myapp PRIVATE $\\\\{GTK3_INCLUDE_DIRS\\\\})
target_link_libraries(myapp $\\\\{GTK3_LIBRARIES\\\\})
target_compile_options(myapp PRIVATE $\\\\{GTK3_CFLAGS_OTHER\\\\})

Conditional Logic

if/else/endif

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    target_compile_definitions(myapp PRIVATE DEBUG_MODE)
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
    target_compile_definitions(myapp PRIVATE RELEASE_MODE)
endif()

# Platform-specific code
if(WIN32)
    target_sources(myapp PRIVATE windows_specific.cpp)
elseif(UNIX)
    target_sources(myapp PRIVATE unix_specific.cpp)
endif()

# Compiler-specific options
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    target_compile_options(myapp PRIVATE -Wall -Wextra)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
    target_compile_options(myapp PRIVATE /W4)
endif()

option

option(BUILD_TESTS "Build test programs" ON)
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)

if(BUILD_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif()

Functions and Macros

Functions

function(add_my_executable name)
    add_executable($\\\\{name\\\\} $\\\\{ARGN\\\\})
    target_compile_features($\\\\{name\\\\} PRIVATE cxx_std_17)
    target_compile_options($\\\\{name\\\\} PRIVATE -Wall -Wextra)
endfunction()

# Usage
add_my_executable(myapp main.cpp utils.cpp)

Macros

macro(set_default_build_type)
    if(NOT CMAKE_BUILD_TYPE)
        set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE)
    endif()
endmacro()

# Usage
set_default_build_type()

Advanced Functions

function(add_library_with_alias target_name)
    set(options SHARED STATIC)
    set(oneValueArgs ALIAS)
    set(multiValueArgs SOURCES HEADERS)

    cmake_parse_arguments(ARG "$\\\\{options\\\\}" "$\\\\{oneValueArgs\\\\}" "$\\\\{multiValueArgs\\\\}" $\\\\{ARGN\\\\})

    if(ARG_SHARED)
        add_library($\\\\{target_name\\\\} SHARED $\\\\{ARG_SOURCES\\\\})
    else()
        add_library($\\\\{target_name\\\\} STATIC $\\\\{ARG_SOURCES\\\\})
    endif()

    if(ARG_ALIAS)
        add_library($\\\\{ARG_ALIAS\\\\} ALIAS $\\\\{target_name\\\\})
    endif()
endfunction()

# Usage
add_library_with_alias(mylib
    SHARED
    ALIAS MyNamespace::mylib
    SOURCES utils.cpp network.cpp
)

Testing

CTest Integration

enable_testing()

# Add test executable
add_executable(test_utils test_utils.cpp)
target_link_libraries(test_utils mylib)

# Add test
add_test(NAME test_utils COMMAND test_utils)

# Test with arguments
add_test(NAME test_with_args COMMAND myapp --test --verbose)

# Test properties
set_tests_properties(test_utils PROPERTIES
    TIMEOUT 30
    WORKING_DIRECTORY $\\\\{CMAKE_CURRENT_BINARY_DIR\\\\}
)

Google Test Integration

find_package(GTest REQUIRED)

add_executable(unit_tests
    test_main.cpp
    test_utils.cpp
)

target_link_libraries(unit_tests
    mylib
    GTest::GTest
    GTest::Main
)

# Discover tests automatically
include(GoogleTest)
gtest_discover_tests(unit_tests)

Installation

Basic Installation

```cmake

Install executable

install(TARGETS myapp RUNTIME DESTINATION bin )

Install library

install(TARGETS mylib LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin )

Install headers

install(DIRECTORY include/ DESTINATION include FILES_MATCHING PATTERN "*.h" )

Install files

install(FILES config.txt DESTINATION etc ) ### Paketconfigurationcmake

Generate package config files

include(CMakePackageConfigHelpers)

Create config file

configure_package_config_file( $\\{CMAKE_CURRENT_SOURCE_DIR\\}/Config.cmake.in $\\{CMAKE_CURRENT_BINARY_DIR\\}/MyProjectConfig.cmake INSTALL_DESTINATION lib/cmake/MyProject )

Create version file

write_basic_package_version_file( $\\{CMAKE_CURRENT_BINARY_DIR\\}/MyProjectConfigVersion.cmake VERSION $\\{PROJECT_VERSION\\} COMPATIBILITY SameMajorVersion )

Install config files

install(FILES $\\{CMAKE_CURRENT_BINARY_DIR\\}/MyProjectConfig.cmake $\\{CMAKE_CURRENT_BINARY_DIR\\}/MyProjectConfigVersion.cmake DESTINATION lib/cmake/MyProject )

Export targets

install(EXPORT MyProjectTargets FILE MyProjectTargets.cmake NAMESPACE MyProject:: DESTINATION lib/cmake/MyProject ) ## Generator-Ausdrückecmake

Build type specific

target_compile_definitions(myapp PRIVATE \(<\):DEBUG_MODE> \(<\):RELEASE_MODE> )

Platform specific

target_compile_definitions(myapp PRIVATE \(<\):WINDOWS_BUILD> \(<\):LINUX_BUILD> )

Compiler specific

target_compile_options(myapp PRIVATE \(<\):-Wall> \(<\):/W4> ) ### Grundlegende Generator-Ausdrückecmake

Target properties

target_include_directories(myapp PRIVATE $ )

Conditional linking

target_link_libraries(myapp \(<\)\(\\\\{BUILD_SHARED_LIBS\\\\}>:\)\\\\{CMAKE_DL_LIBS\\\\}> )

File operations

target_sources(myapp PRIVATE \(<\):windows_main.cpp> \(<\):linux_main.cpp> ) ### Fortgeschrittene Generator-Ausdrückebash

Configure (generate build files)

cmake -S . -B build

Build

cmake --build build

Install

cmake --install build

Test

cd build && ctest

Clean

cmake --build build --target clean ## Befehlszeilenverwendungbash

Set build type

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release

Set variables

cmake -S . -B build -DBUILD_TESTS=ON -DBUILD_SHARED_LIBS=ON

Set generator

cmake -S . -B build -G "Unix Makefiles" cmake -S . -B build -G "Ninja" cmake -S . -B build -G "Visual Studio 16 2019"

Set toolchain

cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake

Parallel build

cmake --build build --parallel 4 cmake --build build -j 4 ### Grundlegende Befehlebash

Configure with preset

cmake --preset=default

Build specific target

cmake --build build --target myapp

Install to custom prefix

cmake --install build --prefix /opt/myapp

Run specific test

cd build && ctest -R test_utils

Verbose output

cmake --build build --verbose ctest --verbose ### Konfigurationsoptionencmake if(WIN32) # Windows-specific code target_compile_definitions(myapp PRIVATE PLATFORM_WINDOWS) elseif(APPLE) # macOS-specific code target_compile_definitions(myapp PRIVATE PLATFORM_MACOS) elseif(UNIX) # Linux/Unix-specific code target_compile_definitions(myapp PRIVATE PLATFORM_LINUX) endif() ### Erweiterte Verwendungcmake

toolchain-mingw.cmake

set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Usage

cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=toolchain-mingw.cmake ## Plattformübergreifende Entwicklungcmake cmake_minimum_required(VERSION 3.15)

project(MyProject VERSION 1.0.0 DESCRIPTION "My awesome project" LANGUAGES CXX )

Only do these if this is the main project

if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) set(CMAKE_CXX_EXTENSIONS OFF) set_property(GLOBAL PROPERTY USE_FOLDERS ON)

include(CTest)
if(BUILD_TESTING)
    add_subdirectory(tests)
endif()

endif()

Add subdirectories

add_subdirectory(src) add_subdirectory(external) ### Plattformerkennungcmake

Use target-based approach

target_include_directories(mylib PUBLIC \(<BUILD_INTERFACE:\)\\{CMAKE_CURRENT_SOURCE_DIR\\}/include> $ )

Use imported targets

find_package(Threads REQUIRED) target_link_libraries(myapp PRIVATE Threads::Threads)

Use generator expressions

target_compile_features(myapp PRIVATE cxx_std_17)

Avoid global commands

Don't use: include_directories(), link_directories(), add_definitions()

Use target-specific commands instead

### Toolchain-Dateiencmake

Check CMake version

cmake_minimum_required(VERSION 3.15)

Validate variables

if(NOT DEFINED PROJECT_VERSION) message(FATAL_ERROR "PROJECT_VERSION must be defined") endif()

Check for required files

if(NOT EXISTS "$\\{CMAKE_CURRENT_SOURCE_DIR\\}/src/main.cpp") message(FATAL_ERROR "main.cpp not found") endif()

Validate options

if(BUILD_TYPE AND NOT BUILD_TYPE MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)$") message(FATAL_ERROR "Invalid BUILD_TYPE: $\\{BUILD_TYPE\\}") endif() ## Best Practicescmake

Print variables

message(STATUS "CMAKE_BUILD_TYPE: $\\{CMAKE_BUILD_TYPE\\}") message(STATUS "CMAKE_CXX_COMPILER: $\\{CMAKE_CXX_COMPILER\\}")

Print all variables

get_cmake_property(_variableNames VARIABLES) foreach(_variableName \(\\\\{_variableNames\\\\}) message(STATUS "\)\\{_variableName\\}=\(\\\\{\)\\{_variableName\\}\\}") endforeach()

Print target properties

get_target_property(MYAPP_SOURCES myapp SOURCES) message(STATUS "myapp sources: $\\{MYAPP_SOURCES\\}") ### Projektstrukturbash

Verbose makefile

cmake -S . -B build -DCMAKE_VERBOSE_MAKEFILE=ON

Debug find_package

cmake -S . -B build --debug-find

Trace execution

cmake -S . -B build --trace

Debug output

cmake -S . -B build --debug-output ```### Moderne CMake-Muster https://cmake.org/documentation/##

Fehlerbehandlung

https://cmake.org/cmake/help/latest/guide/tutorial/#

Debugging

https://cliutils.gitlab.io/modern-cmake/##

Debug-Ausgabe

https://github.com/ttroy50/cmake-examples##

Fehlerbehebung