cmake中的configure_file() 和option()命令

1、configure_file() 命令:

configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"	// 源文件(用户提供)
  "${PROJECT_BINARY_DIR}/config.h"		// 目标文件路径(由cmake生成,用户可在源代码中使用)
  )
1.1 用于标识宏
  • 在 CMake 配置时,configure_file() 可以将 config.h.in 中的占位符替换为具体的值,生成最终的 config.h 文件。(注:名称可随意haha.h.in也行)
  • config.h.in #cmakedefine USE_MYMATH ,这个使用#cmakedefine就表示了这是个占位符,可以通过 -D 选项在命令行中进行设置。例如:cmake -DUSE_MYMATH=OFF /path/to/source,如果设置为OFF,则生成的config.h中,该宏被注释掉:/*#define USE_MYMATH*/
  • config.h 通常用于在源代码中使用,例如条件编译,控制预处理器宏的定义。
1.2 用于变量
  • 比如在ver.h.in中,const char* ver = "${cf_example_VERSION}",这相当于设置了一个cmake变量cf_example_VERSION,这里${}是取值操作,这个变量可以在CmakeLists.txt 中用set()来设置
  • 然后再CmakeLists.txt文件中,设置变量值
    set (cf_example_VERSION_MAJOR 0)
    set (cf_example_VERSION_MINOR 2)
    set (cf_example_VERSION_PATCH 1)
    set (cf_example_VERSION "${cf_example_VERSION_MAJOR}.${cf_example_VERSION_MINOR}.${cf_example_VERSION_PATCH}")	
    
  • 最后在你的源码中,包含头文件ver.h,就可以使用变量了,比如cout << ver << "\n";

2、option() 命令:
用于在 CMakeLists.txt 中定义一个 CMake 变量比如 USE_MYMATH,并且默认值为ON。这个变量的值也可以在 CMake 配置时通过 -D 选项来修改。例如:cmake -DUSE_MYMATH=OFF /path/to/source

option(USE_MYMATH "Use provided math implementation" ON)

option() 通常用于控制 CMakeLists.txt 中的条件编译逻辑,影响生成的构建系统和代码

比如在CmakeLists.txt中:

option(USE_MYMATH "Use provided math implementation" ON) // 默认为ON,可以通过-DUSE_MYMATH=OFF 来修改

if (USE_MYMATH)	// 这里根据它的值来决定是否用math这个我们自定义的库
  	include_directories ("${PROJECT_SOURCE_DIR}/math")
  	add_subdirectory (math)  
  	set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)

重点:.h.in 文件和 option() 命令分别定义了一个变量 USE_MYMATH,它们之间是相互独立的。.h.in 文件中的 USE_MYMATH 是在 configure_file() 运行时被替换的。-DUSE_MYMATH 是用于在 CMake 运行时通过命令行设置变量的一种方式。如果你使用 -DUSE_MYMATH=OFF,那么这个值会影响到 CMake 中 option() 定义的变量,同时也会在 configure_file() 运行时替换 .h.in 文件中的相应占位符。

所以,这两种设置方式互相独立,但在最终的配置过程中,它们会共同影响到 config.h 文件的生成。

一般来说

  • option() 定义的cmake变量的作用域是 CMakeLists.txt,用于控制 CMake 构建时的条件逻辑。
  • configure_file() 命令的源文件中的变量或宏的作用域是 源代码,用于在编译时通过预处理器宏来影响源代码的编译行为,或者生成一些变量或代码,以供使用。

顺带说一句,标识宏和常量宏定义方法不太一样

标识宏(Identity Macro):

  • 这类宏通常被用作开关或标志,用于条件编译。在 config.h 文件中使用,通过预处理器宏的定义或注释来控制代码的编译。

  • 例如,在 config.h.in 中定义:

    // config.h.in
    #cmakedefine USE_FEATURE_XYZ
    
    • 通过-D命令设为ON 或 OFF
    • 用户可以通过 CMake 的 configure_file() 来生成 config.h,然后在代码中使用它来控制条件编译。

常量宏(Constant Macro):

  • 这类宏通常用于定义常数,例如定义某个固定的最大值。可以使用 add_compile_definitionstarget_compile_definitionsCMakeLists.txt 文件中定义。
  • 例如,在 CMakeLists.txt 中定义:
    add_compile_definitions(MAX=65536)
    

这将在编译时将 MAX 定义为 65536,在代码中使用它作为一个常量值。

### CMake 配置教程 #### 使用 `configure_file` 进行文件配置 为了理解如何使用 `configure_file` 来处理模板文件并生成最终使用的源码或头文件,可以考虑如下场景: 当项目中有依赖于构建环境设置的宏定义或其他预处理器指令时,可以通过 `configure_file` 自动生成相应的头文件。此命令允许将输入文件中的特定标记替换为当前构建上下文中定义的实际值。 对于给定的例子,在 `config.h.cmake` 文件中定义了一系列可能被条件化包含或排除以及直接赋值的内容[^3]。具体来说, ```cmake // config.h.cmake #cmakedefine VAR0 #cmakedefine01 VARB #cmakedefine VAR1 @VAR1@ #cmakedefine VAR2 ${VAR2} ``` 这里展示了不同类型的变量声明方式及其对应的替代模式。其中 `${}` `@...@` 是两种常见的语法形式用来表示待替换的位置;而 `#cmakedefine` 则用于控制是否应该在输出文件里保留该行代码。 接着,在主 `CMakeLists.txt` 脚本内设置了各个必要的变量之后调用了 `configure_file()` 函数完成实际转换过程: ```cmake set(VAR0 "VAR000") set(VAR1 "VAR111") set(VAR2 VAR222) option(VARB "" ON) configure_file( "${PROJECT_SOURCE_DIR}/include/config.h.cmake" "${PROJECT_BINARY_DIR}/include/config.h" @ONLY ) ``` 这段脚本指定了源文件路径 (`"${PROJECT_SOURCE_DIR}/include/config.h.cmake"`), 输出目标位置(`"${PROJECT_BINARY_DIR}/include/config.h"`) 并且选择了只做字符串替换而不关心其他内容 (通过传递参数 `@ONLY`). #### 创建包配置文件 除了简单的文本替换外,有时还需要创建更复杂的配置文件以便第三方应用程序能够方便地找到集成自己的库。这时就可以利用 `configure_package_config_file` 命令来辅助实现这一目的[^2]. 假设有一个名为 MyLib 的共享库希望提供给他人使用,则可以在其顶层 CMakeList 中加入类似这样的片段: ```cmake find_package(PkgConfig REQUIRED) pkg_check_modules(PC_MYLIB QUIET mylib) include(CMakePackageConfigHelpers) write_basic_package_version_file( "${PROJECT_BINARY_DIR}/MyLibConfigVersion.cmake" COMPATIBILITY SameMajorVersion ) configure_package_config_file( "${PROJECT_SOURCE_DIR}/cmake/MyLibConfig.cmake.in" "${PROJECT_BINARY_DIR}/MyLibConfig.cmake" INSTALL_DESTINATION lib/cmake/mylib PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR ) install(FILES "${PROJECT_BINARY_DIR}/MyLibConfig.cmake" "${PROJECT_BINARY_DIR}/MyLibConfigVersion.cmake" DESTINATION lib/cmake/mylib ) ``` 以上代码段首先尝试获取有关本地是否存在兼容版本的信息,随后编写基本版本验证逻辑存入临时文件,并最终基于模板生成完整的配置描述文档供后续引用.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宗浩多捞

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值