2401cmake,学习cmake2

步4:安装与测试

现在开始给项目添加安装规则和支持测试.

安装规则

安装规则非常简单:对MathFunctions,想安装库和头文件,对应用,想安装可执行文件和配置头.

所以在MathFunctions/CMakeLists.txt尾添加:

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

在顶层CMakeLists.txt尾添加:

install(TARGETS Tutorial DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"DESTINATION include
)

就完成了本地安装.

现在运行cmakecmake-gui来配置项目并构建.
然后在命令行中运行cmakeinstall选项来执行安装步骤(3.15引入).

多配置工具,记得用--config来指定配置.如果用IDE,直接构建INSTALL目标即可.这一步会安装适合的头文件,库和可执行文件:

camke --install .

CMakeCMAKE_INSTALL_PREFIX变量确定安装文件的根目录.如果使用cmake --install命令,可用--prefix参数覆盖安装前缀:

cmake --install . --prefix "/home/myuser/installdir"

浏览安装目录,然后验证是否可运行安装的Tutorial.

支持测试

接着测试应用,在顶级CMakeLists.txt尾,可打开测试功能,然后加一些基本测试来验证是否正确安装.

enable_testing()
//是否运行`应用`
add_test(NAME Runs COMMAND Tutorial 25)
//使用消息是否工作?
add_test(NAME Usage COMMAND Tutorial)
set_tests_properties(UsagePROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
)
//定义简化加测试的函数
function(do_test target arg result)add_test(NAME Comp${arg} COMMAND ${target} ${arg})set_tests_properties(Comp${arg}PROPERTIES PASS_REGULAR_EXPRESSION ${result}
)
endfunction(do_test)//测试
do_test(Tutorial 4 "4 is 2")
do_test(Tutorial 9 "9 is 3")
do_test(Tutorial 5 "5 is 2.236")
do_test(Tutorial 7 "7 is 2.645")
do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is [-nan|nan|0]")
do_test(Tutorial 0.0001 "0.0001 is 0.01")

多配置生成器,要用-C来指定配置类型.

ctest -C Debug -VV
ctest -C Release -VV

或也可在IDE中构建RUN_TESTS目标.

步5:增加系统自检

现在想在项目中增加一些目标平台可能没有依赖代码.如,要加入代码依赖目标平台是否有logexp函数.

如果平台logexp,则就在mysqrt函数里使用.首先在顶层CMakeLists.txt里用CheckSymbolExists测试是否有这些函数?

一些平台,如果没有logexp,就需要连接到m库.

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里使用了:

//平台是否提供`exp`和`log`功能?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

如果在系统上可用logexp,则在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<< " 用log和exp" << std::endl;
#elsedouble result = x;

还要修改mysqrt.cxx来包含cmath:

#include <cmath>

运行cmakecmake-gui来配置项目,然后构建并执行Tutorial.

会注意到没用logexp,即使认为它们应该是可用的.很容易发现,在mysqrt.cxx中忘记包含TutorialConfig.h了.

也需要更新MathFunctions/CMakeLists.txt,这样mysqrt.cxx才可定位文件:

target_include_directories(MathFunctionsINTERFACE${CMAKE_CURRENT_SOURCE_DIR}PRIVATE${CMAKE_BINARY_DIR}
)

更新后,继续构建项目,然后运行Tutorial.如果仍没有使用logexp,打开构建目录下的生成的Tutorial.h文件,可能他们在当前系统下不可用的.

那个函数目前结果更好呢,sqrt还是mysqrt?

指定编译定义

除了在TutorialConfig.h中存储HAVE_LOGHAVE_EXP外,还有更好的地方么?试试用target_compile_definitions().

首先在TutorialConfig.h中移除定义,不再需要从mysqrt.cxx中包含TutorialConfig.h或在MathFunctions/CMakeLists.txt中额外包含它了.
接着可把HAVE_LOGHAVR_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()//添加编译定义
if(HAVE_LOG AND HAVE_EXP)target_compile_definitions(MathFunctionsPRIVATE "HAVE_LOG" "HAVE_EXP")
endif()

调整更新后,重构项目,再运行Tutorial并确认结果.

步6:添加自定义命令和生成文件

现在,决定不想再用平台的logexp函数,并想生成一些会在mysqrt函数里使用到的预计算值表.

这里,创建该表并作为构建的一步,然后编译到应用中.

首先,移除MathFunctions/CMakeLists.txt中的检查logexp.然后移除mysqrt.cxx检查对HAVE_LOGHAVR_EXP.同时,也可移除#include <cmath>.

MathFunctions子目录下,有个MakeTable.cxx新文件来生成表格.

浏览该文件,可发现,表格C++代码生成的,且通过参数传入输出文件名.

下一步是在MathFunctions/CMakeLists.txt中添加合适命令来构建MakeTable可执行文件,然后作为构建流程的一部分来运行.

需要一些命令来完成这一步.
首先,在MathFunctions/CMakeLists.txt的开头,添加MakeTable可执行文件目标.

add_executable(MakeTable MakeTable.cxx)

然后添加一项定义命令指定如何运行MakeTable创建表格.

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.hCOMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.hDEPENDS MakeTable
)

接着要让CMake知道mysqrt.cxx依赖创建的Table.h.把生成Table.h添加到MathFunctions库的源列表.

add_library(MathFunctionsmysqrt.cxx${CMAKE_CURRENT_BINARY_DIR}/Table.h
)

现在使用生成表,首先,修改mysqrt.cxx来包含Table.h,然后重写mysqrt函数以使用这张表:

double mysqrt(double x)
{if (x <= 0) {return 0;}//使用该表帮助查找初值double result = x;if (x >= 1 && x < 10) {std::cout << "用表" << std::endl;result = sqrtTable[static_cast(x)];}//十次迭代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 << "计算" << x << "为" << result << std::endl;}return result;
}

运行cmakecmake-gui来配置项目并构建.
构建项目时,首先构建的是MakeTable,然后会运行MakeTable并创建Table.h.最后编译包含了Table.hmysqrt.cxx来创建MathFunctions库.

运行Tutorial可执行文件,然后验证使用了表格.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/660700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务网格(Service Mesh)流行工具

在这篇博客中&#xff0c;我们将介绍微服务的最佳服务网格工具列表&#xff0c;这些工具提供安全性、金丝雀部署、遥测、负载均衡等。 用于部署和操作微服务的服务网格工具的数量不断增加。在这篇文章中&#xff0c;我们将探讨您应该用来构建自己的服务网格架构的顶级服务网格…

【Eclipse平台】2 Eclipse Workbench工作台介绍

Eclipse Workbench工作台介绍 本文介绍Eclipse工作台Workbench。 当工作台启动时&#xff0c;首先看到的是一个对话框&#xff0c;该对话框允许我们选择工作区的位置。工作区是存储工作的目录。现在&#xff0c;只需单击“确定”即可选择默认位置。 选择工作区位置后&#x…

如何访问 Oracle OKE 集群

OKE是Oracle Cloud提供的托管Kubernetes服务&#xff0c;为用户提供强大而灵活的容器编排平台。在本文中&#xff0c;我们将详细介绍如何有效地与OKE集群进行交互&#xff0c;包括访问集群的不同方式、管理访问权限以及执行常见操作的步骤。 1 安装oci命令 1.1 在Oracle Linux…

【gRPC】protoc文件转py文件

以下基于Win系统下Python的venv虚拟环境演示 《Python3笔记之venv虚拟环境》《Python笔记之pip国内镜像修改方法》 在桌面创建个test目录作为项目目录&#xff0c;初始化venv环境后&#xff0c;安装基础依赖&#xff1a; pip install grpcio grpcio-reflection grpcio-tools p…

证券开户怎么联系专属客户经理?新手必看!

证券开户联系专属客户经理的方式有很多&#xff0c;可以通过手机网上找客户经理&#xff0c;现在这种方式是最多的&#xff0c;比如咱们网站都是各大券商专业的客户经理&#xff0c;在线联系就可以帮您安排。您自己也可以挑选自己觉得好的券商和客户经理&#xff0c;然后再沟通…

Backtrader 文档学习- Broker - Trade

Backtrader 文档学习- Broker - Trade 1. 概述 交易的定义&#xff1a; 通过操作持仓从0变为大小为X时&#xff08;可能为正/负&#xff0c;对于多头/空头头寸&#xff09;&#xff0c;则交易处于开放状态。当持仓从X变为0时&#xff0c;交易关闭。 以下两个操作&#xff1a…

使用Server-Sent Events实现后端主动向前端进行通信

目录 概述 使用 Server-Sent Events (SSE) 示例 1.创建SpringBoot项目添加web依赖&#xff0c;并编写以下代码 2.创建Vue项目并在项目的.vue文件中编写以下代码 效果说明 使用触发的方式向前端传递数据 总结 概述 在典型的前后端分离架构中&#xff0c;前端通过发起 H…

静态HTML引入vue封装组件

在对历史原生html代码使用vue重构项目时&#xff0c;可以利用vue相关组件进行项目优化、实现统一管理&#xff0c;本文结束htmlvue的构建方式&#xff0c;欢迎大家阅读交流。 1、 下载vue.js 可自行到官网下载所需版本或者使用cdn资源 2、封装通用组件 2.1 封装通用实例化m…

MIMIC-IV官方视图解析 - cardiac_marker心脏标记表

今天在学习官方衍生表mimiciv_derived.cardiac_marker心脏标记表时候发现了一些问题&#xff1a; 该表中troponin_t &#xff08;肌钙蛋白t&#xff09;的值结果都是空值null 或者 ___ &#xff08;由于去标识化&#xff09;&#xff0c; 这明显是不合理的 小编查看了该表的官…

MySQL-运维篇-日志

一、错误日志 二、二进制日志 1、介绍 2、日志格式 3、日志查看 4、日志删除 三、查询日志 四、慢查询日志

汽车软件开发模式的5个特点

汽车软件开发属于较为复杂的系统工程&#xff0c;经常让来自不同知识背景的工程师在观点交锋时出现分歧。在解决复杂性和对齐讨论基准时&#xff0c;可以通过勾勒出讨论对象最关键的几个特征来树立典型概念。本文旨在通过5个典型特点的抽取&#xff0c;来勾勒出汽车软件开发模式…

python实现贪吃蛇小游戏(附源码)

文章目录 导入所需的模块坐标主游戏循环模块得分 贪吃蛇小游戏&#xff0c;那个曾经陪伴着00后和90后度过无数欢笑时光的熟悉身影&#xff0c;仿佛是一把打开时光之门的钥匙。它不仅是游戏世界的经典之一&#xff0c;更是我们童年岁月中不可或缺的一部分&#xff0c;一个承载回…

Spring如何进行参数校验

在Java开发中&#xff0c;对输入参数进行校验是一个非常重要的环节&#xff0c;它可以帮助我们避免非法数据对程序造成的影响。Spring框架提供了多种方式进行参数校验&#xff0c;本文将详细介绍如何在Spring中进行参数校验。 一、使用Spring的Validated和Valid注解 Spring提供…

新媒体与传媒行业数据分析实践:从网络爬虫到文本挖掘的综合应用,以“中国文化“为主题

大家好&#xff0c;我是八块腹肌的小胖&#xff0c; 下面将围绕微博“中国文化”以数据分析、数据处理、建模及可视化等操作 目录 1、数据获取 2、数据处理 3、词频统计及词云展示 4、文本聚类分析 5、文本情感倾向性分析 6、情感倾向演化分析 7、总结 1、数据获取 本…

征集各位的意见

1.B站 下一个月我打算在B站开始上传视频教程了&#xff0c;关注我的有一部分是看我TMS320F28377D的&#xff0c;有一部分是看我LPC804M101的&#xff0c;我这里问一下大家想先看哪个教程&#xff1f;好多盆友看我文章里都描述的不是很清楚&#xff0c;可能我上传B站&#xff0…

SwiftUI 动画入门之一:路径动画(Path Animations)

概览 在 SwiftUI 的开发中,我们往往需要使用千姿百态的动画把我们的界面元素妆点的更加鲜活灵动。 如上图所示,我们使用路径动画使折线图更加生动了!这是怎么做到的呢? 在本篇博文中,您将学到以下内容: 概览1. 路径与形状(Path and Shape)2. 路径动画的原理3. 让路径…

Zookeeper服务注册与发现实战

目录 设计思路 Zookeeper注册中心的优缺点 SpringCloudZookeeper实现微服务注册中心 第一步&#xff1a;在父pom文件中指定Spring Cloud版本 第二步&#xff1a;微服务pom文件中引入Spring Cloud Zookeeper注册中心依赖 第三步&#xff1a; 微服务配置文件application.y…

页面切换导致echarts不加载的问题

1. 问题描述 在A页面写了echarts,初始化dom元素加载,显示正常.当切换到B页,再切换回A页面时,echarts加载不出来. f12召唤出来看看报错,没有问题,但是有这样的警告 渲染echarts的dom元素上多了一个" echarts_instance "的属性,这是用来表示唯一性的. 2. 问题解决 …

杂题——试题-算法训练-P0604-runaround数

分析&#xff1a; 题目有三个关键点&#xff1a; 一&#xff1a;结束时&#xff0c;回到起始位置&#xff08;比较结束时和起始时的下标位置是否相同&#xff09;二&#xff1a;该整数的所有数字都必须遍历一遍&#xff0c;且只能遍历一遍&#xff08;把遍历过的数字做个标记&a…

记录下Flybirds移动端ui自动化框架的搭建

一、参考文档 1.官方文档&#xff1a;携程机票跨端跨框架 BDD UI 自动化测试方案Flybirds — flybirds v0.1.5 文档 2.Flybirds运行环境&#xff1a;Flybirds运行环境 - 简书 3.Windows系统连接IOS安装tidevice&#xff1a;iOS自动化之tidevice-CSDN博客 二、Windows系统演…