db41258d16
Ersetzt das Geruest (counter/notebook) durch ein echtes Beispiel und teilt es in zwei eigenstaendige Projekte, wie P1204R0 es fuer Bibliothek plus Programm verlangt. libpda: textfile (C, Datei-I/O und Feld-Escaping), calculator (Recursive-Descent-Parser mit std::expected), contact, editor, explorer. Exportiert pda::pda ueber install(EXPORT) und ist per find_package(pda) benutzbar. pda: Shell ohne Ein-/Ausgabe (execute() gibt Text zurueck, deshalb ohne Terminal testbar), REPL und Stapelbetrieb in main.cpp. examples/consumer und tools/check-install.sh pruefen die Export-Kette Ende-zu-Ende: installieren, dann ein fremdes Projekt dagegen bauen. docs/CMAKE.md erklaert das Target-Modell, PUBLIC/PRIVATE/INTERFACE, Generator-Ausdruecke, install/export und Symbolsichtbarkeit an diesem Projekt. 71 Tests gruen unter Homebrew-clang 22, Apple clang und GCC 16, statisch und shared, mit und ohne ASan/UBSan. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
77 lines
3.3 KiB
CMake
77 lines
3.3 KiB
CMake
# ---------------------------------------------------------------------------
|
|
# Gemeinsame Grundeinstellungen fuer alle Teilprojekte.
|
|
#
|
|
# Diese Datei wird von zwei Seiten eingebunden:
|
|
# * vom Superprojekt (CMakeLists.txt im Wurzelverzeichnis), oder
|
|
# * von einem Teilprojekt, das ALLEIN konfiguriert wird
|
|
# (cmake -S libpda -B build/lib).
|
|
#
|
|
# Deshalb ist alles hier idempotent: zweimal einbinden darf nichts kaputt
|
|
# machen. Das ist keine Vorsicht, sondern Voraussetzung -- ohne das koennte
|
|
# man libpda nicht einzeln bauen.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
include_guard(GLOBAL)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Sprachstandards: C23 + C++23, keine GNU-Extensions.
|
|
#
|
|
# Das sind ganz normale Variablen, KEINE Targeteigenschaften. CMake liest sie
|
|
# in dem Moment, in dem ein Target angelegt wird, und schreibt den Wert dann
|
|
# in das Target. Wer sie NACH add_library() setzt, aendert nichts mehr --
|
|
# einer der haeufigsten Anfaengerfehler.
|
|
# ---------------------------------------------------------------------------
|
|
set(CMAKE_C_STANDARD 23)
|
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
|
set(CMAKE_C_EXTENSIONS OFF)
|
|
|
|
set(CMAKE_CXX_STANDARD 23)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
|
|
# compile_commands.json fuer clangd. Muss vor dem ersten Target stehen.
|
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
|
|
# C++20-Modul-Scanning aus. Sonst schreibt Ninja bei CXX_STANDARD 23 ein
|
|
# "@CMakeFiles/<target>.dir/<datei>.o.modmap" in jeden Compile-Command, und
|
|
# clangd stolpert ueber die Response-Datei, sobald build/ geleert wurde.
|
|
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)
|
|
|
|
# Ohne explizites CMAKE_BUILD_TYPE waeren alle -O/-g-Flags leer.
|
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
|
|
endif()
|
|
|
|
# Alle Binaries an einen vorhersagbaren Ort. Ohne das landet jede Executable
|
|
# im Verzeichnis ihres CMakeLists.txt, und "wo ist mein Programm" wird zur
|
|
# Suchaufgabe.
|
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
|
|
|
# Bei Shared Libraries: Symbole sind per Default unsichtbar und muessen
|
|
# ausdruecklich exportiert werden (siehe generate_export_header in
|
|
# libpda/CMakeLists.txt). Das ist unter Windows ohnehin Pflicht -- es hier
|
|
# auch unter Unix zu erzwingen, faengt Portabilitaetsfehler frueh.
|
|
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
|
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
|
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
|
|
|
# Damit eine gebaute Shared Library aus dem Build-Baum heraus lauffaehig ist,
|
|
# ohne DYLD_LIBRARY_PATH zu setzen.
|
|
set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ccache, wenn vorhanden. Ueber COMPILER_LAUNCHER, NICHT ueber die
|
|
# Compiler-Shims in ccaches libexec -- die faengt jeden Compiler-Aufruf des
|
|
# gesamten Systems ab.
|
|
# ---------------------------------------------------------------------------
|
|
if(NOT CMAKE_C_COMPILER_LAUNCHER AND NOT CMAKE_CXX_COMPILER_LAUNCHER)
|
|
find_program(CCACHE_PROGRAM ccache)
|
|
if(CCACHE_PROGRAM)
|
|
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
|
|
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
|
|
message(STATUS "ccache: ${CCACHE_PROGRAM}")
|
|
endif()
|
|
endif()
|