CMake教程(七):添加系统检查

个人觉得 CMake 官网教程 Step6 对当前我们增加对 CMake 的了解作用不大,所以直接写了教程七。

现在,我们考虑在项目中添加一些代码,这些代码取决于目标平台可能没有的功能。对于这个例子,我们将添加一些代码,这取决于目标平台是否具有logexp 函数。几乎每个平台都具有这两个函数,在这里我们仅是作为例子来说明本节的内容。

本节的目标是根据可用的系统依赖让编译器有选择性编译具体的实现代码。

需要编辑的文件:

  • MathFunctions/CMakeLists.txt
  • MathFunctions/mysqrt.cxx

本节使用的源代码是官网 Step7 目录下的文件。一开始我们需要编辑 MathFunctions/CMakeLists.txt 文件,包含 CheckCXXSourceCompiles 模块。之后,使用 check_cxx_source_compiles 确认 cmath 库当中的 logexp 函数是否可用。如果它们可用,使用 target_compile_definitions() 指定 HAVE_LOGHAVE_EXP 作为编译定义。

MathFunctions/mysqrt.cxx 文件中,包含 cmath。之后,如果系统有 logexp 函数,使用它们计算平方根。

首先,修改 MathFunctions/mysqrt.cxx 文件,在其中添加下面的指令:
include(CheckCXXSourceCompiles)

之后,使用 check_cxx_compiles_source 测试 logexp 函数的可用性。此函数允许我们在编译真正的源代码之前,尝试编译具有所需依赖关系的简单代码。结果变量 HAVE_LOGHAVE_EXP 表示这些依赖关系是否可用。继续修改 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 的编译定义。继续修改 MathFunctions/CMakeLists.txt 文件,添加以下的内容:

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

  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()

接下来,我们需要修改 mysqrt.cxx 文件包含 cmath

#include <cmath>

如果 logexp 函数都可用,那么在 mysqrt 函数当中使用它们来计算平方根。修改 MathFunctions/mysqrt.cxx 文件中的 mysqrt 函数:

#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

执行结果:
在这里插入图片描述

如果想要使用我们自己编写的指数函数和对数函数,需要在 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 当中的 CheckCXXSourceCompiles 模块,该模块提供了一系列用于检查 C++ 源代码片段是否能够在当前系统上成功编译的宏。接着,使用 CHECK_CXX_SOURCE_COMPILES 指令让 CMake 编译一小段代码,如果编译成功,根据这个结果来设置变量、条件编译选项或者定义特定的特性。

最后,介绍 include(CheckCXXSourceCompiles) 的作用。

include(CheckCXXSourceCompiles) 的作用

在CMake中,include(CheckCXXSourceCompiles) 命令的作用是引入一个 CMake 模块,该模块提供了一系列用于检查 C++ 源代码片段是否能够在当前系统上成功编译的宏。这通常用于在配置(configure)阶段自动检测系统或编译器的特定功能或限制。

具体来说,CheckCXXSourceCompiles 模块定义了一个或多个宏,比如 CHECK_CXX_SOURCE_COMPILES,你可以使用这些宏来编写一小段 C++ 代码,并让 CMake 尝试编译这段代码。如果编译成功,你可以根据这个结果来设置变量、条件编译选项或者定义特定的特性。

使用 CHECK_CXX_SOURCE_COMPILES 宏时,需要提供至少两个参数:

  • 第一个参数是要执行的 C++ 代码;
  • 第二个参数是一个自定义的变量,用于存储编译这段代码的结果。

下面是一个简单的例子,展示了如何使用 CheckCXXSourceCompiles 来检测编译器是否支持 C++11 的某些特性(如 auto 关键字):

include(CheckCXXSourceCompiles)  
 
# 检查C++11的auto关键字是否可用  
CHECK_CXX_SOURCE_COMPILES("  
#include <vector>  
  
int main() {  
    std::vector<int> v = {1, 2, 3};  
    auto x = v[0];  
    return 0;  
}  
" HAVE_CXX11_AUTO)  
  
# 根据检查结果,可以做出不同的配置决策  
if(HAVE_CXX11_AUTO)  
    message(STATUS "Compiler supports C++11 auto keyword.")  
else()  
    message(FATAL_ERROR "Compiler does not support C++11 auto keyword.")  
endif()

各位道友,码字不易,如有收获,记得一键三连啊。
看完觉得有帮助的道友,可以关注我的公众号,里面会分享一些高质量的个人成长类读书笔记、生活随笔以及职场经验等等。
在这里插入图片描述

世界地图矢量数据可以通过多种网站进行下载。以下是一些提供免费下载世界地图矢量数据的网站: 1. Open Street Map (https://www.openstreetmap.org/): 这个网站可以根据输入的经纬度或手动选定范围来导出目标区域的矢量图。导出的数据格式为osm格式,但只支持矩形范围的地图下载。 2. Geofabrik (http://download.geofabrik.de/): Geofabrik提供按洲际和国家快速下载全国范围的地图数据。数据格式支持shape文件格式,包含多个独立图层,如道路、建筑、水域、交通、土地利用分类、自然景观等。数据每天更新一次。 3. bbbike (https://download.bbbike.org/osm/): bbbike提供全球主要的200多个城市的地图数据下载,也可以按照bbox进行下载。该网站还提供全球的数据,数据格式种类齐全,包括geojson、shp等。 4. GADM (https://gadm.org/index.html): GADM提供按国家或全球下载地图数据的服务。该网站提供多种格式的数据下载。 5. L7 AntV (https://l7.antv.antgroup.com/custom/tools/worldmap): L7 AntV是一个提供标准世界地图矢量数据免费下载的网站。支持多种数据格式下载,包括GeoJSON、KML、JSON、TopJSON、CSV和高清SVG格式等。可以下载中国省、市、县的矢量边界和世界各个国家的矢量边界数据。 以上这些网站都提供了世界地图矢量数据的免费下载服务,你可以根据自己的需求选择合适的网站进行下载。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值