CMake
允许为项目增加编译选项,从而可以根据用户的环境和需求选择最合适的编译方案。
例如,可以将 MathFunctions
库设为一个可选的库,如果该选项为 ON
,就使用该库定义的数学函数来进行运算。否则就调用标准库中的数学函数库。
我们要做的第一步是在根目录的 CMakeLists.txt
文件中添加该选项:
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo4)
# 是否使用自己的 MathFunctions 库
option (USE_MYMATH
"Use provided math implementation" ON)
# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)
# 是否加入 MathFunctions 库
if (USE_MYMATH)
include_directories ("${PROJECT_SOURCE_DIR}/math")
add_subdirectory (math)
set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 指定生成目标
add_executable(Demo ${DIR_SRCS})
target_link_libraries (Demo ${EXTRA_LIBS})
其中:
option
命令添加了一个 USE_MYMATH
选项,并且默认值为 ON
。configure_file
命令用于加入一个配置头文件 config.h
,这个文件由 CMake
从 config.h.in
生成,通过这样的机制,将可以通过预定义一些参数和变量来控制代码的生成。USE_MYMATH
变量的值来决定是否使用我们自己编写的 MathFunctions
库。之后修改 main.cc 文件,让其根据 USE_MYMATH
的预定义值来决定是否调用标准库还是 MathFunctions
库:
#include <stdio.h>
#include <stdlib.h>
#include <config.h>
#ifdef USE_MYMATH
#include <MathFunctions.h>
#else
#include <math.h>
#endif
int main(int argc, char *argv[])
{
if (argc < 3){
printf("Usage: %s base exponent \n", argv[0]);
return 1;
}
double base = atof(argv[1]);
int exponent = atoi(argv[2]);
#ifdef USE_MYMATH
printf("Now we use our own Math library. \n");
double result = power(base, exponent);
#else
printf("Now we use the standard library. \n");
double result = pow(base, exponent);
#endif
printf("%g ^ %d is %g\n", base, exponent, result);
return 0;
}
上面的程序值得注意的是第2行,这里引用了一个 config.h
文件,这个文件预定义了 USE_MYMATH
的值。但我们并不直接编写这个文件,为了方便从 CMakeLists.txt
中导入配置,我们编写一个 config.h.in
文件,内容如下:
#cmakedefine USE_MYMATH
这样 CMake 会自动根据 CMakeLists 配置文件中的设置自动生成 config.h 文件。
现在编译一下这个项目,为了便于交互式的选择该变量的值,可以使用 ccmake .
命令
从中可以找到刚刚定义的 USE_MYMATH
选项,按键盘的方向键可以在不同的选项窗口间跳转,按下 enter
键可以修改该选项。修改完成后可以按下 c
选项完成配置,之后再按 g
键确认生成 Makefile
。ccmake
的其他操作可以参考窗口下方给出的指令提示。
我们可以试试分别将 USE_MYMATH 设为 ON 和 OFF 得到的结果:
xuke@ubuntu:~/work/cmake-demo/Demo4$ cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /home/xuke/work/cmake-demo/Demo4
xuke@ubuntu:~/work/cmake-demo/Demo4$ make
[ 50%] Built target MathFunctions
[100%] Built target Demo
xuke@ubuntu:~/work/cmake-demo/Demo4$ ./Demo 3 2
Now we use our own Math library.
3 ^ 2 is 9
xuke@ubuntu:~/work/cmake-demo/Demo4$ cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /home/xuke/work/cmake-demo/Demo4
xuke@ubuntu:~/work/cmake-demo/Demo4$ make
Scanning dependencies of target Demo
[ 50%] Building CXX object CMakeFiles/Demo.dir/main.cc.o
[100%] Linking CXX executable Demo
[100%] Built target Demo
xuke@ubuntu:~/work/cmake-demo/Demo4$ ./Demo 3 2
Now we use the standard library.
3 ^ 2 is 9
[CMake 入门实战] http://www.hahack.com/codes/cmake/ [代码参考] https://github.com/wzpan/cmake-demo