cmake教程5-macro宏定义以及传递参数给源文件

引入在C++程序中我们经常见到如下,两个问题:
1. 输出当前程序的版本号
2. 通过cmake添加macro宏定义 出入到源文件,例如在编译opencv/caffe的时候,我们通过cmake -DUSE_CUDA=ON/OFF来确定,是否使用cuda.
问题cmake中如何实现上述两个功能的呢?

至于问题1:

我们可能想到直接在头文件中定义,这样也可以,但是如果直接在cmake中定义,然后传递给程序读取生成更加灵活。

至于问题2:

可以在cmake中通过option函数以及add_definitions函数来实现。

感兴趣也可以看 stack overflow:How to read a CMake Variable in C++ source code

cmake 传递版本号给源文件

首先定义demo11Config.h.in头文件接受CMakeLists.txt传递来的版本号参数,文件内容如下:

// the configured options and settings for demo11
#define demo11_VERSION_MAJOR @demo11_VERSION_MAJOR@
#define demo11_VERSION_MINOR @demo11_VERSION_MINOR@

demo11.cpp代码如下:


#include <stdio.h>
// demoConfig.h文件是cmake生成的
#include "demoConfig.h"

int main(int argc, char* argv[]){

    printf("%s version: %d.%d \n", argv[0], demo11_VERSION_MAJOR, demo11_VERSION_MINOR);
}

注意的是demoConfig.h是生成的在项目结构中并不存在,项目目录如下:

这里写图片描述

CMakeLists.txt如下:

cmake_minimum_required(VERSION 
### CMake宏定义的使用方法 在 CMake 脚本中,可以通过多种方式实现宏定义的功能。以下是几种常见的方法及其具体示例。 #### 方法一:通过 `add_definitions` 添加编译选项 CMake 提供了一个简单的命令来向项目添加全局宏定义。这通常用于设置一些影响整个项目的配置参数[^1]。 ```cmake # 定义名为 USE_MYLIB 的宏 add_definitions(-DUSE_MYLIB) # 如果需要传递额外的值给宏,也可以这样做 add_definitions(-DMY_VERSION="\"1.0.0\"") ``` 上述代码会在编译器调用时自动附加 `-DUSE_MYLIB` 和 `-DMY_VERSION=\"1.0.0\"` 参数,从而使得这些宏可以在源文件中被识别并使用。 --- #### 方法二:通过 `macro` 或 `function` 创建自定义宏/函数 如果希望创建更复杂的逻辑或者封装某些重复操作,则可以利用 `macro` 或者 `function` 来完成这一目标[^2]。 ##### 使用 `macro` 当不需要返回值的情况下,可以选择 `macro`: ```cmake # 定义一个名为 define_colors 的宏 macro(define_colors) message(STATUS "Defining color macros...") add_definitions(-DCOLOR_RED="#FF0000") add_definitions(-DCOLOR_GREEN="#00FF00") add_definitions(-DCOLOR_BLUE="#0000FF") endmacro() # 调用该宏 define_colors() ``` 注意,在 `macro` 内部修改变量的行为会直接影响到外部作用域中的同名变量。 ##### 使用 `function` 相比之下,`function` 更适合于局部化处理,因为它不会污染父级作用域内的变量状态: ```cmake # 定义一个名为 generate_version_info 的函数 function(generate_version_info output_var major minor patch) set(version_string "${major}.${minor}.${patch}") set(${output_var} ${version_string} PARENT_SCOPE) # 将结果传回上层作用域 endfunction() # 调用此函数并将版本号存储至 VERSION 变量 generate_version_info(VERSION 1 2 3) message(STATUS "Generated version: ${VERSION}") # 输出 Generated version: 1.2.3 ``` --- #### 方法三:取消或重新定义现有宏 有时可能需要移除已有的宏定义,或者是基于条件动态调整它们的内容。此时可借助未文档化的 `_remove definitions` 技巧以及 XMACRO 高级模式[^3]。 ##### 移除特定宏 虽然官方并未提供直接删除单个宏的方法,但可以通过清理所有先前指定过的定义列表再重建的方式间接达成目的: ```cmake set(CMAKE_C_FLAGS "") # 清空原有标志位 string(REPLACE "-DUSE_OLD_FEATURE" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") # 紧接着重新加入新的必要项 add_definitions(-DUSE_NEW_FEATURE=1) ``` ##### 利用 XMACRO 扩展功能 对于复杂的数据结构初始化场景(比如枚举类型),XMACRO 是一种优雅的选择: ```c++ // 在头文件中声明扩展点 #define CMD_LIST(X) \ X(FUNC_A, "Function A") \ X(FUNC_B, "Function B") typedef enum { #undef X #define X(name, desc) name, CMD_LIST(X) #undef X CMD_MAX } tCmd; ``` 随后可在其他地方重载相同的模板生成不同用途的信息表: ```c++ const char* cmd_descriptions[] = { #undef X #define X(name, desc) [name] = #desc, CMD_LIST(X) }; ``` 以上展示了如何灵活运用 CMake 结合宿主语言特性构建强大的抽象机制。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值