第 7 步:添加系统自检

让我们考虑向我们的项目添加一些代码,这些代码取决于目标平台可能没有的功能。对于这个例子,我们将添加一些代码,这取决于目标平台是否有 logexp 函数。当然几乎每个平台都有这些功能,但在本教程中假设它们并不常见。

练习 1 - 评估依赖可用性

目标

根据可用的系统依赖项更改实现。

有用的资源

要编辑的文件

  • MathFunctions/CMakeLists.txt

  • MathFunctions/mysqrt.cxx

入门

起始源代码在“Step7”目录中提供。在本练习中,完成“TODO 1”到“TODO 5”。

首先编辑``MathFunctions/CMakeLists.txt``。包括 CheckCXXSourceCompiles 模块。然后,使用 check_cxx_source_compiles 确定 logexp 是否可从 cmath 获得。如果它们可用,请使用 target_compile_definitions() 指定 HAVE_LOGHAVE_EXP 作为编译定义。

在“MathFunctions/mysqrt.cxx”中,包含“cmath”。然后,如果系统有 logexp,用它们来计算平方根。

构建并运行

创建一个名为“Step7_build”的新目录。运行 cmake 可执行文件或 cmake-gui 来配置项目,然后使用您选择的构建工具构建它并运行 ` `教程``可执行文件。

这可能类似于以下内容:

mkdir Step7_build
cd Step7_build
cmake ../Step7
cmake --build .

现在哪个函数给出更好的结果,sqrtmysqrt

解决方案

在本练习中,我们将使用 CheckCXXSourceCompiles 模块中的函数,因此首先我们必须将其包含在 MathFunctions/CMakeLists.txt 中。

TODO 1: Click to show/hide answer
TODO 1:MathFunctions/CMakeLists.txt
include(CheckCXXSourceCompiles)

然后使用 check_cxx_compiles_source 测试 logexp 的可用性。这个函数让我们在真正的源代码编译之前尝试编译具有所需依赖关系的简单代码。结果变量 HAVE_LOGHAVE_EXP 表示这些依赖项是否可用。

TODO 2: Click to show/hide answer
TODO 2:MathFunctions/CMakeLists.txt
check_cxx_source_compiles("
  #include <cmath>
  int main() {
    std::log(1.0);
    return 0;
  }
" HAVE_LOG)
check_cxx_source_compiles("
  #include <cmath>
  int main() {
    std::exp(1.0);
    return 0;
  }
" HAVE_EXP)

接下来,我们需要将这些 CMake 变量传递给我们的源代码。这样,我们的源代码就可以知道哪些资源可用。如果 logexp 都可用,请使用 target_compile_definitions()HAVE_LOGHAVE_EXP 指定为 PRIVATE 编译定义。

TODO 3: Click to show/hide answer
TODO 3:MathFunctions/CMakeLists.txt
if(HAVE_LOG AND HAVE_EXP)
  target_compile_definitions(MathFunctions
                             PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()

由于我们可能会使用 logexp,因此我们需要修改 mysqrt.cxx 以包含 cmath

TODO 4: Click to show/hide answer
TODO 4:MathFunctions/mysqrt.cxx
#include <cmath>

如果 logexp 在系统上可用,则使用它们在 mysqrt 函数中计算平方根。 MathFunctions/mysqrt.cxx 中的``mysqrt`` 函数如下所示:

TODO 5: Click to show/hide answer
TODO 5:MathFunctions/mysqrt.cxx
#if defined(HAVE_LOG) && defined(HAVE_EXP)
  double result = std::exp(std::log(x) * 0.5);
  std::cout << "Computing sqrt of " << x << " to be " << result
            << " using log and exp" << std::endl;
#else
  double result = x;