最近看到一个开源的CMake教程,从基础到进阶,结合例子讲解的很好,就想着做一个CMake教程的翻译系列。项目地址:https://github.com/ttroy50/cmake-examples。
本节demo地址:https://github.com/ttroy50/cmake-examples/tree/master/01-basic/A-hello-cmake
1 简介
展示一个简单的hello world 例子。
教程中的文件如下:
CMakeList.txt--包含要运行的CMake命令。
# Set the minimum version of CMake that can be used# To find the cmake version run# $ cmake --versioncmake_minimum_required(VERSION 3.5)# Set the project nameproject (hello_cmake)# Add an executableadd_executable(hello_cmake main.cpp)
main.cpp--一个简单的输出“Hello CMake”的cpp文件。
#include int main(int argc, char *argv[]){ std::cout << "Hello CMake!" << std::endl; return 0;}
2 概念
2.1 CMakeList.txt
txt文件应该存储你所有的CMake命令。当cmake在一个文件夹中运行时,它将寻找该文件,如果该文件不存在,cmake将退出并报错。
2.2 最低CMake版本
当使用CMake创建项目时,须要指定支持的CMake的最小版本。
cmake_minimum_required(VERSION 3.5)
2.3 工程(项目)
CMake构建可以包含一个项目名,以便在使用多个项目时更容易引用某些变量。
project(hello_cmake)
2.4 创建可执行文件
add_executable()命令指定应该从指定的源文件构建可执行文件,在本例中为main.cpp。add_executable()函数的第一个参数是要编译的可执行文件的名称,第二个参数是要编译的源文件列表。
add_executable(hello_cmake main.cpp)
NOTE:一种简单的写法是让项目名称和可执行文件同名,写法如下:
cmake_minimum_required(VERSION 2.6)project (hello_cmake)add_executable(${PROJECT_NAME} main.cpp)
在这个例子中,函数project()会创建一个变量${PROJECT_NAME},其值为hello_cmake。然后,可以将其传递给add_executable()函数,以输出一个“hello_cmake”可执行文件。
2.5 二进制文件路径
运行cmake命令的根目录称为CMAKE_BINARY_DIR,也是所有二进制文件的根文件夹。CMake支持就地(In-Place Build)构建和生成二进制文件,也支持Out-of-Source的构建。
2.5.1 In-Place Build
In-Place Build在与源代码相同的目录结构中生成所有临时构建文件。这意味着所有的makefile和对象文件都分散在正常的代码文件中。要创建一个In-Place Build目标,在根目录中运行cmake命令。例如:
A-hello-cmake$ cmake .-- The C compiler identification is GNU 4.8.4-- The CXX compiler identification is GNU 4.8.4-- Check for working C compiler: /usr/bin/cc-- Check for working C compiler: /usr/bin/cc -- works-- Detecting C compiler ABI info-- Detecting C compiler ABI info - done-- Check for working CXX compiler: /usr/bin/c++-- Check for working CXX compiler: /usr/bin/c++ -- works-- Detecting CXX compiler ABI info-- Detecting CXX compiler ABI info - done-- Configuring done-- Generating done-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/A-hello-cmakeA-hello-cmake$ tree.├── CMakeCache.txt├── CMakeFiles│ ├── 2.8.12.2│ │ ├── CMakeCCompiler.cmake│ │ ├── CMakeCXXCompiler.cmake│ │ ├── CMakeDetermineCompilerABI_C.bin│ │ ├── CMakeDetermineCompilerABI_CXX.bin│ │ ├── CMakeSystem.cmake│ │ ├── CompilerIdC│ │ │ ├── a.out│ │ │ └── CMakeCCompilerId.c│ │ └── CompilerIdCXX│ │ ├── a.out│ │ └── CMakeCXXCompilerId.cpp│ ├── cmake.check_cache│ ├── CMakeDirectoryInformation.cmake│ ├── CMakeOutput.log│ ├── CMakeTmp│ ├── hello_cmake.dir│ │ ├── build.make│ │ ├── cmake_clean.cmake│ │ ├── DependInfo.cmake│ │ ├── depend.make│ │ ├── flags.make│ │ ├── link.txt│ │ └── progress.make│ ├── Makefile2│ ├── Makefile.cmake│ ├── progress.marks│ └── TargetDirectories.txt├── cmake_install.cmake├── CMakeLists.txt├── main.cpp├── Makefile
在Windows上使用CMake-gui:
Where is the source code: 和 Where to build the binaries选择同一个目录即CMakeList.txt所在的目录。Config->Generate之后,源代码、工程文件都参杂在一起。
2.5.2 Out-of-Source Build
Out-of-Source Build允许创建单个构建文件夹,该文件夹可以位于文件系统的任何位置。所有临时构建和目标文件都位于这个目录中,保持源代码树的整洁。要创建一个Out-of-Source Build,在构建文件夹中运行cmake命令,并将其指向根目录CMakeLists.txt文件。如果想从头重新创建cmake环境,需要删除构建目录,然后重新运行cmake。
A-hello-cmake$ mkdir buildA-hello-cmake$ cd build/A-hello-cmake/build$ make ..make: Nothing to be done for ‘..’.matrim@freyr:~/workspace/cmake-examples/01-basic/A-hello-cmake/build$ cmake ..-- The C compiler identification is GNU 4.8.4-- The CXX compiler identification is GNU 4.8.4-- Check for working C compiler: /usr/bin/cc-- Check for working C compiler: /usr/bin/cc -- works-- Detecting C compiler ABI info-- Detecting C compiler ABI info - done-- Check for working CXX compiler: /usr/bin/c++-- Check for working CXX compiler: /usr/bin/c++ -- works-- Detecting CXX compiler ABI info-- Detecting CXX compiler ABI info - done-- Configuring done-- Generating done-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/A-hello-cmake/buildA-hello-cmake/build$ cd ..A-hello-cmake$ tree.├── build│ ├── CMakeCache.txt│ ├── CMakeFiles│ │ ├── 2.8.12.2│ │ │ ├── CMakeCCompiler.cmake│ │ │ ├── CMakeCXXCompiler.cmake│ │ │ ├── CMakeDetermineCompilerABI_C.bin│ │ │ ├── CMakeDetermineCompilerABI_CXX.bin│ │ │ ├── CMakeSystem.cmake│ │ │ ├── CompilerIdC│ │ │ │ ├── a.out│ │ │ │ └── CMakeCCompilerId.c│ │ │ └── CompilerIdCXX│ │ │ ├── a.out│ │ │ └── CMakeCXXCompilerId.cpp│ │ ├── cmake.check_cache│ │ ├── CMakeDirectoryInformation.cmake│ │ ├── CMakeOutput.log│ │ ├── CMakeTmp│ │ ├── hello_cmake.dir│ │ │ ├── build.make│ │ │ ├── cmake_clean.cmake│ │ │ ├── DependInfo.cmake│ │ │ ├── depend.make│ │ │ ├── flags.make│ │ │ ├── link.txt│ │ │ └── progress.make│ │ ├── Makefile2│ │ ├── Makefile.cmake│ │ ├── progress.marks│ │ └── TargetDirectories.txt│ ├── cmake_install.cmake│ └── Makefile├── CMakeLists.txt├── main.cpp
在Windows上,可以创建一个Build文件夹,Where to build the binaries指向Build文件夹即可:
3 构建示例
$ mkdir build$ cd build$ cmake ..-- The C compiler identification is GNU 4.8.4-- The CXX compiler identification is GNU 4.8.4-- Check for working C compiler: /usr/bin/cc-- Check for working C compiler: /usr/bin/cc -- works-- Detecting C compiler ABI info-- Detecting C compiler ABI info - done-- Check for working CXX compiler: /usr/bin/c++-- Check for working CXX compiler: /usr/bin/c++ -- works-- Detecting CXX compiler ABI info-- Detecting CXX compiler ABI info - done-- Configuring done-- Generating done-- Build files have been written to: /workspace/cmake-examples/01-basic/hello_cmake/build$ makeScanning dependencies of target hello_cmake[100%] Building CXX object CMakeFiles/hello_cmake.dir/hello_cmake.cpp.oLinking CXX executable hello_cmake[100%] Built target hello_cmake$ ./hello_cmakeHello CMake!
在Windows上会生成.sln工程文件,用vs打开编译运行即可。
下节(1.2 CMake基础-hello_headers)将会介绍把头文件和源文件分别放在各自的文件夹(include/src)中时,如何编写CMakeLists.txt。
注:封面来自CMake官网。