Die Meldung 'This file does not belong to any project target' kommt nicht vom CMakeLists.txt: die File API ordnet calculator.hpp korrekt dem Target pda zu (LIBPDA_HEADERS geht an add_library). CLion hatte nur kein Modell. Dokumentiert dazu die Falle, dass eine aus dem Dock gestartete GUI die PATH aus .zprofile nicht erbt -- 'CMAKE_C_COMPILER: clang' loest dort auf Apple clang auf, im Terminal auf Homebrew-LLVM. Da binaryDir in beiden Faellen build/debug ist, gewinnt lautlos, wer zuerst konfiguriert. .gitignore deckte /build/ ab, aber nicht CLions Default cmake-build-<profil>/ im Wurzelverzeichnis. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
playground
Ein kleiner PDA — Kontakte, Taschenrechner, Notizen, Dateiexplorer — als Übungsprojekt für die Bau- und Projektstruktur, die dahintersteht.
Aufgeteilt nach P1204R0 „Canonical Project Structure" in zwei eigenständige Projekte:
playground/ Superprojekt, kein eigener Quellcode
├── libpda/ die Bibliothek -> libpda.a
│ ├── libpda/
│ │ ├── textfile.h/.c C: Datei-I/O und Feld-Escaping
│ │ ├── calculator.hpp/.cpp Ausdrucksparser (Recursive Descent)
│ │ ├── contact.hpp/.cpp Kontaktverwaltung mit Persistenz
│ │ ├── editor.hpp/.cpp zeilenorientierter Textpuffer
│ │ ├── explorer.hpp/.cpp Verzeichnisnavigation
│ │ ├── *.test.c/.cpp Unit-Tests, direkt neben dem Modul
│ │ └── details/ Implementation Details
│ └── tests/basics/ Integrationstest, nur öffentliche API
├── pda/ die Anwendung -> bin/pda
│ ├── pda/shell.hpp/.cpp Kommandoverarbeitung, ohne Ein-/Ausgabe
│ ├── pda/main.cpp REPL und Stapelbetrieb
│ └── tests/session/ Integrationstest einer ganzen Sitzung
├── examples/consumer/ fremdes Projekt, benutzt find_package(pda)
├── cmake/ ProjectDefaults, Warnings, Sanitizers, Config-Vorlage
├── third_party/ vendortes Unity + doctest, nie editieren
├── tools/check-install.sh prüft die Export-Kette Ende-zu-Ende
└── docs/ CMAKE.md, CONVENTIONS.md, ADRs
Warum getrennte Projekte: P1204R0 verlangt es, und der praktische Grund ist, dass die Bibliothek ohne die Anwendung baubar, testbar und installierbar sein muss — sonst ist sie keine Bibliothek, sondern ein Unterverzeichnis.
Bauen
cmake --preset debug
cmake --build --preset debug
ctest --preset debug
./build/debug/bin/pda
Presets: debug, release, asan-ubsan, apple-clang, homebrew-gcc,
linux-gcc.
Benutzen
Interaktiv:
$ pda
pda 0.1.0 -- 'help' zeigt die Kommandos, 'quit' beendet.
playground> contact add "Anna Schmidt" 0151 anna@example.org meine Schwester
'Anna Schmidt' angelegt (1 Kontakte)
playground> calc (2+3)*4 - 10/2
15
playground> note add Anna anrufen
Zeile 1 angelegt
playground> contact save kontakte.tsv
1 Kontakte nach kontakte.tsv geschrieben
Im Stapelbetrieb — ein Kommando, dann Ende:
pda calc "2^10" # 1024
pda contact list
Der Exit-Code ist 1, wenn das Kommando scheitert. Fehler gehen nach stderr.
Als Bibliothek benutzen
cmake -S libpda -B build/lib -DCMAKE_INSTALL_PREFIX=/pfad
cmake --build build/lib && cmake --install build/lib
Dann im eigenen Projekt:
find_package(pda 0.1 REQUIRED)
target_link_libraries(mein_programm PRIVATE pda::pda)
#include <libpda/calculator.hpp>
const auto value = pda::evaluate("(1 + 2) * 3 ^ 2");
if (value) std::println("{}", *value);
Ein vollständiges Beispiel steht in examples/consumer/;
tools/check-install.sh baut es gegen eine frisch installierte Bibliothek und
ist damit der Test für den Export-Mechanismus.
Dokumentation
- docs/CMAKE.md — CMake an diesem Projekt erklärt:
Target-Modell,
PUBLIC/PRIVATE/INTERFACE, Generator-Ausdrücke, install/export, Symbolsichtbarkeit, „wann mache ich was?" - docs/CONVENTIONS.md — Stil- und Strukturregeln
- docs/adr/ — Architekturentscheidungen mit Begründung
Stand
71 Tests (Unity für C, doctest für C++, zwei Integrationstreiber ohne Framework). Grün unter Homebrew-clang 22, Apple clang und GCC 16, jeweils statisch und als Shared Library, mit und ohne ASan/UBSan.