CMake中的option用于控制编译流程,相当于C语言中的宏条件编译。
基本格式
options基本格式如下:
option(<variable> "<help_text>" [value])
- variable:定义选项名称
- help_text:说明选项的含义
- value:定义选项默认状态,一般是OFF或者ON,除去ON之外,其他所有值都为认为是OFF。
示例
示例项目结构如下:
- build:工程编译目录
- CMakeList.txt:cmake主编译脚本
- sub:子工程目录,sub子目录相当于一个子工程,用于演示主工程选项和子工程选项之间的关系。
- test.c测试程序
示例项目的功能如下:
- 说明cmake选项的基本用法。
- 说明如何通过cmake的选项,控制C程序条件编译。
- 说明主项目和子项目之间,同一选项之间的关系。
主工程CMakeList.txt编译脚本:
#Cmake 最低版本要求
cmake_minimum_required(VERSION 3.16)
#项目名称
project(CMakeExp)
message(STATUS "CMakeExpMaster.")
#set(TEST_OPTION OFF)
option(TEST_OPTION "test opiton" ABC)
if (DEFINED TEST_OPTION)
message(STATUS "TEST_OPTION defined: " ${TEST_OPTION})
else ()
message(STATUS "TEST_OPTION un-defined: " ${TEST_OPTION})
endif()
if (TEST_OPTION)
message(STATUS "TEST_OPTION ON.")
add_definitions(-DTEST_OPTION)
else ()
message(STATUS "TEST_OPTION OFF.")
endif()
if (NOT TEST_OPTION)
message(STATUS "NOT-TEST_OPTION ON.")
else ()
message(STATUS "NOT-TEST_OPTION OFF.")
endif()
add_subdirectory(sub)
add_executable(test test.c)
子工程编译脚本:
#Cmake 最低版本要求
cmake_minimum_required(VERSION 3.16)
#项目名称
project(CMakeExpSub)
message(STATUS "\n\nCMakeExpSub.")
option(TEST_OPTION "test opiton" ON)
if (DEFINED TEST_OPTION)
message(STATUS "TEST_OPTION defined: " ${TEST_OPTION})
else ()
message(STATUS "TEST_OPTION un-defined: " ${TEST_OPTION})
endif()
if (TEST_OPTION)
message(STATUS "TEST_OPTION ON.")
else ()
message(STATUS "TEST_OPTION OFF.")
endif()
test.c程序内容:
#include <stdio.h>
int main(void)
{
#ifdef TEST_OPTION
printf("Hello, CMake.\n");
#endif
return 0;
}
基本用法
主项目里定义的一个TEST_OPTION选项,如下:
option(TEST_OPTION "test opiton" ON)
下面对于TEST_OPTION选项定义,进行了测试:
if (DEFINED TEST_OPTION)
message(STATUS "TEST_OPTION defined: " ${TEST_OPTION})
else ()
message(STATUS "TEST_OPTION un-defined: " ${TEST_OPTION})
endif()
if (TEST_OPTION)
message(STATUS "TEST_OPTION ON.")
else ()
message(STATUS "TEST_OPTION OFF.")
endif()
进入build目录,执行cmake编译,结果如下:
$ cmake ..
在执行cmake时,可以使用-D+选项名称,修改选项的值,如下:
$cmake .. -DTEST_OPTION=OFF
cmake执行完成之后,选项的值会保存到CMakeCache.txt中。
C程序条件编译
通过判断选项的值,可以通过 add_definitions()定义相关的宏,已达到控制C程序条件编译流程。
示例中,如果TEST_OPTION选项的值是ON,那么就会定义TEST_OPTION宏,这样在test.c中就可以通过判断TEST_OPTION的声明情况,来控制编译流程。
#ifdef TEST_OPTION
printf("Hello, CMake.\n");
#endif
这里,如果TEST_OPTION宏被定义,那么test就会打印"Hello,CMake.
可以看到,test输出了“Hello,CMake.”。
主、次项目之间选项的关系
示例项目中,包括一个子项目,里面也定义了一个CMakeList.txt脚本,里面也定义了和主项目相同的选项TEST_OPTION,下面展示一下主、子项目之间,同一选项之间的关系。
主项目定义:
option(TEST_OPTION "test opiton" ON)
子项目定义:
option(TEST_OPTION "test opiton" OFF)
可以看到,虽然子项中TEST_OPTION选项定义为了OFF,但是,由于主项目中TEST_OPTION选项的值是ON,导致子项目的选项值变为了ON,可以看出,对于同一选项,子项目值遵循主项目的定义。
注意:对于这种,主、次架构的项目来说,整个工程只有一个CMakeCache.txt,其位于主项目的编译目录下,子项目会根据次此CMakeCache.txt中选项的定义,进行子项目本身的编译。