CMake多文件编译

news2024/11/16 3:38:50

之前学习ceres-solver中的3d相关的源码的时候,发现对于CMake多文件工程编译中对于CMakeLists.txt的编写和处理的理解运用还是比较模糊,这里整理梳理一下对于不同文件夹数量如何使用。

参考文章:

CMake使用详解二(多文件编译)_刘凯数据分析的博客-CSDN博客_cmake 多文件编译

1.同一文件夹下,多cpp文件

tree如下所示:

.
└── test1
    ├── add.cpp
    ├── add.hpp
    ├── CMakeLists.txt
    └── main.cpp

其中的源码为:

//add.h
#include "iostream"

using namespace std;

int add1(int a, int b);

//add.cpp
#include "add.hpp"

int add1(int i, int j)
{
    return i + j;
}

//main.cpp
#include "add.hpp"

int main()
{
    cout << add1(1, 10) << endl;
    return 0;
}

CMakeLists.txt如下所示:

cmake_minimum_required(VERSION 2.8)
project(add)

add_executable(add1 main.cpp add.cpp)

2.同一文件夹下,超多cpp文件

如果文件夹下有很多cpp文件5个以上,这样一个个打不方便,可以在CMakeLists.txt中输入命令:

aux_source_directory

aux_source_directory(<dir> <variable>)

1中使用aux_source_directory如下:

cmake_minimum_required(VERSION 2.8)
project(add)
aux_source_directory(. ALL_SRCS)
add_executable(add1 ${ALL_SRCS})

同样编译可以通过。

CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 2.8.12 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.


-- Configuring done
-- Generating done
-- Build files have been written to: /home/hhh/test-folder/cmake-test/test1/build
Consolidate compiler generated dependencies of target add1
[ 33%] Building CXX object CMakeFiles/add1.dir/main.cpp.o
[ 66%] Linking CXX executable add1
[100%] Built target add1

3.不同文件夹下

tree如下所示:

.
├── add
│   ├── add.cpp
│   ├── add.hpp
│   └── CMakeLists.txt
├── CMakeLists.txt
└── main.cpp

其中所有的源码如下:

//   add/add.hpp
#include <iostream>
using namespace std;

int add1(int i, int j);

//   add/add.cpp
#include "add.hpp"

int add1(int i, int j)
{
    return i + j;
}

//   main.cpp
#include "add/add.hpp"

int main()
{
    cout << add1(10, 1) << endl;
    return 0;
}

最外层的CMakeLists.txt文件:

cmake_minimum_required(VERSION 2.8)
project(add1)

aux_source_directory(. ALL_SRCS)
add_subdirectory(add)
add_executable(add1 ${ALL_SRCS})
target_link_libraries(add1 add2)

分析:

add_subdirectory(add)

是将指明本项目包含一个子目录 add,这样 add 目录下的 CMakeLists.txt 文件和源代码也会被处理 。

通过编译运行后,在build文件夹下,就会出现一个add文件夹:

里面有:

 就是add文件夹的静态库。

target_link_libraries(add1 add2)

指明可执行文件 add1 需要连接一个名为 add2 的链接库 。

然后在add文件夹中CMakeLists.txt文件:

aux_source_directory(. LIB_SRCSSSSS)
add_library(add2 ${LIB_SRCSSSSS})
add_library(add2 ${LIB_SRCSSSSS})

是将当前目录下的工作生成一个静态库,库名为add2。

 这里还有一个命令:

include_directories()

这篇文章写的很详细:

include_directories和find_package_天锡的博客-CSDN博客_include_directories

4.另一形式

tree如下:

.
├── add
│   └── add.h
├── CMakeLists.txt
└── main
    ├── add.cpp
    └── main.cpp

参考文章:

cmake构建多目录项目_今年不吃饭...的博客-CSDN博客_cmake 创建目录

根据这个文章修改tree:

.
├── add
│   ├── add.h
│   └── CMakeLists.txt
├── CMakeLists.txt
└── main
    ├── add.cpp
    └── main.cpp

然后就出现了很多有意思的错误,经过一些列的尝试后发现,不能在.h文件里面写CMakeLists.txt文件,得修改成这个样子:

.
├── add
│   └── add.h
├── CMakeLists.txt
└── main
    ├── add.cpp
    ├── CMakeLists.txt
    └── main.cpp

其中main文件夹中的CMakeLists.txt应该这样写:

include_directories(../add)
add_library(add2 add.cpp)

主要作用是读取add.h头文件的内容,并添加add2的静态库。

最外层的CMakeLists.txt文件应该这样写:

cmake_minimum_required(VERSION 2.8)
project(main)


set(DIR_SRCS ./main/main.cpp)
add_subdirectory(main)
add_executable(add1 ${DIR_SRCS})
target_link_libraries(add1 add2)

set命令直接指向了最后的main.cpp文件,然后将main文件夹加入cmake编译路径,生成add1可执行文件,给add1链接上add2的库。

重点是main.cpp的内容:

#include "../add/add.h"

int main()
{
    cout << add1(1, 12222);
    return 0;
}

头文件必须采用相对地址,才能编译通过。

5.再次编译ceres-slover中3d-pose工程文件

参考文章:

cmake--多级目录工程 - 流浪侠客 - 博客园

tree:

.
├── common
│   └── read_g2o.h
└── pose_graph_3d
    ├── CMakeLists.txt
    ├── plot_results.py
    ├── pose_graph_3d.cc
    ├── pose_graph_3d_error_term.h
    ├── README.md
    └── types.h

然后这里的CMakeLists.txt文件的内容:

cmake_minimum_required(VERSION 2.8)
project(addd)
include_directories(../common)

find_package(Ceres REQUIRED)
include_directories(${CERES_INCLUDE_DIRS})

aux_source_directory(. ALL_SRCS)
add_executable(pose3d ${ALL_SRCS} )

target_link_libraries(pose3d  ${CERES_LIBRARIES})

target_include_directories( pose3d
 PUBLIC ../common
)

因为这个里面pose_graph_3d.cc里面使用了common文件夹内的read_g2o.h。所以要使用include_directories()和target_include_directories()这里面PUBLIC是必须命令把它加入,如果生成了库的话,可以在common里面写一个CMakeLists.txt里面生成库,然后把库加入到这个CMakeLists.txt文件里面。

之后就编译通过了,注意pose_graph_3d.cc里面read_g2o.h的引用格式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/176186.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

maya常用操作

1&#xff1a;重置工作区。2&#xff1a;切换视图。按空格切换视图。3&#xff1a;未选中状态&#xff0c;按shift&#xff0c;再点右键&#xff0c;可以打开交互式创建。这样可以在栅格上创建想要的大小。不选中交互式创建的话&#xff0c;创建的是默认未知。默认未知为正中间…

linux系统中利用QT实现车牌识别的方法

大家好&#xff0c;今天主要和大家分享一下&#xff0c;如何利用QT实现车牌识别的方法。 目录 第一&#xff1a;车牌识别基本简介 第二&#xff1a;车牌识别产品申请 第三&#xff1a;百度车牌识别API接口 第四&#xff1a;车牌识别综合测试 第一&#xff1a;车牌识别基本简…

Scala快速入门

Scala简介 Scala是一门现代的多范式编程语言&#xff0c;平滑地集成了面向对象和函数式语言的特性。Scala运行于Java平台&#xff08;JVM&#xff0c;Java 虚拟机&#xff09;上&#xff0c;并兼容现有的Java程序&#xff0c;Scala代码可以调用Java方法&#xff0c;访问Java字…

ArcGIS Pro脚本工具(17)——生成多分式标注

​朋友们&#xff0c;你们知道ArcGIS里面分式标注的四种写法么&#xff1f; 放错图了&#xff0c;是这个 分式标注的四种形式我们可以把这类叫分式标注&#xff0c;网上也有博主分享过如何在ArcGIS中制作这类标注&#xff0c;但我觉得仍有一些不足。 一是基本都使用VB编写&…

中文问题相似度挑战赛

赛题概要 请本赛题排行榜前10位的队伍&#xff0c;通过作品说明提交源代码&#xff0c;模型以及说明文档&#xff0c;若文件过大&#xff0c;可发送至官网邮箱AICompetitioniflytek.com, 若截止时间内为提交&#xff0c;官方会通过电话联系相关选手&#xff0c;若未接到通知或…

WPF作图神器Interactive DataDisplay的初步使用

文章目录安装初步使用安装 Interactive DataDisplay是一款比较优秀的C#绘图控件&#xff0c;尽管与一些商业控件还有不小的差距&#xff0c;关键是开源免费轻量。 在VS中安装控件十分简单&#xff0c;本测试基于Net Core5.0&#xff0c;在VS的菜单栏->工具->NuGet包管理…

HomeLab 常用工具一:filebrowser

前言在实际使用过程中&#xff0c;我们通常都有基于WEB 的文件操作需求&#xff08;例如从一台陌生设备上想打开看一下&#xff0c;图片等&#xff09;&#xff0c;和nextcloud 相比 filebrowser 更为轻巧也更为方便。一、filebrowser 安装这里基于docker 安装和使用&#xff0…

Prometheus 动态拉取监控服务

Prometheus 版本 2.41.0 平台统一监控的介绍和调研直观感受PromQL及其数据类型PromQL之选择器和运算符PromQL之函数Prometheus 配置身份认证Prometheus 动态拉取监控服务 我们在以前的实例中配置Prometheus 的target 都是手动配置&#xff0c;这在监控目标少的情况下还可以接受…

【基础】BMP格式

BMP格式位图 (BMP)简介格式1.1图和调色板的概念1.2 bmp文件格式1.2.1 位图文件头 14字节1.2.2 位图信息头 40字节1.2.3 调色板1.2.4 注意位图 (BMP)简介 BMP取自位图Bitmap的缩写&#xff0c;也称为DIB&#xff08;与设备无关的位图&#xff09;&#xff0c;是一种独立于显示器…

【苹果家庭群发推】软件keychain中刚打开的证书下载的证书文件要决不会报错 UNTimeIntervalNotificationTrigge

推荐内容IMESSGAE相关 作者✈️IMEAX推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容3.日历推 *** …

linux入门---linux基本指令

目录标题云服务器选择云服务器购买xshell下载如何登陆云服务器Linux的新建与删除新建删除云服务器选择 学习linux的时候云服务器是一个非常重要的工具&#xff0c;那么我们在购买云服务器的时候有很多选择比如说&#xff1a;华为云&#xff0c;腾讯云&#xff0c;阿里云等等&a…

活动星投票网络文明公益广告网络评选微信的投票方式线上免费投票

“网络文明公益广告”网络评选投票_不记名投票小程序_投票帮手免费畅享_扫码投票微信小程序手机互联网给所有人都带来不同程度的便利&#xff0c;而微信已经成为国民的系统级别的应用。现在很多人都会在微信群或朋友圈里转发投票&#xff0c;对于运营及推广来说找一个合适的投票…

ROS2机器人编程简述humble-第三章-PERCEPTION AND ACTUATION MODELS .1

书中&#xff0c;第三章主题&#xff1a;First Behavior: Avoiding Obstacles with Finite States Machines本节旨在应用到现在为止所展示的一切来创建看似“聪明”的行为。这个练习将介绍的许多东西结合起来&#xff0c;并展示使用ROS2编程机器人的效率。此外&#xff0c;将解…

第五届字节跳动青训营 前端进阶学习笔记(八)React框架入门

文章目录前言React 的设计思路1.传统JavaScript更新UI的痛点2.我们对UI代码的需求3.组件&#xff08;1&#xff09;组件定义&#xff08;2&#xff09;组件设计&#xff08;3&#xff09;组件结构4.React的生命周期React的基本语法1.JSXReact的实现1.虚拟DOM2.响应数据的实现前…

Java面试题,Spring Bean的注册与依赖注入

Spring Bean的注册与依赖注入一、XML文件中&#xff0c;将Bean创建到Spring容器1. 基本类型注册2. 类装配3. 有参构造方法装配4. 扩展注入5. Bean的作用域6. Bean的其他配置二、配置类中&#xff0c;将Bean创建到Spring容器1. 在mapper、service、controller中创建&#xff0c;…

计网必会:HTPP详解(非常全面)、cookie、缓存

文章目录应用层协议Web和HTTPHTTP 概述采用非持续连接的HTTPRTT 往返时间的定义**三次握手过程**采用持续连接的HTTPHTTP到底采用哪个&#xff1f;HTTP 的报文格式请求报文功效格式响应报文状态码格式Cookie什么是cookieWeb缓存在学习的过程很多人都遇到了HTTP和Cookie&#xf…

卓有成效的五种用例设计方法

持续坚持原创输出&#xff0c;点击蓝字关注我吧用例设计作为测试工程师的立身之本&#xff0c;是衡量测试工程师综合素质的重要参考&#xff0c;时间是测试工作中重要的测试资源&#xff0c;通过设计高质量的测试用例可以有效地提升测试效率。本文旨在介绍测试工作中常用的五种…

SSO笔记

自己学习做的笔记.没有具体代码 单点登录:多系统,单一位置登录,实现多系统同时登录的一种技术. 也就是说多个应用系统中&#xff0c;用户只需要登录一次就可以访问所有相互信任的应用系统。 和三方登录Oauth2是有区别的.Oauth2属于三方登录.通常是某系统,使用其他系统的用户,…

【机器学习】多分类及多标签分类算法(含源代码)

目录&#xff1a;多分类及多标签分类算法一、单标签二分类问题1.1 单标签二分类算法原理二、单标签多分类问题2.1 ovo2.1.1 手写代码2.1.2 调用API2.2 ovr2.2.1 手写代码2.2.2 调用API2.3 OvO和OvR的区别2.4 Error Correcting三、多标签算法问题3.1 Problem Transformation Met…

Vue3 – Composition API(二)

1、computed函数使用 1.1、computed 在前面我们讲解过计算属性computed&#xff1a;当我们的某些属性是依赖其他状态时&#xff0c;我们可以使用计算属性来处理 在前面的Options API中&#xff0c;我们是使用computed选项来完成的&#xff1b;在Composition API中&#xff0c…