当前位置: 首页 > news >正文

CMake Tutorial 巡礼(5)_添加系统自察

CMake Tutorial巡礼(5)_ 添加系统自察

这是本系列的第六篇。
上一篇我们学习了如何生成安装包,以及如何使用ctest进行简单的测试。
这一篇我们继续学习,如何添加系统自察。什么是“系统自察”呢?具体到本例,就是对系统是否具有某些函数或功能进行预先的测试,通过判断系统的自身属性,在编译时决定采用不同的分支。

本章导读

在这里插入图片描述

第五步:添加系统自察

Let us consider adding some code to our project that depends on features the target platform may not have. For this example, we will add some code that depends on whether or not the target platform has the log and exp functions. Of course almost every platform has these functions but for this tutorial assume that they are not common.

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

If the platform has log and exp then we will use them to compute the square root in the mysqrt function. We first test for the availability of these functions using the CheckCXXSourceCompiles module in MathFunctions/CMakeLists.txt.

如果平台有logexp函数,那么我们将使用它们来计算mysqrt函数中的平方根。我们首先使用MathFunctions/CMakeLists.txt中的CheckCXXSourceCompiles模块测试这些函数的可用性。

Add the checks for log and exp to MathFunctions/CMakeLists.txt, after the call to target_include_directories():

MathFunctions/CMakeLists.txt中添加针对logexp的测试,位于target_include_directories()调用之后。

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)

If available, use target_compile_definitions() to specify HAVE_LOG and HAVE_EXP as PRIVATE compile definitions.

如果得到的验证结果是“可行”,使用target_compile_definitions()来指定HAVE_LOGHAVE_EXP,作为私有,即PRIVATE编译定义。

MathFunctions/CMakeLists.txt

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

小白按:以上修改完成后,最终修改的结果为

add_library(MathFunctions mysqrt.cxx)

# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
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)

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

# install rules
install(TARGETS MathFunctions DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)

If log and exp are available on the system, then we will use them to compute the square root in the mysqrt function. Add the following code to the mysqrt function in MathFunctions/mysqrt.cxx (don’t forget the #endif before returning the result!):

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

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;

We will also need to modify mysqrt.cxx to include cmath.

我们也需要修改mysqrt.cxx,使其包含cmath

MathFunctions/mysqrt.cxx

#include <cmath>

小白按:以上修改全部完成后,mysqrt.cxx的全貌为

#include <iostream>
#include <cmath>  

#include "MathFunctions.h" 
// a hack square root calculation using simple operations
double mysqrt(double x)
{
  if (x <= 0) {
    return 0;
  }  

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

Run the cmake executable or the cmake-gui to configure the project and then build it with your chosen build tool and run the Tutorial executable.

执行 cmakecmake-gui,指定项目,并且用你选定的编译工具进行编译,最后运行Tutorial可执行文件。

Which function gives better results now, sqrt or mysqrt?

哪一个函数给出了更优的结果?sqrt还是mysqrt?

小白按:给出所有的编译代码:

mkdir Step5_build
cd Step5_build
cmake ../Step5
cmake --build .
cd Debug
Tutorial 4294967206
cd ..
cmake ../Step5 -DUSE_MYMATH=OFF
cmake --build .
cd Debug
Tutorial 4294967206

两个结果分别是:

Computing sqrt of 4.29497e+09 to be 65536 using log and exp
The square root of 4.29497e+09 is 65536
The square root of 4.29497e+09 is 65536

可以看出,使用了logexp之后,平方根运算的精度已经和系统自带的sqrt函数不相上下了。

这一小节还算是比较容易+平顺的,下一回合我们将要学习“添加自定义命令和生成文件”。

【水平所限,错漏难免,创作不易,轻喷勿骂】

在这里插入图片描述

相关文章:

  • 注意力机制(attention)学习笔记
  • Cocos3.x 对象池NodePool使用介绍和注意事项
  • 计算机二级WPS 选择题(模拟和解析二)
  • java计算机毕业设计基于安卓Android微信的儿童疫苗接种管理小程序uniApp
  • 什么是协程?
  • [配置] 安卓 | 将微信公众号文章保存到Notion
  • Docker启动mysql服务
  • 基于java安全管理系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
  • 为何基于树的模型在表格型数据中能优于深度学习?
  • 贪心+二分
  • Geoserver Windows 安装部署教程
  • haproxy,nginx,keepalived综合运用
  • 动态多目标优化算法:MOEA/D-FD求解FDA1、FDA2、FDA3、FDA4和FDA5(Matlab代码)
  • 【基于C的排序算法】插入排序之直接插入排序
  • Golang——从入门到放弃
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • JS实现简单的MVC模式开发小游戏
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • Python连接Oracle
  • SpringBoot几种定时任务的实现方式
  • windows-nginx-https-本地配置
  • 简单实现一个textarea自适应高度
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 学习Vue.js的五个小例子
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • #AngularJS#$sce.trustAsResourceUrl
  • #define与typedef区别
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (二开)Flink 修改源码拓展 SQL 语法
  • (六)激光线扫描-三维重建
  • (三)Honghu Cloud云架构一定时调度平台
  • (转)Linux下编译安装log4cxx
  • (转)视频码率,帧率和分辨率的联系与区别
  • (转载)CentOS查看系统信息|CentOS查看命令
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET 8.0 中有哪些新的变化?
  • .net core使用ef 6
  • .net Signalr 使用笔记
  • .NET 分布式技术比较
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .net的socket示例
  • .Net下的签名与混淆
  • .Net中间语言BeforeFieldInit
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • .sh 的运行
  • ?.的用法
  • [ IOS ] iOS-控制器View的创建和生命周期
  • [ 网络基础篇 ] MAP 迈普交换机常用命令详解
  • [.NET 即时通信SignalR] 认识SignalR (一)
  • [2023-年度总结]凡是过往,皆为序章
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [C++提高编程](三):STL初识