CMake入门(一)
编译:mkdir build && cd build && cmake .. && cmake --build .
cmake .. -ONNXRUNTIME_ROOTDIR=/home/data/yelong/onnxruntime-linux-x64-1.10.0/
CMake教程
在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:
- 编写 CMake 配置文件 CMakeLists.txt 。
- 执行命令
cmake PATH
或者ccmake PATH
生成 Makefile(ccmake
和cmake
的区别在于前者提供了一个交互式的界面)。其中,PATH
是 CMakeLists.txt 所在的目录。 - 使用
make
命令进行编译。
CMakeLists.txt 的语法:
由命令、注释和空格组成,其中命令是不区分大小写的。符号 #
后面的内容被认为是注释。
命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔。
入门案例:单个源文件
举例:
1 | # CMake 最低版本号要求 |
依次出现了几个命令:
cmake_minimum_required
:指定运行此配置文件所需的 CMake 的最低版本;project
:参数值是Demo1
,该命令表示项目的名称是Demo1
。add_executable
: 将名为 main.cc 的源文件编译成一个名称为 Demo 的可执行文件。
编译项目
==在当前目录执行 cmake .
,得到 Makefile 后再使用 make
命令编译==得到 Demo1 可执行文件。
(先cmake,再make)
多个源文件
同一目录,多个源文件
上面的例子只有单个源文件。现在假如把 power
函数单独写进一个名为 MathFunctions.c
的源文件里,使得这个工程变成如下的形式:
1 | ./Demo2 |
这个时候,CMakeLists.txt 可以改成如下的形式:
1 | # CMake 最低版本号要求 |
唯一的改动只是在 add_executable
命令中增加了一个 MathFunctions.cc
源文件。这样写当然没什么问题,但是如果源文件很多,把所有源文件的名字都加进去将是一件烦人的工作。更省事的方法是使用 aux_source_directory
命令,该命令会查找指定目录下的所有源文件,然后将结果存进指定变量名。其语法如下:
1 | aux_source_directory(<dir> <variable>) |
因此,可以修改 CMakeLists.txt 如下:
1 | # CMake 最低版本号要求 |
在CMake中使用C++11
add_definitions(-std=c++11)
多个目录,多个源文件
现在进一步将 MathFunctions.h 和 MathFunctions.cc 文件移动到 math 目录下。
1 | ./Demo3 |
对于这种情况,需要分别在项目根目录 Demo3 和 math 目录里各编写一个 CMakeLists.txt 文件。为了方便,我们可以先将 math 目录里的文件编译成静态库再由 main 函数调用。
根目录中的 CMakeLists.txt :
1 | # CMake 最低版本号要求 |
该文件添加了下面的内容: 第3行,使用命令 add_subdirectory
指明本项目包含一个子目录 math,这样 math 目录下的 CMakeLists.txt 文件和源代码也会被处理 。第6行,使用命令 target_link_libraries
指明可执行文件 main 需要连接一个名为 MathFunctions 的链接库 。
子目录(math/)中的 CMakeLists.txt:
1 | # 查找当前目录下的所有源文件 |
在该文件中使用命令 add_library
将 src 目录中的源文件编译为静态链接库。
小结:在根目录和子目录都建了cmakelist,然后子目录生成链接库,根目录通过target_link_libraies
来链接这个库,这里链接的指令可以写在生成可执行文件的命令add_executable
之后。
自定义编译选项
CMake 允许为项目增加编译选项,从而可以根据用户的环境和需求选择最合适的编译方案。
例如,可以将 MathFunctions 库设为一个==可选的库==,如果该选项为 ON
,就使用该库定义的数学函数来进行运算。否则就调用标准库中的数学函数库。
修改 CMakeLists 文件
我们要做的第一步是在顶层的 CMakeLists.txt 文件中添加该选项:
1 | # CMake 最低版本号要求 |
其中:
- 第7行的
configure_file
命令用于加入一个配置头文件 config.h ,这个文件由 CMake 从 config.h.in 生成,通过这样的机制,将可以通过预定义一些参数和变量来控制代码的生成。 - 第13行的
option
命令添加了一个USE_MYMATH
选项,并且默认值为ON
。 - 第17行根据
USE_MYMATH
变量的值来决定是否使用我们自己编写的 MathFunctions 库。
修改 main.cc 文件
之后修改 main.cc 文件,让其根据 USE_MYMATH
的预定义值来决定是否调用标准库还是 MathFunctions 库:
1 |
|
编写 config.h.in 文件
上面的程序值得注意的是第2行,这里引用了一个 config.h 文件,这个文件预定义了 USE_MYMATH
的值。但我们并不直接编写这个文件,为了方便从 CMakeLists.txt 中导入配置,我们编写一个 config.h.in 文件,内容如下:
1 | #cmakedefine USE_MYMATH |
这样 CMake 会自动根据 CMakeLists 配置文件中的设置自动生成 config.h 文件。