第四步,添加系统相关特性
相关代码:4_system
下面,我们考虑为我们的项目添加一些代码,这些代码所依赖的特性可能在目标平台上是没有的。
对于这个例子,我们将加入一些代码,这些代码依赖的是:目标平台是否具有 log
和 exp
函数。当然,几乎所有的平台都有这些函数,但是在这个教程中,我们假设它们是不通用的。
如果平台具有 log
和 exp
,那么我们就在程序中使用 log
和 exp
。
编辑项目文件 CMakeLists.txt
我们首先通过在顶级 CMakeLists.txt
中使用 CheckSymbolExists
. cmake
宏检测这些函数的可用性,如下:
# does this system provide the log and exp functions?
include(CheckSymbolExists)
set(CMAKE_REQUIRED_LIBRARIES "m")
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)
message("Begin!")
if (HAVE_LOG AND HAVE_EXP)
message("Have, have have!")
# add_definitions(-DHAVE_LOG)
# add_definitions(-DHAVE_EXP)
endif (HAVE_LOG AND HAVE_EXP)
message("End!")
注意
- 不知为何,有时
#if(HAVE_LOG AND HAVE_EXP)
为真,有时为假,确保这个变量的话,可以用 "cmake -DHAVE_LOG=ON -DHAVE_EXP=ON tutorial" 来调试。 - 对
log
和exp
的测试要在用于TutorialConfig.h
的configure_file
命令之前进行。configure_file
命令会根据当前在CMake
中的设置立即对文件进行配置。 - 使用
set(CMAKE_REQUIRED_LIBRARIES "m")
设置后,再进行检测否则可能会有问题。
编辑配置文件 TutorialConfig.h.in
接下来,我们修改 TutorialConfig.h.in
来定义哪些值以便 CMake
在平台上查找,如下:
// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP
注意:
- 前面
CMakeLists.txt
中的add_definitions(...)
与这里的#cmakedefine ...
是相互冲突的,不能同时存在,保留一个即可。
编辑代码文件 main.cpp
我们通过下述代码,可以在 log
和 exp
在系统中可用的时候,基于这两个函数提供一个可选的实现,如下:
// if we have both log and exp then use them
#if defined (HAVE_LOG) && defined (HAVE_EXP)
fprintf(stdout, "Result of exp(log(0.5))is:%ld\n", exp(log(0.5)));
#else // otherwise use an iterative approach
fprintf(stdout, "Don't support exp and log\n");
#endif
执行
$cmake -S tutorial -B build
$cmake --build build
$./build/Tutorial
./build/Tutorial Version 1.0
Usage: ./build/Tutorial number
$./build/Tutorial 25
Result of exp(log(0.5))is:4627730092099895296
custom square root.
The square root of 25 is 0
注意,第一条命令 -S
指定源码目录, -B
指定生成的编译目录。 第二条命令 --build
指明到 build
目录中编译,相当于 cd build && make
。
网友评论