CMake教程(二):创建并使用库

CMake教程(二):创建并使用库

前言:一个大型 C++ 项目中经常需要使用到各种第三方库,本节主要介绍如何使用 cmake 生成并使用我们自己的库。所用到的资料是 CMake 官网 3.30.3 版的 Step2 目录下的文件。

本节所用材料的文件目录结构如下:
在这里插入图片描述

1. 创建库

通常,第三方库会放到一个子文件夹当中。为了使顶层 CMakeLists.txt 文件能够搜索到我们编写的第三方库,需要在顶层 CMakeLists.txt 文件中使用 add_subdirectories() 指令。此外,为了生成我们自己的库,需要在第三方库所在子目录 MathFunctions 下的 CMakeLists.txt 文件中使用 add_library() 指令。

下面介绍如何生成自己的库,然后在需要生成的可执行文件中使用我们自己创建的库。

  1. MathFunctions/CMakeLists.txt 文件添加如下指令:
add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)

add_libraryMathFunctions 是库名称,MathFunctions.cxxmysqrt.cxx
生成这个库时所依赖的源代码文件。

  1. 修改 Step2 目录下的 CMakeLists.txt 文件,添加以下两条指令:
# 把第三方库添加到项目的搜索范围中
add_subdirectories(MathFunctions)
# 生成Tutorial 可执行文件时,需要依赖库 MathFunctions
target_link_libraries(Tutorial PUBLIC MathFunctions)
# 因为我们使用了自己编写的库,所以需要确保可以找得到库相关的头文件
target_include_directories(Tutorial PUBLIC
                          "${PROJECT_BINARY_DIR}"
                          "${PROJECT_SOURCE_DIR}/MathFunctions"
                          )

{PROJECT_SOURCE_DIR}是指顶层 CMake 配置文件所在的目录。
3. 修改 tutorial.cxx 文件的内容:

#include "MathFunctions.h"

// 调用自己编写的sqrt函数
const double outputValue = mathfunctions::sqrt(inputValue);

后面就是创建一个 build 目录,然后使用指令 cmake ..make 命令。
在这里插入图片描述

2. 增加选项

在大型项目当中,会用到许多第三方库。但有时我们需要在编译源代码时,有选择地链接第三方库。例如,我们的项目用到了 Sqlite3MySQL 数据库,通常在编译时只需要指定一个即可。CMake 中的 option 指令让我们使用编译选项来配置 CMake 的构建过程。

接下来,我们通过设置 USE_MYMATH 变量来控制 cmake 在构建项目时是否使用我们自己编写的数学库。

下面介绍详细的步骤。

修改 MathFunctions/CMakeLists.txt 文件,按以下步骤修改相应的文件内容:

  1. 使用 option 指令添加编译选项开关。
    option 指令用于定义一个可选的开关,使用户可以在 CMake 配置时(运行cmake命令时指定-D<VARIABLE>=<ON|OFF>选项)设置这个开关的值为 ONOFF
# 设置 USE_MYMATH 变量的默认值为ON。字符串是对这个变量含义的描述
option(USE_MYMATH "Use tutorial provided math implementation" ON)

下面我们使用 if() 语句检查 USE_MYMATH 的值。在 if() 语句块中使用 target_compile_definitions 指令向指定的目标(如可执行文件、库等)添加编译定义(Compiler Definitions)。

  1. target_compile_definitions
if (USE_MYMATH)
  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
endif()
  1. 接下来,我们需要修改 MathFunctions.cxx 文件中的内容:
#ifdef USE_MYMATH
  return detail::mysqrt(x);
#else
  return std::sqrt(x);
#endif
  1. 下面,如果宏定义了 USE_MYMATH,那么我们需要包含 mysqrt.h 文件:
#ifdef USE_MYMATH
#include "mysqrt.h"
#endif
  1. 然后,我们需要直接包含 cmath 头文件:
#include <cmath>

但是现在有一个问题,如果USE_MYMATH的值是 OFF ,尽管 mysqrt.h 未被包含,但仍然需要编译,这样会拖慢编译速度。

有几种方式解决这个问题,一种是使用 target_sources()USE_MYMATH语句块内部添加mysqrt.cxx。另一种方式是在 USE_MYMATH 语句块内创建一个负责编译 mysqrt.cxx的额外库,就是把是否编译 mysqrt.cxx 设置成依赖于 USE_MYMATH。下面我们使用第二种方式。
修改 MathFunctions/CMakeLists.txt 文件:

if(USE_MYMATH)
add_library(SqrtLibrary STATIC
              mysqrt.cxx
              )

  # TODO 6: Link SqrtLibrary to tutorial_compiler_flags
  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()

本节放上按照以上步骤填充完整代码的源文件。

各位道友,码字不易,如有收获,记得一键三连啊。

  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值