CMake教程Step2(添加库)

2023-05-16

CMake官方文档

参考官方cmake3.24教程翻译
https://cmake.org/cmake/help/v3.24/guide/tutorial/index.html
https://gitlab.kitware.com/cmake/cmake/-/tree/master/Help/guide/tutorial
step2
https://cmake.org/cmake/help/v3.24/guide/tutorial/Adding%20a%20Library.html
我的仓库 :
https://github.com/FRBoiling/cmake-tutorial.git

添加一个库

现在,我们将向项目添加一个库。这个库将包含我们自己的计算数字平方根的实现。然后,可执行文件就可以使用这个库,而不是编译器提供的标准平方根函数。
在本教程中,我们将把库放入名为MathFunctions的子目录中。这个目录包含一个头文件MathFunctions.h和一个源文件mysqrt.cxx。源文件有一个名为mysqrt的函数,它提供了与编译器的sqrt函数类似的功能。
将以下一行CMakeLists.txt文件添加到MathFunctions目录:

初始化库

进入项目文件夹Step2,创建子目录MathFunctions,这个目录包含一个头文件MathFunctions.h、一个源文件mysqrt.cxx和一个CMakeLists.txt文件

mkdir Step2 Step2_build
cd Step2
mkdir MathFunctions
cd MathFunctions
touch MathFunctions.h mysqrt.cxx CMakeLists.txt

MathFunctions.h 内容如下:

double mysqrt(double x);

mysqrt.cxx 中内容如下:

#include <iostream>

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

CMakeLists.txt 内容如下

add_library(MathFunctions mysqrt.cxx)

项目引用库

项目结构如下:
image.png
为了使用新库,我们将在顶级目录(Step2)CMakeLists.txt文件中添加一个add_subdirectory()调用,以便构建库。我们将新的库添加到可执行文件中,并添加MathFunctions作为include目录,以便可以找到MathFunctions.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"
                          )

1.1、构建可选选项

现在让我们将MathFunctions库设置为可选的。对于本教程来说,确实不需要这样做,但对于更大的项目来说,这是常见的情况。第一步是在顶级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(tutorial_config.h.in tutorial_config.h)

该选项将显示在cmake-gui和ccmake中,其默认值为ON,用户可以更改该值。该设置将存储在缓存中,这样用户就不需要每次在构建目录上运行CMake时都设置该值。

1.2、条件构建和链接

下一个更改是将构建和链接MathFunctions库设置为条件。为此,我们将创建一个if语句来检查该选项的值。在if块中,放入上面的add_subdirectory()命令和一些附加的列表命令,以存储链接到库所需的信息,并将子目录作为include目录添加到教程目标中。顶级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中包括MathFunctions.h头文件:

#ifdef USE_MYMATH
  include "MathFunctions.h"
#endif

然后,在同一个文件中,使用USE_MYMATH控制使用哪个平方根函数:

#ifdef USE_MYMATH
  const double outputValue = mysqrt(inputValue);
#else
  const double outputValue = sqrt(inputValue);
#endif

因为源代码现在需要USE_MYMATH,我们可以用下面这行代码将它添加到TutorialConfig.h.in:

#cmakedefine USE_MYMATH

测试和练习

最终 Step2/CMakeLists.txt内容如下

cmake_minimum_required(VERSION 3.10)

# set the project name and version
project(Tutorial VERSION 1.0)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# should we use our own math functions
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)

# add the MathFunctions library
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}
                           )

tutorial.cxx 内容如下

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include "tutorial_config.h"
#ifdef USE_MYMATH
#include "math_functions.h"
#endif

int main(int argc, char *argv[])
{
    // if(argc<2){
    //     fprintf(stdout, "Uage: %s number\n", argv[0]);
    //     return 1;
    // }
    if (argc < 2)
    {
        // report version
        std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
                  << Tutorial_VERSION_MINOR << std::endl;
        std::cout << "Usage: " << argv[0] << " number" << std::endl;
        return 1;
    }
    // double inputValue = atof(argv[1]);
    const double inputValue = std::stod(argv[1]);
#ifdef USE_MYMATH
    const double outputValue = mysqrt(inputValue);
#else
    const double outputValue = sqrt(inputValue);
#endif
    fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue);
    return 0;
}

练习

1、Why is it important that we configure tutorial_config.h.in after the option for USE_MYMATH?
2、What would happen if we inverted the two?
运行cmake可执行文件或cmake-gui来配置项目,然后使用您选择的构建工具构建它。然后运行构建的Tutorial可执行文件。

测试

现在让我们更新USE_MYMATH的值。
最简单的方法是在终端中使用cmake-gui或ccmake。
你也可以通过从命令行修改这个选项,如下

cmake …/Step2 -DUSE_MYMATH=ON

image.png

cmake …/Step2 -DUSE_MYMATH=OFF

image.png
重新构建并再次运行本教程。

哪个函数给出更好的结果,sqrt还是mysqrt?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake教程Step2(添加库) 的相关文章

随机推荐

  • 接口测试之Postman使用全指南(原来使用 Postman测试API接口如此简单)

    Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件 Postman背景介绍 用户在开发或者调试网络程序或者是网页B S模式的程序的时候是需要一些方法来跟踪网页请求的 xff0c 用户可以使用一些网络的监视工具比如
  • 常用Qt类的继承图

  • extern “C”{}的含义及解决的问题

    C 与C 43 43 程序连接问题 它们之间的连接问题主要是因为c c 43 43 编绎器对函数名译码的方式不能所引起的 xff0c 考虑下面两个函数 c int strlen char string c 43 43 int strlen
  • ROS2学习笔记(四)-- 用方向键控制小车行走

    简介 xff1a 在上一节的内容中 xff0c 我们通过ROS2的话题发布功能将小车实时视频信息发布了出来 xff0c 同时使用GUI工具进行查看 xff0c 在这一节内容中 xff0c 我们学习一下如何订阅话题并处理话题消息 xff0c
  • C++实现简单的HTTP客户端(阻塞方式)

    项目中用到的HTTP请求功能 xff0c 自己简单写了个客户端 xff0c 实现了POST方式 xff0c GET方式实现应该也很简单 xff08 空接口已经写好 xff1a 61 xff09 应该支持多线程 xff08 这个很重要 xff
  • WSAWaitForMultipleEvents()

    简述 xff1a 只要指定事件对象中的一个或全部处于有信号状态 xff0c 或者超时间隔到 xff0c 则返回 include lt winsock2 h gt DWORD WSAAPI WSAWaitForMultipleEvents D
  • WSAEnumNetworkEvents()

    WSAEnumNetworkEvents 简述 xff1a 检测所指定的套接口上网络事件的发生 include lt winsock2 h gt int WSAAPI WSAEnumNetworkEvents SOCKET s WSAEVE
  • WSASend()

    WSASend 简述 xff1a 在一个已连接的套接口上发送数据 include lt winsock2 h gt int WSAAPI WSASend SOCKET s LPWSABUF lpBuffers DWORD dwBufferC
  • 临界区

    本文假定您熟悉 Win32 C 43 43 和多线程处理 下载本文的代码 xff1a CriticalSections exe 415KB 摘要 临界区是一种防止多个线程同时执行一个特定代码节的机制 xff0c 这一主题并没有引起太多关注
  • glBegin()用法小结

    glBegin 用法小结 1 在glBegin 和glEnd 之间可调用的函数 函数 函数意义 glVertex 设置顶点坐标 glColor 设置当前颜色 glIndex 设置当前颜色表 glNormal 设置法向坐标 glEvalCoo
  • C++中的显式构造函数

    以两个C 43 43 的小例子来说明怎样通过使用显式构造函数来防止隐式转换 有如下一个简单的复数类 xff1a class ClxComplex public ClxComplex double dReal 61 0 0 double dI
  • 类中的static关键字

    面向对象的static关键字 xff08 类中的static关键字 xff09 1 静态数据成员 在类内数据成员的声明前加上关键字static xff0c 该数据成员就是类内的静态数据成员 先举一个静态数据成员的例子 可以看出 xff0c
  • VS2005 常用快捷键

    2007 04 10 15 32 VS2005 常用快捷键 仁者无敌 2006 08 02 20 20 16 Shift 43 Alt 43 Enter 切换全屏编辑 Ctrl 43 B T Ctrl 43 K K 切换书签开关 Ctrl
  • const

    面向对象是C 43 43 的重要特性 但是c 43 43 在c的基础上新增加的几点优化也是很耀眼的 就const直接可以取代c中的 define 以下几点很重要 学不好后果也也很严重 const 1 限定符声明变量只能被读 const in
  • ROS2学习笔记(五)-- ROS2命令行操作常用指令总结(一)

    简介 xff1a 在前面的章节中 xff0c 我们先简单学习了ROS2的话题发布和订阅 xff0c 两种操作都是通过python代码实现的 xff0c 而在实际应用过程中 xff0c 我们会经常用到命令行操作来辅助调试 xff0c 更进一步
  • Ubuntu16.04配置Carla第三方egg库

    背景 CARLA软件是英特尔公司主导的 xff0c 基于虚幻4游戏引擎 xff0c 用于自动驾驶仿真的一款开源仿真软件 xff0c 该软件可以模拟激光雷达 xff0c 摄像头等等自动驾驶中常用的传感器的行为以及获取传感器数据 xff0c 从
  • 串口通信校验方式(even,odd,space,mark)

    无校验 xff08 no parity xff09 奇校验 xff08 odd parity xff09 xff1a 如果字符数据位中 34 1 34 的数目是偶数 xff0c 校验位为 34 1 34 xff0c 如果 34 1 34 的
  • 更改Ubuntu默认python版本的两种方法

    更改Ubuntu默认python版本的两种方法 没找到原文地址 xff0c 作者写的很实用的方法 xff0c 赞一个 当你安装 Debian Linux 时 xff0c 安装过程有可能同时为你提供多个可用的 Python 版本 xff0c
  • Franka+Realsense D435i Ubuntu 20.04-easyHandeye 手眼标定

    使用Panda 43 realsense D435i 43 easyhandeye 43 ROS neotic 全流程记录 安装环节 安装ros安装libfranka安装moveit panda moveit config 安装 visp安
  • CMake教程Step2(添加库)

    CMake官方文档 参考官方cmake3 24教程翻译 https cmake org cmake help v3 24 guide tutorial index html https gitlab kitware com cmake cm