CMake教程Step5(添加系统自检)

CMake官方文档

参考官方cmake3.24教程翻译。我这里使用cmake 3.16来演示例子。 step5 我的仓库 :

让我们考虑向项目中添加一些依赖于目标平台可能不具备的特性的代码。 对于本例,我们将添加一些依赖于目标平台是否具有log和exp函数的代码。当然,几乎每个平台都有这些功能,但在本教程中假设它们并不常见。 如果平台有log和exp,那么我们将使用它们在mysqrt函数中计算平方根。

我们首先使用MathFunctions/CMakeLists.txt中的CheckCXXSourceCompiles模块来测试这些函数的可用性。 在调用target_include_directories()之后,将log和exp的检查添加到MathFunctions/CMakeLists.txt:

target_include_directories(MathFunctions
          INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
          )

# does this system provide the log and exp functions?
include(CheckCXXSourceCompiles)
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)

如果可用,使用target_compile_definitions()将HAVE_LOG和HAVE_EXP指定为私有编译定义。

if(HAVE_LOG AND HAVE_EXP)
  target_compile_definitions(MathFunctions
                             PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()

如果log和exp在系统上可用,那么我们将使用它们在mysqrt函数中计算平方根。将以下代码添加到math_functions/mysqrt.cxx中的mysqrt函数中(在返回结果之前不要忘记#endif):

#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;

我们还需要修改mysqrt.cxx包含cmath头文件。

#include <cmath>

到这里,mysqrt.cxx内容长这样:

#include <cmath>
#include <iostream>

#include "MathFunctions.h"

// a hack square root calculation using simple operations
double mysqrt(double x)
{
          
   
  if (x <= 0) {
          
   
    return 0;
  }

  // if we have both log and exp then use them
#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;

  // do ten iterations
  for (int i = 0; i < 10; ++i) {
          
   
    if (result <= 0) {
          
   
      result = 0.1;
    }
    double delta = x - (result * result);
    result = result + 0.5 * delta / result;
    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
  }
#endif
  return result;
}

运行cmake可执行文件或cmake-gui来配置项目,然后使用您选择的构建工具构建它,并运行教程可执行文件。

测试

现在哪个函数给出了更好的结果,sqrt还是mysqrt?

经验分享 程序员 微信小程序 职场和发展