CMake 教程(Step 2): 添加库

本文指导如何在VSCode中使用CMake构建一个可选的数学库MathFunctions,包含mysqrt函数。通过CMake选项管理库的启用与编译,演示了如何在程序中条件调用。

注:

现在我们将向我们的项目添加一个库。这个库将包含我们自己的计算一个数的平方根的实现。可执行程序可以使用这个库,而不是编译器提供的标准平方根函数。

在本教程中,我们将把库放到一个名为MathFunctions的子目录中。该目录已经包含一个头文件MathFunctions.h和一个源文件mysqrt.cxx。源文件有一个名为mysqrt的函数,它提供了类似于编译器的sqrt函数的功能。

  • 在上一节的工程目录下, 创建名为MathFunctions的文件夹
  • 在文件夹MathFunctions中新建名为MathFunctions.h的头文件, 文件内容如下:
#ifndef _MATH_FUNCTIONS_H_
#define _MATH_FUNCTIONS_H_
double mysqrt(double x);
#endif
  • 在文件夹MathFunctions中新建名为mysqrt.cxx的源文件, 文件内容如下:
#include <iostream>
#include "MathFunctions.h"

// a hack square root calculation using simple operations
double mysqrt(double x)
{
  if (x <= 0) {
    return 0;
  }

  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;
  }
  return result;
}
  • 在文件夹MathFunctions中新建CMakeLists.txt文件, 文件内容如下:
add_library(MathFunctions mysqrt.cxx)
  • 为了使用这个新库,我们将在工程目录下的CMakeLists.txt文件中添加一个add_subdirectory()调用,以便构建这个库。我们将新库添加到可执行文件中,并将MathFunctions添加到包含目录中,这样就可以找到mysqrt.h头文件。工程目录下的CMakeLists.txt文件的最后几行现在应该看起来像
# add the MathFunctions library
add_subdirectory(MathFunctions)

# add the executable
add_executable(Tutorial tutorial.cxx)

target_link_libraries(Tutorial PUBLIC MathFunctions)

# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
                          "${PROJECT_BINARY_DIR}"
                          "${PROJECT_SOURCE_DIR}/MathFunctions"
                          )
  • tutorial.cxx中包含MathFunctions.h, 并将sqrt()函数替换为mysqrt()函数
...
// 包含头文件
#include <MathFunctions.h>
...
int main(int argc, char* argv[])
{
  ...
  // 将`sqrt()`替换为`mysqrt()`
  const double outputValue = mysqrt(inputValue);
  ...
}
  • 点击状态栏中的build按钮,重新构建.
  • 在终端中输入.\build\tutorial.exe 100, 运行结果如下所示.
    在这里插入图片描述

为程序添加选项

现在让我们将MathFunctions库设为可选的。通过设置一个USE_MYMATH的开关, 让CMake决定使用MathFunctions中的mysqrt()或是cmath中的sqrt(). 对于本教程来说,确实没有必要这样做,但对于大型项目来说,这种情况很常见。

  • 在顶级CMakeLists.txt文件中添加一个选项。
option(USE_MYMATH "Use tutorial provided math implementation" ON)

# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
  • 这个选项将在cmake-guicmake中显示,默认值为ON,用户可以更改。这个设置将被存储在缓存中,这样用户就不需要每次在构建目录上运行CMake时都要设置这个值。下面我将介绍使用vscode修改该选项的方法

  • 下一个修改是让MathFunctions库的构建和链接成为有条件的。为此,我们将创建一个if语句来检查选项的值。在if块中,将上面的add_subdirectory()命令和一些额外的列表命令放在一起,以存储链接到库所需的信息,并将子目录添加为教程目标中的包含目录。顶层CMakeLists.txt文件修改后如下所示:

...
if(USE_MYMATH)
  add_subdirectory(MathFunctions)
  list(APPEND EXTRA_LIBS MathFunctions)
  list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()

# add the executable
add_executable(Tutorial tutorial.cxx)

target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})

# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
                           "${PROJECT_BINARY_DIR}"
                           ${EXTRA_INCLUDES}
                           )
...

注意,使用变量EXTRA_LIBS收集任何可选库,以便稍后链接到可执行文件中。变量EXTRA_INCLUDES类似地用于可选头文件。在处理许多可选组件时,这是一种经典的方法,我们将在下一步讨论现代的方法。

  • 对源代码tutorial.cxx做如下修改:
...
#ifdef USE_MYMATH
#include "MathFunctions.h"
#else
#include <cmath>
#endif
...
int main(int argc, char* argv[])
{
  ...
#ifdef USE_MYMATH
  const double outputValue = mysqrt(inputValue);
#else
  const double outputValue = sqrt(inputValue);
#endif
...
}
  • 由于源代码现在需要USE_MYMATH,我们可以将它添加到TutorialConfig.h.in,如下所示:
#cmakedefine USE_MYMATH
  • 使用vscode可以修改该选项是否启用.
    • 打开命令托盘(Ctrl + Shift + P), 输入"cme", 选择CMake: Edit CMake Cache(UI)
    • 在搜索框中输入"use_", 点击"USE_MYMATH"后的复选框, 可在"ON"|"OFF"间切换.

USE_MYMATH设置为ON时, 调用mysqrt()的代码行变为启用状态, 相应的, 调用sqrt()的代码行变为禁用状态.反之亦然.
分别将USE_MYMATH设置为ONOFF, 构建并运行, 查看运行结果.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

falwat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值