https://cmake.org/cmake/help/latest/guide/tutorial/index.html
添加系统自检(步骤5)
让我们考虑将一些代码添加到我们的项目中,这取决于目标平台可能不具备的功能。 对于此示例,我们将添加一些代码,具体取决于目标平台是否具有log和exp函数。 当然,几乎每个平台都具有这些功能,但对于本教程而言,它们并不常见。
如果平台具有log和exp,那么我们将使用它们来计算mysqrt函数中的平方根。 我们首先使用顶级CMakeLists.txt中的CheckSymbolExists模块测试这些功能的可用性。 在某些平台上,我们将需要链接到m库。 如果最初没有找到log和exp,则需要m库,然后重试。
我们将在TutorialConfig.h.in中使用新定义,因此请确保在配置该文件之前进行设置。
include(CheckSymbolExists)
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)
if(NOT (HAVE_LOG AND HAVE_EXP))
unset(HAVE_LOG CACHE)
unset(HAVE_EXP CACHE)
set(CMAKE_REQUIRED_LIBRARIES "m")
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)
if(HAVE_LOG AND HAVE_EXP)
target_link_libraries(MathFunctions PRIVATE m)
endif()
endif()
现在,将这些定义添加到TutorialConfig.h.in中,以便我们可以从mysqrt.cxx中使用它们:
// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP
如果log和exp在系统上可用,那么我们将使用它们来计算mysqrt函数中的平方根。 将以下代码添加到MathFunctions / mysqrt.cxx中的mysqrt函数中(在返回结果之前不要忘记#endif!):
#if defined(HAVE_LOG) && defined(HAVE_EXP)
double result = exp(log(x) * 0.5);
std::cout << "Computing sqrt of " << x << " to be " << result
<< " using log and exp" << std::endl;
#else
double result = x;
我们还需要修改mysqrt.cxx以包括cmath。
#include <cmath>
运行cmake可执行文件或cmake-gui以配置项目,然后使用所选的构建工具进行构建,并运行Tutorial可执行文件。
您会注意到,即使我们认为它们应该可用,我们也没有使用log和exp。 我们应该很快意识到,我们忘记在mysqrt.cxx中包含TutorialConfig.h。
我们还需要更新MathFunctions / CMakeLists.txt,以便mysqrt.cxx知道此文件的位置:
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_BINARY_DIR}
)
完成此更新后,继续并再次构建项目,然后运行构建的Tutorial可执行文件。 如果仍未使用log和exp,请从构建目录中打开生成的TutorialConfig.h文件。 也许它们在当前系统上不可用?
sqrt或mysqrt哪个函数现在可以提供更好的结果?
指定编译定义
除了在TutorialConfig.h中保存HAVE_LOG和HAVE_EXP值,我们还有更好的地方吗? 让我们尝试使用target_compile_definitions()。
首先,从TutorialConfig.h.in中删除定义。 我们不再需要包含mysqrt.cxx中的TutorialConfig.h或MathFunctions / CMakeLists.txt中的其他包含内容。
接下来,我们可以将HAVE_LOG和HAVE_EXP的检查移至MathFunctions / CMakeLists.txt,然后将这些值指定为PRIVATE编译定义。
include(CheckSymbolExists)
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)
if(NOT (HAVE_LOG AND HAVE_EXP))
unset(HAVE_LOG CACHE)
unset(HAVE_EXP CACHE)
set(CMAKE_REQUIRED_LIBRARIES "m")
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)
if(HAVE_LOG AND HAVE_EXP)
target_link_libraries(MathFunctions PRIVATE m)
endif()
endif()
# add compile definitions
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(MathFunctions
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
完成这些更新后,继续并重新构建项目。 运行内置的Tutorial可执行文件,并验证结果与本步骤前面的内容相同。