0x01 介绍
概念: 分离编译
首先,CMake是一种开源的构建工具,可以用于自动生成构建文件,比如Makefile和Visual Studio工程文件。它通过一个名为CMakeLists.txt的配置文件来描述项目的构建过程。用户可以使用CMake来生成构建文件,然后使用其他工具来编译和链接项目。其次,CMake支持多种语言,包括C++、C、Fortran、Python等。它的目的是为了消除编译环境的差异,使用户能够在多种平台上轻松构建项目。最后,CMake支持分离编译,即将源文件和中间文件存放在不同的目录中。这样做的好处是可以更好地管理源文件和中间文件,并且可以更方便地进行多次编译。
在CMake中,"分离编译"指的是将源文件和中间文件存放在不同的目录中。这样做的好处是可以更好地管理源文件和中间文件,并且可以更方便地进行多次编译。
概念: CMake变量
CMake 语法指定了许多变量,这些变量可用于帮助在项目或源代码树中找到有用的目录。其中一些包括:
变量 |
信息 |
CMAKE_SOURCE_DIR |
根源目录 |
CMAKE_CURRENT_SOURCE_DIR |
如果使用子项目和目录,则为当前源目录。 |
PROJECT_SOURCE_DIR |
当前 cmake 项目的源目录。 |
CMAKE_BINARY_DIR |
根二进制文件生成目录。这是运行 cmake 命令的目录。 |
CMAKE_CURRENT_BINARY_DIR |
你当前所处的生成目录。 |
PROJECT_BINARY_DIR |
当前项目的生成目录。 |
概念: 详细输出调试
在前面的示例中,当运行 make 命令时,输出仅显示构建的状态。要查看用于调试目的的完整输出,可以在运行 make 时添加 VERBOSE=1 标志。
VERBOSE 输出如下所示。可以看到,include 目录已经被添加到了编译命令中。
0x02 示例
展示一个 hello world 示例,它使用不同的文件夹来存储源文件和头文件。
本教程中的文件包括:
ln28@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_02$ tree . ├── CMakeLists.txt ├── include │ └── hello.h └── src ├── hello.cpp └── main.cpp 2 directories, 4 files
CMake 中包含头文件的方式有多种,下面是一个示例:首先,我们创建一个 "include" 目录,用于存放头文件:
然后,在 "include" 目录中创建一个头文件,例如 "hello.h":
#include "hello.h" void print_hello() { std::cout << "Hello, World!" << std::endl; }
接着,在 "src" 目录中创建一个源文件,例如 "hello.cpp":
#include "hello.h" void print_hello() { std::cout << "Hello, World!" << std::endl; }
然后,在 "src" 目录中创建一个主函数文件,例如 "main.cpp":
#include "hello.h" int main() { print_hello(); return 0; }
接下来,我们需要使用 CMake 来构建项目。首先,在项目根目录下创建一个 "CMakeLists.txt" 文件:
cmake_minimum_required(VERSION 3.10) project(hello) # 设置 C++ 编译器选项 set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # 指定C++编译器 set(CMAKE_CXX_COMPILER /usr/bin/g++) # 添加头文件搜索路径 include_directories(${PROJECT_SOURCE_DIR}/include) # 指定源文件目录 set(CMAKE_SOURCE_DIR src/hello.cpp src/main.cpp) # 添加源文件 add_executable(hello ${CMAKE_SOURCE_DIR}) #-------------------------------不行 #target_include_directories(hello # PRIVATE # ${PROJECT_SOURCE_DIR}/include #) #file(GLOB CMAKE_SOURCE_DIR "src/*.cpp") #-------------------------------
最后,执行cmake ../ && make -j24 VERBOSE=1
ln28@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_02/build$ cmake ../ && make -j24 VERBOSE=1 -- Configuring done -- Generating done -- Build files have been written to: /mnt/d/Project/Cmake_examples/cmake_basics_02/build /usr/bin/cmake -S/mnt/d/Project/Cmake_examples/cmake_basics_02 -B/mnt/d/Project/Cmake_examples/cmake_basics_02/build --check-build-system CMakeFiles/Makefile.cmake 0 /usr/bin/cmake -E cmake_progress_start /mnt/d/Project/Cmake_examples/cmake_basics_02/build/CMakeFiles /mnt/d/Project/Cmake_examples/cmake_basics_02/build/CMakeFiles/progress.marks make -f CMakeFiles/Makefile2 all make[1]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_02/build' make -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/depend make[2]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_02/build' cd /mnt/d/Project/Cmake_examples/cmake_basics_02/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /mnt/d/Project/Cmake_examples/cmake_basics_02 /mnt/d/Project/Cmake_examples/cmake_basics_02 /mnt/d/Project/Cmake_examples/cmake_basics_02/build /mnt/d/Project/Cmake_examples/cmake_basics_02/build /mnt/d/Project/Cmake_examples/cmake_basics_02/build/CMakeFiles/hello.dir/DependInfo.cmake --color= Dependee "/mnt/d/Project/Cmake_examples/cmake_basics_02/build/CMakeFiles/hello.dir/DependInfo.cmake" is newer than depender "/mnt/d/Project/Cmake_examples/cmake_basics_02/build/CMakeFiles/hello.dir/depend.internal". Dependee "/mnt/d/Project/Cmake_examples/cmake_basics_02/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/mnt/d/Project/Cmake_examples/cmake_basics_02/build/CMakeFiles/hello.dir/depend.internal". Scanning dependencies of target hello make[2]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_02/build' make -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/build make[2]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_02/build' [ 33%] Building CXX object CMakeFiles/hello.dir/src/hello.cpp.o /usr/bin/g++ -I/mnt/d/Project/Cmake_examples/cmake_basics_02/include -std=c++11 -o CMakeFiles/hello.dir/src/hello.cpp.o -c /mnt/d/Project/Cmake_examples/cmake_basics_02/src/hello.cpp [ 66%] Building CXX object CMakeFiles/hello.dir/src/main.cpp.o /usr/bin/g++ -I/mnt/d/Project/Cmake_examples/cmake_basics_02/include -std=c++11 -o CMakeFiles/hello.dir/src/main.cpp.o -c /mnt/d/Project/Cmake_examples/cmake_basics_02/src/main.cpp [100%] Linking CXX executable hello /usr/bin/cmake -E cmake_link_script CMakeFiles/hello.dir/link.txt --verbose=1 /usr/bin/g++ CMakeFiles/hello.dir/src/hello.cpp.o CMakeFiles/hello.dir/src/main.cpp.o -o hello make[2]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_02/build' [100%] Built target hello make[1]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_02/build' /usr/bin/cmake -E cmake_progress_start /mnt/d/Project/Cmake_examples/cmake_basics_02/build/CMakeFiles 0