Building with CMake
لم يُترجم بعد؛ يُعرض باللغة الإنجليزية
A real C++ project has many files, and typing a compiler command for each one does not scale. CMake lets you describe the project once, as targets in a CMakeLists.txt, and turns that into a build system with a build graph: every output file and the files it is made from. Follow a three-file project through configure, build and run, then edit one file and watch only the files that depend on it rebuild.
5 أسئلة سريعة
اختر إجابة لتعرف السبب. تُحفَظ نتيجتك مع تقدّمك.
01What does cmake -S . -B build do?
Configure is the first step. CMake reads the recipe and writes a build system (Makefiles or build.ninja) into build/. Nothing is compiled until you run cmake --build build.
02In this lesson's CMakeLists.txt, what does target_link_libraries(app greet) say?
It adds an edge to the build graph: app depends on greet. The build tool builds libgreet.a before it links app, and the linker joins them.
03After a full build you edit only greet.cpp and build again. Which files are rebuilt?
greet.cpp is now newer than greet.o, so greet.o is remade, and everything made from it after that. main.o is newer than main.cpp and greet.h, so main.cpp is not compiled again: 3 of the 4 outputs are rebuilt.
04Why does editing greet.h rebuild both object files?
An #include pastes the header into each file that includes it, so it is an input of both object files. You never list it yourself: the compiler reports each file's headers to the build tool.
05What does -DCMAKE_BUILD_TYPE=Release change with GCC or Clang?
CMake's default Release flags for GCC and Clang are -O3 -DNDEBUG. Debug adds -g. With no build type there is no -O flag at all, so the compiler does not optimise.
المسرد
- CMake
- A tool that reads a project description (CMakeLists.txt) and writes a build system for your platform and compiler.
- CMakeLists.txt
- The recipe file for CMake: which targets to build, from which source files, and how they depend on each other.
- Target
- One thing CMake builds, such as a library (add_library) or a program (add_executable).
- Configure
- The first CMake step (cmake -S . -B build): check the compiler and write the build system into the build folder.
- Build system
- The files CMake writes (Makefiles or build.ninja) that a build tool such as make or Ninja follows to run the compiler.
- Build graph
- Every output file and the files it is made from. The build tool uses it to choose the order and to skip files that are up to date.
- Static library
- An archive of object files (libgreet.a; greet.lib on Windows) that the linker copies into the programs that use it.
- Build type
- A CMake setting (Debug, Release, RelWithDebInfo, MinSizeRel) that picks the compiler's optimisation and debug flags.
الملاحظات والمصادر
- The build graph card is a simplified view. CMake writes it as Makefiles (the default on Linux and macOS) or as build.ninja (with -G Ninja), with more rules and longer names: the object files are really build/CMakeFiles/greet.dir/greet.cpp.o and build/CMakeFiles/app.dir/main.cpp.o.
- Header dependencies (greet.h) are not written in the recipe or in the generated files: the compiler reports them during the first build (GCC and Clang -MD depfiles), and the build tool remembers them.
- add_library without STATIC or SHARED makes a static library (libgreet.a; greet.lib on Windows) unless BUILD_SHARED_LIBS is on. Modern CMake usually writes target_link_libraries(app PRIVATE greet); without the keyword it means the same here.
- The Release and Debug flags are CMake's defaults for GCC and Clang (CMAKE_CXX_FLAGS_RELEASE and CMAKE_CXX_FLAGS_DEBUG). Microsoft's compiler gets /O2 /Ob2 /DNDEBUG for Release instead. NDEBUG turns assert off.
- With Ninja (cmake -S . -B build -G Ninja), independent commands run in parallel by default, so greet.o and main.o compile together. CMake's default Makefiles finish the whole greet target (greet.o, then libgreet.a) before they start app's files, so cmake --build build --parallel (or make -j) only helps across files inside one target or across unrelated targets. The program is named app.exe on Windows.
- The project is real: greet.h, greet.cpp, main.cpp and the six-line CMakeLists.txt build with CMake 3.20 or newer and any C++20 compiler, and ./build/app prints Hello, CMake!
- CMake documentation: cmake(1), configure and build a project
- CMake documentation: add_library
- CMake documentation: target_link_libraries
- CMake documentation: CMAKE_BUILD_TYPE
- CMake documentation: cmake-generators(7)
- CMake Tutorial
- cppreference.com: Phases of translation
- cppreference.com: Source file inclusion (#include)
- cppreference.com: assert (and NDEBUG)
- Standard C++ Foundation (isocpp.org): Get Started!
- GNU make manual: Rule Introduction
- The Ninja build system manual
اختبار يتاح بعد الخطوة الأخيرة.