cmakelists自定义选项

目录结构如下:

math 目录下的 CMakeLists.txt 文件如下:

aux_source_directory(. DIR_LIB_SRCS)

# 生成链接库

add_library(MathFunctions ${DIR_LIB_SRCS})

cmake 允许为项目增加编译选项,从而可以根据用户的环境和需求选择最合适的编译方案。
例如,可以将 MathFunctions 库设为一个可选的库,如果该选项为 ON ,就使用该库定义的数学函数来进行运算,否则就调用标准库中的数学函数库。
修改根目录下的 CMakeLists.txt 文件如下:

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo)
# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
    "${PROJECT_SOURCE_DIR}/config.h.in"
    "${PROJECT_BINARY_DIR}/config.h"
    )
# 是否使用自己的 MathFunctions 库
option (USE_MYMATH
        "Use provided math implementation" ON)
# 是否加入 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})
  •     configure_file 命令用于加入一个配置头文件 config.h ,这个文件由 cmake 从 config.h.in 生成,通过这样的机制,将可以通过预定义一些参数和变量来控制代码的生成。
  •     option 命令添加了一个 USE_MYMATH 选项,并且默认值为 ON 。根据 USE_MYMATH 变量的值来决定是否使用我们自己编写的 MathFunctions 库。

        修改 main.cc 文件,让其根据 USE_MYMATH 的预定义值来决定是否调用标准库还是MathFunctions 库:

#include "config.h"
#ifdef USE_MYMATH
    #include "math/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;
}

编写 config.h.in 文件
        注意 main.cc 的第一行,这里引用了一个 config.h 文件,这个文件预定义了 USE_MYMATH 的值。但我们并不直接编写这个文件,为了方便从 CMakeLists.txt 中导入配置,我们编写一个 config.h.in 文件,内容如下:

#cmakedefine USE_MYMATH

        这样 cmake 会自动根据 CMakeLists.txt 配置文件中的设置自动生成 config.h 文件。

结合自己案例:

src新增 config.h.in文件,内容如下:

#cmakedefine USE_MYMATH

// == 下面试测试用的
#cmakedefine01 TEST_ON
#cmakedefine01 TEST_OF

#ifndef __${VAR}___@VAR@

#endif

进入build 开始构建,然后执行bin目录下的./sample8 2 8 输出:
Now we use our own Math library.
2 ^ 8 is 256

打开 build/src下的config.h文件,内容为:

/* #undef USE_MYMATH */

// == 下面试测试用的
#define TEST_ON 1
#define TEST_OF 0

#ifndef __VAR_NEW___VAR_NEW

#endif

cmake新增语法解释:

  • option (USE_MYMATH "Use provided math implementation" ON)指令
    给变量赋值 ON,代表真;OFF关键字则代表 假
  • configure_file(<input> <output> [COPYONLY] [ESCAPE_QUOTES] [@ONLY])
    对指定的输入文件中的内容按照指定的规则进行替换,替换完成后输出到output指定的输出路径

替换规则为:
1、在输入文件中,凡是以${VAR}格式或@VAR@格式出现的地方都将用CMake中对应变量的值进行替换,如上例中VAR变量的值为VAR_NEW,config.h中全部替换成了这个值
2、在输入文件中,类似于#cmakedefine VAR的定义语句将会被替换为#define VAR或者/* #undef VAR /,如上例中USE_MYMATH当设定为ON的时候,config.h变成了#define USE_MYMATH,设定为OFF时,变成了/ #undef USE_MYMATH */;同理,类似于#cmakedefine01 VAR的定义语句将会被替换为#define VAR 1或#define VAR 0。

     调试Tips: 

        每次想改变MYDEBUG时都需要去修改CMakeLists.txt,有点麻烦,其实可以通过cmake的命令行去操作,例如我们想把MYDEBUG设置为OFF,先cd到build目录,然后输入cmake .. -DMYDEBUG=ON,这样就可以编译出main1和main2 (在bin目录下)

  • cmake .. -DWWW1=ON -DWWW2=OFF && make
  • cmake .. -DWWW1=OFF -DWWW2=ON && make
  • cmake .. -DWWW1=ON -DWWW2=ON && make
  • -DWWW1对应的是源文件宏定义的WWW1

        这里有个小坑要注意下:假设使用cmake设置了一个option叫A,下次再设置别的option例如B,如果没有删除上次执行cmake时产生的缓存文件,那么这次虽然没设置A,也会默认使用A上次的option值。

        所以如果option有变化,要么删除上次执行cmake时产生的缓存文件,要么把所有的option都显式的指定其值。
 

tips: 如果将CMakeLists.txt中的
@# 是否使用自己的 Math库
option (USE_MYMATH "Use provided math implementation" ON)
@# 用于测试替换用的变量
set(TEST_ON 1)
set(TEST_OF 0)
set(VAR "VAR_NEW")
这一段写到config_file指令的后面,会发生什么?
只有放到前面,config_file指令执行时这些变量才是有效的,切莫注意


 

https://www.jianshu.com/p/f0f71d36411a

CMakeLists.txt 语法介绍与实例演练_阿飞的博客-CSDN博客_cmakelist

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值