modern cmake的概念剖析

这篇文章主要介绍一些相关的概念,具体的语法建议去github上看相关教程。

从c++的依赖关系说起

如果要学习modern cmake,最基本的是要搞清楚文件之间以及项目之间的依赖关系。在c++中,文件之间的依赖关系主要来自两个方面:

  1. include头文件;
  2. 函数声明和实现的分离,声明依赖于实现才能正确链接;

按照依赖关系,把一个项目中所有文件都连上箭头,我们可以得到一个有向图。(通常是带环的)
如果对这个项目进行编译链接,所有的cpp文件会编译链接成一个整体,它们的依赖关系也会合并。同时,由于cpp中的include在编译过程中已经展开了,所以cpp文件中由(1. include头文件)引入的依赖关系会消失,而(2. 函数声明和实现的分离,声明依赖于实现才能正确链接)只会剩下.h文件对.cpp文件的依赖,.cpp文件对.h文件的依赖往往不存在(正常来说没有人会在一个cpp文件声明某个函数并且在另一个h文件中实现它)。于是,生成的lib文件不会依赖于任何文件(动态链接是另一种情况,暂且不提),不过,h文件引入的依赖关系依旧会保存。这时,整个项目只剩下不同h文件之间的依赖关系和h文件对lib的依赖。

cmake中文件的interface和private

如果这个项目是一个库,我们往往会把库中的一些h文件提供给外部使用,另一部分则隐藏起来。把提供给外部使用的头文件设置为interface,相应的,这些提供给外部使用的头文件所依赖的其它头文件也应当设置为interface(显然,interface必须要随着依赖关系传递,如果A依赖于B并且A是interface的,那么B也是interface的)(一般的做法是把这些头文件单独放到一个目录并且通过target_include_libraries(interface)来设置,事实上,由于include是通过目录来寻找.h文件,我们不能单独把某个头文件设置为interface,只能把某个目录设置为interface)。如果一个头文件不需要提供给外面,也不会被其它提供给外部的头文件引用,只是自己编译链接才需要,则设置为private,private可以理解为在编译链接后就不复存在的东西,只是编译链接时使用。既是interface又是private的头文件则设置为public。绝大多数情况下,由于h文件往往依赖于lib,所以lib也会提供给外部使用,默认为interface,不需要显示指出(实际上也没法指出来,在cmake的相关教程中并未说明编译后的lib是interface还是private,但从逻辑上看,把编译后的lib理解为interface是非常合理的)。同时,由于cpp文件无法对外提供(一般不会去include一个cpp文件),所以cpp文件默认为private。(某些特殊情况下,有些cpp不会被编译,可以把这些cpp文件指定为interface)。
简单的理解,interface是提供给外部使用的,private是自己编译链接项目所使用。另外,还有一个名为public的关键字,如果既是interface也是private,则设置为public。

cmake中项目(target)的interface和private

在上一节已经提到,对于一个项目来说,设置为interface的文件是提供给外部使用的。于是,如果一个项目要使用另一个项目,这个项目也就只能拿到另一个项目中设置为interface的文件而接触不到设置为private的文件。事实上,对于这个项目来说,另一个项目就是另一个项目中所有设置为interface的文件的合集。于是,可以仿照上一节中,把文件区分为interface或private,项目也可以被区分为为interface或private。另外,在正式使用中,不止文件和项目,其它属性也可以区分为interface或者private。

interface libraries

在cmake中还有一个相当有趣的东西,interface libraries。一个不编译链接的项目是一个interface libraries(通过add_libraries(interface)指明)。由于自己不编译链接,所以不存在private的东西,全是interface。这个指令主要用来处理:

  1. 只有头文件的库;
  2. 没有指明extern “C"或者__declspec (dllexport)或者def文件的库(比如OpenGL的glad库);
  3. 属性表

以上这些情况下,对应的库都不能编译链接,因此只能作为interface libraries来管理。

动态链接

在上面几节中,还只提到了静态的编译链接问题,对于动态链接与加载该如何处理则没有提到。事实上,cmake和编译器并不能很好的解决第三方dll的动态加载问题,动态链接本身也不是编译器的任务(在path里设置dll的路径是无效的,只有在系统环境变量添加path或者dll和exe在同一个目录时才能找到正确的dll)。因此,对于dll的管理,需要自己手动写add_custom_target和add_custom_command去管理。除此之外,在c++的代码中还可能动态的加载一些文件或者图片,这些同样超出了cmake的职责,只能自己写add_custom_target和add_custom_command去管理。

项目是modern cmake的核心

在cmake 3.0之前,cmake一直是全局变量漫天飞,成不成功全看运气。为了解决这一问题,从3.0开始,cmake要求尽量少的使用全局变量,而是用项目去管理所有的东西。
从上面这几节可以发现,一个项目,既可以是一个文件、也可以是一个大型的库、也可以是一个属性表、还可以是一个命令或者一组命令,具有非常高的灵活性。同时,又通过interface和private来区分项目对其它事物的使用,极大的简化了编译链接中的逻辑,使得编译链接的管理变得愈发清晰,这也正是modern cmake所推崇的。

modern cmake的概念剖析相关推荐

  1. Modern CMake 翻译 2.1 变量和缓存

    <<Modern CMake>> 翻译 2.1 变量和缓存 局部变量 我们首先来看变量.局部变量通常这样设置: set(MY_VARIABLE "value" ...

  2. 第一章:数组与指针概念剖析

    第一章 数组与指针概念剖析 收藏 数组与指针生来就是双胞胎,多数人就是从数组的学习开始指针的旅程的.在学习的过程中,很自然就会经常听到或见到关于数组与指针的各种各样的看法,下面我节选一些在各种论坛和文 ...

  3. 高数 | 【概念剖析】一元、二元微分,连续、可微、可偏导、偏导连续的超强通俗解析!

    先来看看关系网络全地图: 联想一下,疏通筋骨!(注:偏导连续默认指一阶偏导连续) 一.连续.可微 连续,就是离散的对立统一面. 一元函数中,用直线串联相邻微分点,就构成了宏观连续的平面曲线. 二元函数 ...

  4. 【Netty】第二章 网络编程和 IO 概念剖析

    [Netty]第二章 网络编程 文章目录 [Netty]第二章 网络编程 一.网络编程 1.模拟阻塞模式下服务器单线程处理请求 2.模拟非阻塞模式下服务器单线程处理请求 3.使用 Selector 改 ...

  5. IO学习之概念剖析及五种IO模型

    1.概念剖析 后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,即使没有见过,但是IO肯定都听说过.聊IO之前需要我们对几个概念有一定的认识和理解,比如同步.阻塞.异步.非阻塞 ...

  6. Python基础系列讲解——继承派生和组合的概念剖析

    Python作为一门面向对象的语言,它的面向对象体系中主要存在这么两种关系,一个是"类"和"实例"的关系,另一个是"父类"和"子类 ...

  7. 安卓dts音频解码_DTS音效、解码、编码概念剖析

    一.什么是DTS 1.DTS是什么 我们经常看到电子产品上贴着DTS的logo,那到底什么DTS呢?其实DTS非常复杂,是一个庞大的系统,里面包括了很多子系统,主要包括声音编码.解码.音效.我们可以简 ...

  8. RocketMQ基础概念剖析源码解析

    Topic Topic是一类消息的集合,是一种逻辑上的分区.为什么说是逻辑分区呢?因为最终数据是存储到Broker上的,而且为了满足高可用,采用了分布式的存储. 这和Kafka中的实现如出一辙,Kaf ...

  9. python形参中传入两个实参_C语言学习第3篇---形参-实参概念剖析

    参数概念 #include<stdio.h>int function(int a){return a+1;}int main(){printf("%d",functio ...

最新文章

  1. 力扣(LeetCode)刷题,简单题+中等题(第20期)
  2. WebLogic使用总结(一)——WebLogic安装
  3. layer output 激活函数_深入理解YOLO v3实现细节 - 第3篇 构建v3的Loss_layer
  4. Python 语法错误:“SyntaxError: invalid character in identifier“,原因及解决方法
  5. 搭建认证服务器 - Spring Security Oauth2.0 集成 Jwt 之 【密码认证流程】 总结
  6. kibana安装与Kibana server is not ready yet
  7. 绝对编码和增量编码_用户体验设计师应该学习编码吗? 绝对
  8. 神经网络的相关函数以及误差类型
  9. 【转】卖萌的大牛你桑不起啊 ——记CVPR2011一篇极品文章
  10. android 阿里hotfix,Android 热修复方案--阿里百川HotFix
  11. mysql deadlock处理
  12. 联想微型计算机m910q,联想ThinkCentre M910x迷你台式机 获最佳创新产品奖
  13. 外星人笔记本计算机,目前收集整理的外星人笔记本型号大全
  14. 打开项目时,出现“确保已安装项目类型(.wdproj)的应用程序 ”的解决办法
  15. 7-6 平面向量加法
  16. scratch编程巡线小虫
  17. c语言将两幅bmp格式图片拼接图片
  18. Linux服务器安装杀毒软件ClamAV
  19. 论文阅读: BotCamp: Bot-driven Interactions in Social Campaigns WWW 2019
  20. 一般小型网站价格,小型网站怎么优化

热门文章

  1. 华硕主板win10 使用固态硬盘,机械硬盘不显示解决
  2. RPA中国流程自动化产业峰会火热报名中...
  3. Bea Webblogic
  4. efk集中管理npgstack集群日志
  5. 【51Nod】-1326 遥远的旅途
  6. 5700新手学堂,疑难杂症问题解决荟萃
  7. ARM加载Realtek-8188CUS USB无线网卡(二)_连接到WiFi网络
  8. Flutter实战项目-第八篇 监听键盘弹起
  9. EulerOS 2.0 SP5 - 华为欧拉(CentOS 7 华为版)下载
  10. 【JokerのZYNQ7020】UART