CMake (2026-08-19 - 2026-08-20) =============================== .. topic:: Course Information * Course start: 2026-08-19 at 9:00am * Setup instructions: :doc:`setup` * Agenda: :doc:`agenda` .. toctree:: :hidden: agenda setup exercise-1 Day 1: Basics ------------- Basic material, mandatory: * :doc:`/trainings/material/soup/misc/cmake/intro/basics` * :doc:`/trainings/material/soup/misc/cmake/intro/libraries` * :doc:`/trainings/material/soup/misc/cmake/intro/shared-libraries` * :doc:`/trainings/material/soup/misc/cmake/intro/structure` * :doc:`exercise-1` Final agenda point for day 1: have a look in :doc:`agenda`, and discuss topics for day 2. Day 2: Less Structured, More Practical -------------------------------------- .. contents:: :local: The participants were well able to follow everything, and I was busy upholding my well-structured :doc:`agenda ` against their demands |:ninja:|. I really enjoyed day 2: much dynamicity, much live-hacking, less slide-presenting - all in all leading to severe trainer exhaustion. .. topic:: Source code We morphed the exercise project into something that is not quite what was foreseen by the agenda. Here's the link to the outcome on Codeberg: https://codeberg.org/jfasch/2026-08-19-gluehwein Yesterday's Exercise Solution ............................. .. topic:: See also * :doc:`/trainings/material/soup/misc/cmake/advanced/targets-properties/screenplay` * Solve :doc:`exercise-1` together. Discussed matters like what ``target_include_directories()`` is, and especially what's the meaning of ``PUBLIC``, ``PRIVATE``, and ``INTERFACE``. See https://codeberg.org/jfasch/cmake-subdirs-structure-dependencies for the solution. The solution also covers :doc:`installation `. * :doc:`/trainings/material/soup/misc/cmake/intro/installation`, shown live while doing the exercise. * :doc:`/trainings/material/soup/misc/cmake/advanced/targets-properties/topic`, which is actually what the exercise is about. * The solution uses variables, though sparingly. Cover some of that: :doc:`/trainings/material/soup/misc/cmake/intro/cxx-and-rants` Structure: ``public/``, ``private/``, ``src/`` .............................................. .. topic:: See also * :doc:`/trainings/material/soup/misc/cmake/advanced/targets-properties/screenplay` Following :doc:`the screenplay `, we restructured the project into something that had more structure. Emphasis was put on when to use ``PRIVATE`` to reach one node's *own* header files vs. ``INTERFACE`` to export usage requirements to using nodes. For an immediate outcome it is probably best to look into :doc:`the screenplay's ` solution (https://codeberg.org/jfasch/cmake-public-private-src). Find-Modules: SQLite3 ..................... .. topic:: See also * :doc:`/trainings/material/soup/misc/cmake/advanced/external-dependencies/screenplay-sqlite3` CMake comes with many "find modules"; show how to use `FindSQLite3 `__. Relevant places to look: * Toplevel ``CMakeLists.txt`` for the configure/check step (`CMakeLists.txt `__) * Depending the ``data-logger`` library on SQLite3: `data-logger/CMakeLists.txt `__) * Source code, naturally: `sink-sqlite3.h `__, `sink-sqlite3.cpp `__ Hand-Writing A Find-Module .......................... .. topic:: See also * :doc:`/trainings/material/soup/misc/cmake/advanced/external-dependencies/screenplay-mosquitto` * **Step 1:** for the purpose of integrating our own project into another project, I created a simple brute-force find-module that is installed together with the project's artifacts for use by others. It requires a little CMake programming knowledge, though, which I presented as necessary. See :doc:`/trainings/material/soup/misc/cmake/advanced/language/index` for more. Relevant places: * The find-module: `cmake/FindGluehwein.cmake `__ * Installation of it in the toplevel `CMakeLists.txt `__ Build and install: .. code-block:: console $ cmake -DCMAKE_INSTALL_PREFIX=/home/jfasch/My-Installs/deployment ~/My-Projects/2026-08-19-gluehwein $ make $ make install * **Step 2:** use our project from another project. We quickly created such a project (`here `__); it only contains one trivial program that uses our project via the find-module from step1. .. code-block:: console cmake_minimum_required(VERSION 3.16) project(DecadentlyCookingWine) find_package(Gluehwein REQUIRED) # <-- HERE add_executable(cook-it cook-it.cpp) target_link_libraries( cook-it Gluehwein::Gluehwein # <-- AND HERE ) Build and use cookery from what's installed/deployed in ``/home/jfasch/My-Installs/deployment``. We are using a ``FindGluehwein.cmake`` from a non-standard location, so we pass ``CMAKE_MODULE_PATH``. The find-module is passed that location too which we also have to pass, separately, unfortunately. .. code-block:: console $ cmake \ -DCMAKE_MODULE_PATH=/home/jfasch/My-Installs/deployment/share/Modules \ -DDEPLOYMENT_DIR=/home/jfasch/My-Installs/deployment \ \ ~/My-Projects/2026-08-19-gluehwein-user $ make .. image:: using-gluehwein.svg .. note:: `Conan `__ is a package manager for C/C++, and probably better suited for such tasks. CMake Function ``gluehwein_add_library()`` .......................................... .. topic:: See also * :doc:`/trainings/material/soup/misc/cmake/advanced/library-function/screenplay` To defend against code explosion, one usually writes functions to eliminate duplicate code. This is what we did near the end of day 2. Relevant places: * The function itself, in `cmake/functions.cmake `__ * Toplevel `CMakeLists.txt `__, including that file - thus *inheriting* the function's definition into subdirectories. * Usage in * `base/CMakeLists.txt `__ * `boiling-pot/CMakeLists.txt `__ * `data-logger/CMakeLists.txt `__