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

2-添加库

    本节将学习如何在项目中创建和使用库,还将看到如何使库的使用成为可选的。

    本节中使用的示例代码下载见step1-简单开始cmake实践-CSDN博客。

练习1 -创建一个库

    要在CMake中添加一个库,使用add_library()命令并指定哪些源文件应该组成该库。
    我们可以使用一个或多个子目录组织项目,而不是将所有源文件放在一个目录中。在本例中,我们将专门为库创建一个子目录。在这里,我们可以添加一个新的CMakeLists.txt文件和一个或多个源文件。在顶级的CMakeLists.txt文件中,我们将使用add_subdirectory()命令将子目录添加到构建中。
    创建库之后,使用target_include_directories()和target_link_libraries()将其连接到可执行目标。

目标

    添加并使用库。

开始

    在本练习中,我们将在项目中添加一个库,其中包含我们自己的用于计算数字平方根的实现。然后,可执行文件可以使用这个库,而不采用编译器提供的标准平方根函数。
    在本教程中,我们将把库放入名为MathFunctions的子目录中。这个目录已经包含了头文件MathFunctions.h和mysqrt.h。还提供了它们各自的源文件MathFunctions.cxx和mysqrt.cxx。我们不需要修改这些文件。mysqrt.cxx有一个名为mysqrt的函数,它提供了与编译器的SQRT函数类似的功能。MathFunctions.cxx包含一个函数SQRT,用于隐藏我们自己写的SQRT函数的实现细节。
     从在本文提供的代码实例文件夹下/Step2目录中,从TODO 1开始,完成TODO 6。
    首先,在MathFunctions子目录中填写一行CMakeLists.txt。
    接下来,编辑顶层的CMakeLists.txt。
    最后,使用tutorial.cxx中新创建的MathFunctions库。

操作

    在MathFunctions目录下的CMakeLists.txt文件中,我们使用add_library()创建了一个名为MathFunctions的库目标。库的源文件作为参数传递给add_library()。这看起来像下面这行:

// TODO 1: MathFunctions/CMakeLists.txt
add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)

    为了使用新库,我们将在顶级CMakeLists.txt文件中添加add_subdirectory()调用,以便库将被构建。

// TODO 2: CMakeLists.txt
add_subdirectory(MathFunctions)

    接下来,使用target_link_libraries()将新的库目标链接到可执行目标。

// TODO 3: CMakeLists.txttarget_link_libraries(Tutorial PUBLIC MathFunctions)

    最后,我们需要指定库的头文件位置。修改现有的target_include_directories()调用,将MathFunctions子目录添加为包含目录,这样就可以找到MathFunctions.h头文件。

// TODO 4: CMakeLists.txt
target_include_directories(Tutorial PUBLIC"${PROJECT_BINARY_DIR}""${PROJECT_SOURCE_DIR}/MathFunctions")

    现在让我们使用库。在tutorial.cxx中包含MathFunctions.h:

// TODO 5: tutorial.cxx#include "MathFunctions.h"

    最后,用包装函数mathfunctions::sqrt替换sqrt。

// TODO 6: tutorial.cxxconst double outputValue = mathfunctions::sqrt(inputValue);

编译和运行

mkdir Step2_build
cd Step2_build
cmake ../Step2
cmake --build .

    尝试使用编译好的项目,并确保它仍然产生准确的平方根值。

./Tutorial 4294967296
./Tutorial 10
./Tutorial

练习2 -添加选项

    现在让我们在MathFunctions库中添加一个选项,允许开发人员选择自定义的平方根实现或内置的标准实现。
    CMake可以使用option()命令执行此操作。这为用户提供了一个可以在配置cmake构建时更改的变量。

目标

    添加不使用MathFunctions函数的编译选项。

步骤

     首先使用MathFunctions/CMakeLists.txt中的option()命令创建一个变量USE_MYMATH。在同一个文件中,使用该选项将编译定义传递给MathFunctions库。
    然后,更新MathFunctions,基于USE_MYMATH重定向编译。
    最后,当USE_MYMATH打开时,通过在MathFunctions/CMakeLists.txt的USE_MYMATH块中使其成为自己的库。

操作

    第一步是在MathFunctions/CMakeLists.txt中添加一个选项,默认值为ON,可由用户更改。

// TODO 7: MathFunctions/CMakeLists.txt
option(USE_MYMATH "Use tutorial provided math implementation" ON)

    接下来,使用这个新选项使库与mysqrt函数的构建和链接成为有条件的选项。
    创建一个if()语句来检查USE_MYMATH的值。在if()块中,放入target_compile_definitions()命令和编译定义USE_MYMATH。

// TODO 8: MathFunctions/CMakeLists.txt
if (USE_MYMATH)target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
endif()

条件判断

  • if (USE_MYMATH)
    

    这里使用了 CMake 的 if 命令来判断变量 USE_MYMATH 是否为真(即非空或者非零)。如果 USE_MYMATH 被定义为 ONTRUE、非空字符串或者被设置为一个非零数值,条件判断将会成立。

  • 目标编译定义

  1. target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
    

    如果 USE_MYMATH 的条件成立,那么就会为目标 MathFunctions 添加一个编译定义。在这里,编译定义是 "USE_MYMATH"。这意味着在编译 MathFunctions 库或可执行文件时,会将 "USE_MYMATH" 添加到编译器的预处理器定义中。

  2. PRIVATE 关键字PRIVATE 关键字指定了这个编译定义的作用域。在 CMake 中,PRIVATE 表示这个定义只会影响到 MathFunctions 目标本身及其直接依赖的其他目标。这意味着其他使用 MathFunctions 的目标或库不会自动继承 "USE_MYMATH" 这个定义,除非它们也显式地声明。

    这段代码的作用是根据 USE_MYMATH 变量的值来决定是否为 MathFunctions 添加一个编译定义 "USE_MYMATH"。这样的做法通常用于根据不同的构建选项或条件,启用或禁用特定的功能或代码路径。

    当USE_MYMATH为ON时,编译定义USE_MYMATH将被设置。然后,我们可以使用这个编译定义来启用或禁用源代码的部分。
    接下来在MathFunctions.cxx文件中,我们让USE_MYMATH控制使用哪个平方根函数:

#ifdef USE_MYMATHreturn detail::mysqrt(x);
#elsereturn std::sqrt(x);
#endif

    接下来,如果定义了USE_MYMATH,我们需要包含mysqrt.h。

// TODO 10: MathFunctions/MathFunctions.cxx#ifdef USE_MYMATH
#  include "mysqrt.h"
#endif

    最后,在使用std::sqrt时,我们需要包含cmath。

// TODO 11 : MathFunctions/MathFunctions.cxx#include <cmath>

    此时,如果USE_MYMATH为OFF, mysqrt.cxx不会被使用,但它仍然会被编译,因为MathFunctions目标有mysqrt.cxx列在来源下面。
    有几种方法可以解决这个问题。第一个选项是使用target_sources()来添加mysqrt.cxx从USE_MYMATH块中取出。另一个选择是在USE_MYMATH块中创建一个额外的库,它负责编译mysqrt.cxx。在本教程中,我们将创建一个额外的库。
    首先,在USE_MYMATH中创建一个名为SqrtLibrary的库,其源代码为mysqrt.cxx。

// TODO 12 : MathFunctions/CMakeLists.txtadd_library(SqrtLibrary STATICmysqrt.cxx)# TODO 6: Link SqrtLibrary to tutorial_compiler_flagstarget_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()

    接下来,当启用USE_MYMATH时,我们将SqrtLibrary链接到MathFunctions。

// TODO 13 : MathFunctions/CMakeLists.txttarget_link_libraries(MathFunctions PRIVATE SqrtLibrary)

    最后,我们可以从MathFunctions库源列表中删除mysqrt.cxxcxx,因为它将在包含SqrtLibrary时被拉入。

// TODO 14 : MathFunctions/CMakeLists.txtadd_library(MathFunctions MathFunctions.cxx)

    通过这些更改,mysqrt函数现在对于正在构建和使用MathFunctions库的人来说完全是可选的。用户可以切换USE_MYMATH来操作编译中使用的库。

编译并运行

    由于我们已经在练习1中配置了编译目录,我们可以通过简单地调用以下命令进行编译:

cd ../Step2_build
cmake --build .

    现在让我们将USE_MYMATH的值更新为OFF。

cmake ../Step2 -DUSE_MYMATH=OFF

    现在,用下面的代码重新编译代码:

cmake --build .

    然后,再次运行可执行文件,以确保它在USE_MYMATH设置为OFF时仍然工作。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • nodejs md文件转html
  • 如何在 Microsoft Edge 上使用开发人员工具
  • Spring Boot Vue 毕设系统讲解 3
  • 高效利用iCloud:释放你的数字生活
  • Spring框架Mvc(2)
  • jmeter-beanshell学习5-beanshell加减乘除运算
  • 推荐一款Win11主题WPF UI框架
  • Mysql 高性能索引
  • AI推介-多模态视觉语言模型VLMs论文速览(arXiv方向):2024.07.01-2024.07.05
  • 使用pycuda + skcuda 遇到 OSError: CUDA runtime library not found 的解决方案
  • Python酷库之旅-第三方库Pandas(012)
  • Django QuerySet对象,exclude()方法
  • 【QT】QComboBox允许输入查询,且不区分大小写
  • Edge浏览器油猴插件的安装与使用
  • 【Proteus】按键的实现『⒉种』
  • DataBase in Android
  • echarts花样作死的坑
  • Laravel Telescope:优雅的应用调试工具
  • MySQL-事务管理(基础)
  • 创建一个Struts2项目maven 方式
  • 基于Android乐音识别(2)
  • 开源SQL-on-Hadoop系统一览
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 什么是Javascript函数节流?
  • 探索 JS 中的模块化
  • 温故知新之javascript面向对象
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • 函数计算新功能-----支持C#函数
  • 扩展资源服务器解决oauth2 性能瓶颈
  • # Apache SeaTunnel 究竟是什么?
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • $$$$GB2312-80区位编码表$$$$
  • (12)Hive调优——count distinct去重优化
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (C语言)逆序输出字符串
  • (poj1.3.2)1791(构造法模拟)
  • (待修改)PyG安装步骤
  • (二)windows配置JDK环境
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (附源码)计算机毕业设计大学生兼职系统
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (一)springboot2.7.6集成activit5.23.0之集成引擎
  • (转)http-server应用
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .NET C# 使用 iText 生成PDF
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .NET Standard 的管理策略
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .netcore 获取appsettings
  • .NET简谈设计模式之(单件模式)
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • ??Nginx实现会话保持_Nginx会话保持与Redis的结合_Nginx实现四层负载均衡