当前位置: 首页 > news >正文

【Spiffo】环境配置:最简cmake工程构建(含使用例)

简介:

        本期介绍一下如何配置一个最简单可用cmake工程以及如何在自己的工程里添加第三方库/在已有工程下添加自己的库。目前只涉及最基本的框架搭建,因为想要一篇精通cmake基本上不太可能,而且很可能看晕,所以这里推荐先搞懂最基本的框架,需要什么高级功能再现场管AI要也能保证搭出来的框架能用。

附框架demo:


链接: https://pan.baidu.com/s/1kxLcraBES84QA2p3vKiwvg 提取码: x52c 

一、cmake工程最基本的构造

(1)最简工程

首先看一下cmake工程一般都长什么样子:

cmake的主要作用是辅助构建Makefile的规则,所以和Makefile工程一样,cmake工程一般也存在include和src分别存储头文件和源文件,同时外加了CMakeLists.txt来替代Makefile(因为这个的编写比Makefile更符合直觉,更简单,也更易于移植)和build文件夹来存放编译的中间文件。

CMakeLists.txt中指定编译规则的方法如下:

可以看到,规则文件可以大概划为三段,分别是工程的一些基本设置,这些设置可以理解为不需要修改的内容(等到真需要修改的时候自己就能悟到需要修改了,很神奇);指定src;指定include,每行具体什么意思后面说。有main,有头文件和源,一个最简单的c工程内所有的要素就指定清楚了。

使用方面,进入build目录,输入下面指令后即可生成对应的编译规则

cmake ..

然后make即可编译

(2)含第三方库的工程

        但是通常情况下,如果要制作一个完整项目,我们不可能亲自处理所有的琐碎的小问题(比如格式转换,模型制作,数据处理等),难免要使用第三方库来帮我们处理这些事情,以便我们能够集中精力在主要的程序逻辑上。

        而如果使用第三方库的话,其中又包含它自己的CMakeList和include以及src,可以用一张图来概括cmake工程的结构为:

这也就是说,如果CMakeLists.txt规定好了层级之间的关系的话,就能打通不同层之间的调用关系了,接下来给一个例子进行演示。

二、不同层级之间CMakeLists.txt的关系以及如何引用

(1)根CMakLists.txt是什么样的

上面说了配置文件可以分为三段,其中后两段是需要按需修改的,分别为指定src和指定include:

1)指定src

指定的过程主要就是两行内容,
 

一个是使用 add_executabel()创建可执行文件的对象,

然后target_sources()将源文件编译后放入其中,

至于上面的打包,只是为了方便管理,懒得做的话直接列举出来换掉MAIN_SOURCE这个变量即可

(比如说变成 target_sources(${PROJECT_NAME PRIVATE main.c source1.c source2.c})这样)。当然不必一个一个指定文件,不过我推荐这么做,因为自动搜索文件容易出现稀奇古怪的问题(比如说FILE(GLOB )的方法)。

2)指定include

指定头文件直接一行target_include_directory()即可搞定

(2)不同层级的连接

现在假定ThirdParty_lib是一个第三方库(同样是一个cmake工程,不是的话得自己组装一下,后面说怎么办),如果要在我们的工程中引用它的API的话,就需要告诉我们项目的CMakeList.txt存在一个这样的工程要作为子工程使用。

在根CMakeLists.txt中为:

add_subdirectory()指明了需要在这个文件夹下搜索子工程或库

Target_link_libraries()指明了链接库的名称,要链接叫做ThirdParty的库

关于这个名称,则是由子项目来定义的(看最下面绿色和红色)

也可以看到两个CMakeList.txt在各自指定include和src上的操作是非常相似的

规定完以后便可以在主函数main.c中调用ThirdParty_lib库中的API了

编译运行可以看到API可用

三、使用例

(1)库类型

在举例之前我们要知道库大概分为几类:

1)单文件库

比如各种规定格式的库,这种库只有一个.h,他的函数定义以及逻辑全部写在了同一个文件里,比如:

STB Libraries,https://github.com/nothings/stb

TinyXML2, https://github.com/leethomason/tinyxml2

这种类型的库只需要把.h文件放入我们工程的include文件夹即可,也不需要另外再分支出来一个子工程

2)系统库

系统库一般来说就是apt install下来或者下载完make install的库,这种库也不需要进行过多操作,工程中直接引用即可,比如:

libpng / libjpeg,libpng.org: top level

FFmpeg,FFmpeg

注意,顺便一提,:

引用工程头文件使用,#include “”

引用系统头文件则使用, #include <>

3)多文件库

这种一般比较大,和工程也强相关,一般来说是各种框架性的东西,比如图形框架,实时操作系统框架等,这种就需要用到上述的配置方法,所以这里举一个例子。

(2)配置举例

比如我想在我的工程内内嵌一个lvgl图形框架,那么我应该在我的工程根目录添加一个我自己的CMakeLists.txt

至于链接库的名称是什么,得自己去工程相关文件里找找看(仔细阅读CMakeLists.txt里的引用说明,包能找到的)

编写完以后,就可以常规地进入build生成Makefile并编译了

编译出来的可执行程序就在规则里规定的地方

四、如何配置交叉编译

当然了,有时候这个工程不见得就是给编译它的设备用的,所以再补一个交叉编译如何配置

在工程目录新建一个叫做toolchain.cmake的文件,其中指明你的交叉编译器的路径(如果已经配置了系统环境变量的话直接在CMakeList.txt里指定编译器也可以)

然后生成Make file时指令改成这样即可:

cmake -DCMAKE_TOOLCHAIN_FILE=”../toolchain.cmake” ..

总结

到这里基本上配置出来的cmake工程框架就是可用的了(虽然其功能远不止于此),编写的原则总结起来就是指定src的那两行、指定include的那两行以及链接库如何引用,记住这几个东西类推子工程的配置文件即可。

相关文章:

  • 2025年win10使用dockerdesktop安装k8s
  • 浙大研究团队揭示电场调控5-HT1AR的分子机制
  • 动态规划问题之最长公共子序列
  • 【Easylive】convertVideo2Ts 和 union 方法解析
  • UML统一建模语言
  • Mysql之事务(下)
  • 七. JAVA类和对象(二)
  • FreeCAD傻瓜教程-装配体Assembly的详细使用过程
  • java基础知识面试题总结
  • Android学习总结之算法篇三(排序)
  • git kex_exchange_identification 相关问题
  • C/C++ JSON 库综合对比及应用案例(六)
  • Redis 与 AI:从缓存到智能搜索的融合之路
  • UI设计系统:如何构建一套高效的设计规范?
  • S32K144入门笔记(二十三):FlexCAN解读(1)
  • SAP CO88根据标准价格拆分增量错误解决
  • SpringBoot实战:Excel文件上传、数据验证与存储全流程解析
  • EasyExcel导出导入excel工具类
  • 【创新项目实训个人博客】camel学习笔记(1)camel介绍
  • 【教程】如何利用bbbrisk一步一步实现评分卡
  • 搜狐一季度营收1.36亿美元,净亏损同比收窄超两成
  • 莱布雷希特专栏:古典乐坛边缘人
  • 病愈出院、跳大神消灾也办酒,新华每日电讯:农村滥办酒席何时休
  • 浙江省委金融办原副主任潘广恩被“双开”
  • 中国恒大披露清盘进展:要求债权人提交债权证明表
  • 布局50多个国家和地区,我国科技型企业孵化器数量全球第一