7 routes42 sections324 units

Unit 7.9 · about 5 h

50 / 324

Repeatable CMake builds and test targets

A safe native change must survive a clean build, not just a working terminal session. Target-based builds keep dependencies and diagnostic options attached to the code that needs them.

  • implement

You can now

  • Describe a library, executable and native test as CMake targets with explicit usage requirements.
  • Configure independent debug, optimized and sanitizer builds and inspect their actual compile and link commands.
  • Run registered tests from a fresh build tree and install the intended artifact without installing test executables.

Covers

  • Repeatable CMake configure, build and test targets

Study, in this order

4 steps

  1. Targets, libraries and linking
    CMake tutorial

    Step 1: Background; Exercise 1 - Building an Executable; Exercise 2 - Building a Library; Exercise 3 - Linking Together Libraries and Executables

    Depth · Use the tutorial source archive linked from the v4.2 tutorial index. Stop before Exercise 4 if your project does not need subdirectories.

  2. Target features, warnings and link options
    CMake tutorial

    Step 4: Background; Exercise 1 - Features and Definitions; Exercise 2 - Compile and Link Options

    Depth · Read the scoped-command examples. Skip vendor-library import and precompiled headers; apply the commands to your own targets rather than completing all preceding steps.

  3. Testing and CTest
    CMake tutorial

    Step 8: Background and Exercise 1 - Adding Tests, all seven completion markers, including TestMathFunctions and the four registered operations

  4. Install the intended artifacts
    CMake tutorial

    Step 9: Background and Exercise 1 - Installing Artifacts

    Depth · Use install(TARGETS) and a local install prefix. Stop before exporting targets and version files.

Focus on

  • Model dependencies with target_link_libraries and target-scoped sources, includes and features. PRIVATE affects the target, INTERFACE its consumers, and PUBLIC both.
  • target_compile_features(... cxx_std_20) specifies at least C++20, not necessarily an exact -std=c++20 flag. Record verbose build commands and disable language extensions when strict standard mode is intended.
  • For single-config generators such as Unix Makefiles, configure CMAKE_BUILD_TYPE in separate trees. For multi-config generators, choose --config at build time and -C for CTest.
  • CTest runs registered commands; it does not automatically build them. Sanitizer instrumentation needs compile options and runtime linkage on the executable, and release tests must not disappear under NDEBUG.

Reproduce closed-book

Using CMake 4.2 with the Unix Makefiles generator, create a small library target, an executable linked to it and a separate test executable returning nonzero on failed checks. Set a C++20 requirement and register the test with enable_testing() and add_test(NAME native COMMAND native_tests). Configure with cmake -S . -B build-debug -G 'Unix Makefiles' -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Debug, build with cmake --build build-debug --verbose, and run ctest --test-dir build-debug --output-on-failure. Repeat in a new build-release tree with Release. Inspect the commands for g++ 15.2, language mode and optimization rather than assuming exact preset flags. Add an opt-in sanitizer configuration that applies -fsanitize=address,undefined to compilation and final linking, plus -fno-sanitize-recover=undefined and -fno-omit-frame-pointer to compilation; verify it in a new clang++ 21.1 build tree. Finally use install(TARGETS) for the executable and cmake --install build-release --prefix install-stage, and check that tests are not installed. A deliberately false test condition must make CTest fail in both Debug and Release.

Traps

  • Changing the compiler inside an existing cached tree is not equivalent to a fresh configure. Use a new build directory for a different toolchain.
  • Passing sanitizer flags only when compiling can leave the final link without its runtime libraries.
  • No tests found is not evidence that tests passed. Check discovery and use explicit failure checks that survive optimized builds.

Practice

CMake Tutorial: Building and linking targets

Step 1, Exercises 1 through 3: Building an Executable, Building a Library, Linking Together Libraries and Executables

Complete the target declarations and link the provided program. Then carry the same target structure into the section mini-project.

CMake Tutorial: Adding Tests

Step 8, Exercise 1, all seven completion markers; register TestMathFunctions for add, mul, sqrt and sub

Start from the supplied Step8 directory, which includes earlier solutions. Its public executable checks one fixed example per operation and reports failure via its exit code; it is not a broad numerical test suite. Run all four with CTest, then add your own boundary cases in the mini-project.

Self-test

  1. A library's public header uses std::span. Should its C++20 requirement be PRIVATE or PUBLIC?

  2. Why can CTest fail to run a newly registered executable?

  3. Does CMAKE_BUILD_TYPE=Release select the configuration for every generator?

  4. Why can an assert-only regression pass in Release despite a defect?

Completion criterion

Stop when

The named tutorial targets and four tests work, your own clean debug, release and sanitizer trees run the registered regression, an injected test failure is detected in Debug and Release, and installation excludes tests.

Mark passed, then open 1.1 Only mark this when you can do it without notes.

Leads to

Comes after

Resources for this unit

  • CMake tutorial
    CMakesupportimplementation
    Use the introductory steps for targets, libraries, testing and install rules. Produce one clean debug build and one optimized build without copied one-off commands.

Also in this section

  • AlgoMaster C++
    AlgoMasterprimarycourse
    Use the sections on compilation, pointers and references, memory, RAII and smart pointers, copy and move, STL containers, templates, errors, concurrency and paired exercises. Skip competitive-programming breadth already covered in Algorithms.
  • C++ Core Guidelines
    Standard C++ Foundation communityrequiredreference
    Use the Philosophy, Interfaces, Resource management, Expressions, Containers and concurrency rule groups to review ownership and safety decisions in the native component.
  • cppreference
    cppreference communitysupportreference
    Consult language lifetime, object model, value categories, memory model, atomics, containers and iterator invalidation while reading or modifying code.
  • Clang AddressSanitizer and UndefinedBehaviorSanitizer
    LLVMrequiredimplementation
    Compile seeded memory defects with AddressSanitizer and UndefinedBehaviorSanitizer, preserve the reports, repair the root cause and keep regression tests.
  • pybind11 documentation
    pybind11 projectrequiredimplementation
    Follow First steps and NumPy support to expose one small native function with explicit shape, dtype, stride, ownership, GIL and exception behavior.
  • Algorithmica - AoS and SoA
    Sergey Slotinsupportapplication
    Read the AoS and SoA experiment for a measured case where keeping each record together wins, the counterpart to a single-field scan.
  • `ld.so`: dynamic linker/loader
    Linux man-pages projectsupportreference
    Read DESCRIPTION, Dynamic string tokens and LD_DEBUG to distinguish link-time symbols from runtime shared-library discovery on Linux.
  • Memory Layout Transformations
    Intelsupportreference
    Read Overview and Topics through AOS Form and SOA Form for field-wise access and locality trade-offs. Skip Intel array-notation syntax and the LIBOR example.
  • GDB manual: Backtraces
    GNU Projectsupportreference
    Use section 8.2 for frame numbers, bt, bt -full and optimized-out arguments when inspecting a native failure.

Quick find

Search Michi

Type to search every route, section, unit, topic and resource.

Enter opens the first result Esc closes

Reference

Keyboard shortcuts

n
Continue to the first unit not passed
j / k
Next / previous unit
1 2 3
Toggle learned, practised, passed
/
Open search
?
Show this help
Esc
Close open panels