【CMake】教程:第2步 添加库

2023-11-19

【CMake】教程:第2步 添加库

【问题】

当写的程序由多个模块组成,如何组织这些代码,以及如何利用模块代码生成的库呢?

【解答思路】

  1. 编写模块代码
  2. 将模块代码生成库
  3. 编写调用程序
  4. 编译链接模块库

以求一个数的平方根为例。

编写模块代码

MathFunctions.h
#ifndef __MATHFUNCTIONS_H__
#define __MATHFUNCTIONS_H__

// 求一个数的平方根
double mysqrt(double x);

#endif /* __MATHFUNCTIONS_H__ */

每个头文件需要加上 #ifndef ,以免重复添加头文件,造成重复声明。

mysqrt.cpp
#include <iostream>
#include "MathFunctions.h"

double mysqrt(double x)
{
    if (x <= 0)
    {
        return 0;
    }

    double result = 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 << "Computing sqrt of " << x << " to be " << result << std::endl;
    }

    return result;
}

生成库

一个模块生成库,用 add_library 即可。

CMakeLists.txt
# 如果模块引用其他模块,应链接相应库
add_library(MathFunctions mysqrt.cpp)

调用程序

调用程序可能用c++自带的函数库也可以用模块库,可以用选择编译的方式进行调用;

tutorial.cpp
// 一个简单的计算平方根的程序
#include <cmath>
//#include <cstdlib> // when use c++11
#include <iostream>
#include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h"

int main(int argc, char* argv[])
{
    // 打印版本号
    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
                << Tutorial_VERSION_MINOR << std::endl;

    if (argc < 2) {
        std::cout << "Usage: " << argv[0] << " number" << std::endl;
        return 1;
    }

    // 数据转换为 double
    // const double inputValue = atof(argv[1]);
    const double inputValue = std::stod(argv[1]);  // c++11

#ifdef USE_MYMATH
    const double outputValue = mysqrt(inputValue);
#else
    // 计算平方根
    const double outputValue = sqrt(inputValue);
#endif

    std::cout << "The square root of " << inputValue << " is " << outputValue
                << std::endl;
    return 0;

}

#ifdef USE_MYMATH 中的 USE_MYMATH 是在 CMakeLists.txt里定义的,然后通过 config 的方法将其配置到头文件 TutorialConfig.h中。

链接库

CMakeLists.txt

主CMakeLists.txt如下

cmake_minimum_required(VERSION 3.10)

# 设置项目名称
# project(Tutorial)
# 设置项目名称及版本号
project(Tutorial VERSION 1.1)

# 设置C++
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

option(USE_MYMATH "Use tutorial provided math implementation" ON)

# 通过配置文件将版本号配置到程序中,当然也可以通过git的编号或版本号自动配置进去
# 当然也可以通过配置文件将其他的CMake参数配置到程序中,
# 例如一些不常改变的参数可以通过宏配置进去
configure_file(TutorialConfig.h.in TutorialConfig.h)

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


# 添加执行程序
add_executable(Tutorial tutorial.cpp)

# 添加链接库
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})


# 添加头文件
target_include_directories(Tutorial PUBLIC 
                        "${PROJECT_BINARY_DIR}" 
                        ${EXTRA_INCS}
                        )

option 指令可以将某些变量设置成开关量,可以根据开关量进行编译。
如果 option 里设置为 ON,在例子中实际就是将 USE_MYMATH 设置为 True

add_subdirectory: 将包含子目录,进入子目录后会查找内部的 CMakeLists.txt 继续执行。

target_link_libraries: 添加链接库,除了自己编译的模块,也可以链接其他开源库等。

target_include_directories: 添加目标的链接目录。

TutorialConfig.h.in
// the configured options and settings for Tutorial

#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@

#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

#cmakedefine USE_MYMATH

如果 USE_MYMATH 在编译的时候指定为 ON,则 #cmakedefine USE_MYMATH配置后变成 #define USE_MYMATH

#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@@...@部分替换成 CMakeLists.txt里定义的值,如本例中为 1

【汇总】

## 目录结构如下
.
├── build
├── CMakeLists.txt
├── MathFunctions
│   ├── CMakeLists.txt
│   ├── MathFunctions.h
│   └── mysqrt.cpp
├── TutorialConfig.h.in
└── tutorial.cpp
mkdir build && cd build
cmake ..
make 
./Tutorial 100
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【CMake】教程:第2步 添加库 的相关文章

随机推荐

  • oracle tcp空包请求,再谈 TCP 的 CLOSE_WAIT

    背景 某日集群告警 hbase regionserver 因 fd 不足导致进程主动退出 简单排查后发现regionserver 到 datanode 的TCP 连接存在大量 CLOSE WAIT 单机总数有10万之多 众所周知 CLOSE
  • HTML表格

    目录 实例 表格 表格和边框属性 表格的表头 表格中的空单元格 更多实例 表格标签 一个完整的实例 本例涉及到的资源 eg background jpg eg cute gif 可以使用 HTML 创建表格 实例 表格 这个例子演示如何在
  • 一台电脑上安装两个Tomcat服务器

    在排查问题来源的时候 由于不想卸载之前下载的Tomcat 需要再安装一个Tomcat服务器 下载压缩版的Tomcat之后 第一个Tomcat配置不变 需要修改第二个Tomcat的配置 1 CATALINA HOME 8081 新的地址 2
  • flex:1可以撑满剩余空间

    flex 1 的妙用 首先 flex 是 flex grow flex shrink flex basis的缩写 当 flex 取值为一个非负数字 则该数字为 flex grow 值 flex shrink 取 1 flex basis 取
  • MySql中left join、right join、inner join实例分析,union与union all的区别,Mybatis中CDATA []的用法

    inner join select from user a inner join grade b on a gid b id 只返回两个表中联结字段相等的行 left join select from user a left join gr
  • bokeh python_Python Bokeh数据可视化教程

    bokeh python Bokeh is an interactive Python data visualization library which targets modern web browsers for presentatio
  • cad隐藏图层命令快捷键_教你学会天正CAD局部隐藏对象技巧

    天正局部隐藏命令 JBYC 即局部隐藏的拼音首字母 其命令全称为TMKHIDE 适用于所有天正软件 建筑 电气 给排水 暖通 天正建筑的工具界面中是有此菜单的 且默认快捷键4为局部隐藏 6为恢复可见 其他软件并未显示 需要通过命令输入使用
  • 基于conda的相关命令

    conda 查看python版本环境 打开Anaconda Prompt的命令输入框 查看自己的python版本 conda env list 激活相应的python版本 环境 conda avtivate python 3 9 若输入以下
  • 我在工作中是如何使用【Linux】的

    目录 前言 一 常用命令 二 文件和目录处理 三 用户与组管理命令 四 进程管理命令 五 网络管理命令 六 帮助命令 七 磁盘管理 前言 大家好 这是我首篇博客 内容是linux工作需用到的内容 在这里我给大家总结出来了 希望多支持支持 感
  • 【Hello mysql】 mysql的事务

    Mysql专栏 Mysql 本篇博客简介 介绍mysql的事务 mysql的事务 事务的概念 事务功能测试 事务的隔离级别 如何理解隔离性 粗浅理解 隔离级别 查看和设置隔离级别 四种隔离级别详解 读 未提交 读 提交 可重复读 串行化 一
  • 6月17日实验课之“H.264文件解析”

    文章目录 1 实验要求 2 实验结果 2 1 SPS 2 1 1 profile idc 2 1 2 level idc 2 1 3 seq parameter set id 2 1 4 log2 max frame num minus4
  • jmeter+接口测试练习+接口关联+Json提取

    1 测试用例设计 2 因为要执行多条用例 所以在Jmeter添加了http信息头管理器和http请求默认值 3 查询用户信息接口需要用到登录的token 但要先登录再把token拿出来传到查询的信息头里 会出现登录信息已过期的提示 考虑用j
  • 从0开始写Vue项目-Vue页面主体布局和登录、注册页面

    1 从0开始写Vue项目 环境和项目搭建 慕言要努力的博客 CSDN博客 2 从0开始写Vue项目 Vue2集成Element ui和后台主体框架搭建 慕言要努力的博客 CSDN博客 一 主体布局 关于主体布局 我们刚开始肯定是做的死数据的
  • 考研数二第三讲 极限存在准则和两个重要极限和极限运算准则

    根据前面介绍的内容 具体推理数列以及函数的极限推理过程 在实际应用中极限的两大准则使用还是比较广泛的 大家需要多多关注 极限存在准则和两个重要极限 准则 I 夹逼准则 如果数列 xn yn zn 满足下列条件 证明 此函数分母的极限为 0
  • 稿费一般多少钱一千字_编写教材的稿费一般是多少

    我们知道编写教材是会受到一定的稿酬的 除了编写教材 还有图书 报纸 个人公开发表等等 公费出书都有可能获取一定的稿酬 那么稿酬是如何计算的呢 编写教材的稿费一般是多少 以下是根据 出版文字作品报酬规定 介绍了基本稿酬的标准 供大家参考 19
  • VUE项目中的全局格式化时间过滤器

    自定义格式化时间 一 问题 这是一个后台管理系统中的商品列表页 其中的时间这一项在调用接口后会发现是以毫秒来计算的 这样当然是不行的啦 要换算成我们日常使用的2020 04 07 17 13 这样的时间格式 二 解决办法 1 打开项目中的m
  • html5 比例尺,高德地图API之缩放比例尺控件+3D转换

    缩放比例尺控件 首先引入控件 amap scale 然后使用 map addcontrol 添加控件map margin 0 padding 0 list style none container width 100 height 100
  • Flutter 画板实现

    import package flutter material dart class DrawingBoard extends StatefulWidget override DrawingBoardState createState gt
  • Unity5.4.1与NGUI出现的问题Ignoring menu item NGUI because it is in no submenu!

    原文 http www tasharen com forum index php topic 14856 0 Hey Arenmook after upgrading to Unity 5 4 1 from 5 3 6p1 and upgr
  • 【CMake】教程:第2步 添加库

    CMake 教程 第2步 添加库 问题 当写的程序由多个模块组成 如何组织这些代码 以及如何利用模块代码生成的库呢 解答思路 编写模块代码 将模块代码生成库 编写调用程序 编译链接模块库 以求一个数的平方根为例 编写模块代码 MathFun