Inhaltsverzeichnis
Conan, CMake und MinGW-Compiler
Einbinden fremder Bibliotheken
Die Bibliothek doctest dient als Beispiel. Damit können Unit-Tests in den Quelltext
- sqr.cpp
#include "doctest/doctest.h" int sqr(int number) { return number * number; } TEST_CASE("testing the sqr function") { CHECK(sqr(2) == 4); }
integriert werden (obwohl ich die Trennung von Quellen und Tests bevorzuge). In
- main.test.cpp
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include "doctest/doctest.h"
wird das Hauptprogramm für doctest
-Unit-Tests definiert.
CMake
CMake ist ein Build-Generator für unterschiedliche Compiler und Plattformen. Das CMake-Skript
- CMakeLists.txt
cmake_minimum_required(VERSION 3.27) project(cmake_test VERSION 0.0.1 LANGUAGES CXX) find_package(doctest REQUIRED) add_executable(mytests main.test.cpp sqr.cpp) target_compile_features(mytests PRIVATE cxx_std_23) target_link_libraries(mytests PRIVATE doctest::doctest)
bindet die durch findpackage()
gefundene Bibliothek in das Programm ein.
Aufspüren, Herunterladen, Bauen, Bereitstellen und die Bekanntgabe der Pfade zu externen Bibliotheken ist Aufgabe eines Paketmanagers. Modernes CMake sollte dabei keine Angaben enthalten, die auf spezielle Compiler oder Paketmanager hinweisen. Die Wahl von Paketmanager und Compiler erfolgt unabhängig voneinander.
Conan als Paketmanager
Conan (Version 2.0) ist ein Paketmanager für C++-Bibliotheken, der unter Linux und Windows nutzbar ist. Die Datei conanfile.txt
- conanfile.txt
[requires] doctest/2.4.11 fmt/10.1.1 [generators] CMakeDeps CMakeToolchain
listet erforderliche Bibliotheken mit Versionsangabe auf und legt fest, welche Skripte für CMake erzeugt werden sollen.
Projekt-Setup
Die Übersetzung des Projektes erfolgt in einem Verzeichnis build
(“out of source”). Beim erstmaligen Übersetzen wird zuerst der Paketmanager aufgerufen, danach das CMake-Projekt aufgesetzt.
Unter Linux lassen sich die Befehle in einem Shellscript
- setup_conan_cmake_gcc.sh
#!/bin/sh mkdir build cd build conan install .. cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake cmake --build .
zusammenfassen; unter Windows für den MinGW-Compiler in einer Batch-Datei:
- setup_conan_cmake_minGW.bat
mkdir build conan install . -of build --build=missing --profile=mingw cd build cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug cmake --build .
Header-only-Bibliotheken wie doctest
sind am einfachsten nutzbar. Andere Bibliotheken wie z.B. fmt
müssen eventuell erst aus den Quellen gebaut werden, sofern sie nicht schon auf den Conan-Servern vorrätig sind. Conan nutzt zum Bauen fehlender Bibliotheken einen vorhandenen Compiler. Dazu dienen die Optionen --build=missing
und --profile=mingw
beim Aufruf des Paketmanagers. Da Conan unter Windows im Profil default
von der Existenz von Visual C++ ausgeht, ist für den MinGW-Compiler ein anderes Profil mingw
anzulegen:
- mingw
# copy this file to C:\Users\myUsername\.conan2\profiles\ [settings] arch=x86_64 os=Windows compiler=gcc compiler.version=13.2 compiler.libcxx=libstdc++11 compiler.cppstd=23 compiler.exception=seh compiler.threads=posix build_type=Debug
Dieses Profil wird beim aktuellen Nutzer C:\Users\MyUsername
unter .conan2\profiles
hinterlegt. Compiler-Version, 32- oder 64bit-Architektur und andere Optionen sind je nach genutztem Compiler anzupassen.
Nun ist im C++-Quelltext
- main.cpp
#include <fmt/core.h> int sqr(int number) { return number * number; } int main() { fmt::println("2*2 = {}", sqr(2)); }
auch die Nutzung der fmt
-Bibliothek möglich. Dazu wird CMakeLists.txt
angepasst:
- CMakeLists.txt
cmake_minimum_required(VERSION 3.27) project(cmake_fmt VERSION 0.0.1 LANGUAGES CXX) find_package(doctest REQUIRED) find_package(fmt REQUIRED) add_executable(mytests main.test.cpp sqr.cpp) target_compile_features(mytests PRIVATE cxx_std_23) target_link_libraries(mytests PRIVATE doctest::doctest) add_executable(fmttest main.cpp) target_compile_features(fmttest PRIVATE cxx_std_23) target_link_libraries(fmttest PRIVATE fmt::fmt)
Anmerkung: In C++23 kann die Funktion std:println()
genutzt werden, ist in g++13.2 jedoch noch nicht implementiert.