CMake之PUBLIC、PRIVATE、INTERFACE

news2024/9/20 22:44:53

在这里插入图片描述

竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生~
个人主页: rainInSunny  |  个人专栏: C++那些事儿、 Qt那些事儿

文章目录

  • 写在前面
  • 抽象版解释
  • 头文件和链接库传递
    • 测试代码结构
    • PUBLIC传递
    • PRIVATE传递
    • INTERFACE传递

写在前面

  使用CMake必然离不开target_include_directoriestarget_link_libraries,这两个命令中都可以设置为三种属性:PRIVATE、PUBLIC、INTERFACE。CMake官方文档对于这三种属性的解释过于抽象,本文将从编译行为的角度来理解这三种属性有什么差异。

抽象版解释

  • target_link_libraries(A B)命令为例,从理解的角度解释:

    • PRIVATE依赖项B仅链接到目标A,若有C链接了目标A,C不链接依赖项B。
    • INTERFACE依赖项B并不链接到目标A,若有C链接了目标A,C会链接依赖项B。
    • PUBLIC依赖项B链接到目标A,若有C链接了目标A,C也会链接依赖项B。
  • 从使用的角度解释,若有C链接了目标A:

    • 如果依赖项B仅用于目标A的实现,且不在头文件中提供给C使用,使用PRIVATE
    • 如果依赖项B不用于目标A的实现,仅在头文件中作为接口提供给C使用,使用INTERFACE
    • 如果依赖项B不仅用于目标A的实现,而且在头文件提供给C使用,使用PUBLIC

头文件和链接库传递

测试代码结构

testCMake
├─ add.cpp
├─ build
├─ CMakeLists.txt
├─ Iadd
│  └─ add.h
├─ Isub
│  └─ sub.h
├─ main.cpp
└─ sub.cpp

  代码目录结构十分简单,add.cpp和add.h组成add模块,Iadd是add模块头文件目录,sub.cpp和sub.h组成sub模块,Isub为sub模块头文件目录。main.cpp最后被编译成sample可执行程序。接下来开始测试~

PUBLIC传递

//Iadd里面的头文件可以传递给链接add的target,头文件传递
target_include_directories(add PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Iadd)
//Isub的头文件传递给链接sub库的target,头文件传递
target_include_directories(sub PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Isub)
//sub链接add库,链接sub的库也将链接add,链接库传递(含头文件)
target_link_libraries(sub PUBLIC add)
//sample链接sub
target_link_libraries(sample PUBLIC sub) //无视,因为属于最尾子节点,没有下一级来传播

  使用上面的CMake配置进行测试,得到结果如下。可以看出由于头文件包含属性和链接属性都是PUBLIC,因此sample虽然只链接了sub模块,此时sub链接的add模块会直接传递到sample模块,即sample模块也链接了add模块。

//add模块配置内容
//include
-ID:/workspace/testCmake/Iadd
// link
 -lkernel32 -luser32

//sub模块配置内容
//include 由于add库包含头文件使用的是public,所以sub只要link了add库,就会自动包含add的头文件目录,不需要另外include_directories
-ID:/workspace/testCmake/Isub -ID:/workspace/testCmake/Iadd
// link
 -ladd -lkernel32 -luser32

//sample模块配置内容
//include 同理Isub,另外由于sub是public链接add库,因此add库的头文件可以传递到链接sub的sample
-ID:/workspace/testCmake/Isub -ID:/workspace/testCmake/Iadd
//由于sub是public链接add库,sample也链接了add库
-lsub -ladd -lkernel32 -luser32

PRIVATE传递

//Iadd里面的头文件不可以传递给链接add的target
target_include_directories(add PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Iadd)
//Isub的头文件不可以传递给链接sub库的target
target_include_directories(sub PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Isub)
//sub链接add库,链接sub的库不能自动链接add
target_link_libraries(sub PRIVATE add)
//sample链接sub
target_link_libraries(sample PRIVATE sub)

  使用上面的CMake配置进行测试,得到结果如下。由于使用PRIVATE属性,头文件和链接库都不能传递,所以sample包含的头文件目录为空,只链接了sub库。

//add模块配置内容
//include
-ID:/workspace/testCmake/Iadd
//link
-lkernel32 -luser32

//sub模块配置内容
//include 由于add库包含头文件使用的是PRIVATE,所以sub包含没有Iadd
-ID:/workspace/testCmake/Isub 
// link
-ladd -lkernel32 -luser32

//sample模块配置内容
//include 为空,add及sub头文件都无法传递至sample
//link 只链接sub
-lsub -lkernel32 -luser32

INTERFACE传递

//Iadd里面的头文件可以传递给链接add的target,而add模块本身不包含该目录
target_include_directories(add INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/Iadd)
//Isub的头文件可以传递给链接sub库的target,而sub模块本身不包含该目录
target_include_directories(sub INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/Isub)
//sub没有链接add库,链接sub的库自动链接add
target_link_libraries(sub INTERFACE add)
//sample链接sub和add
target_link_libraries(sample PUBLIC sub) //private也可

  使用上面的CMake配置进行测试,得到结果如下。由于头文件和链接库都设置为INTERFACE,所以add和sub模块都只做头文件和链接库的传递,传递到sample中,最终sample中包含add和sub的头文件并同时链接了add和sub。

//add模块配置内容
//include 为空,INTERFACE只给链接者提供接口,而被链接者不依赖该接口,只做include path的传递
//link
-lkernel32 -luser32

//sub模块配置内容
//include 为空,同上
// link 链接也是INTERFACE,不链接,只做链接库的传递
 -lkernel32 -luser32

//sample模块配置内容
//include 由于是PUBLIC连接sub,所以前面INTERFACE传递的头文件和库都会包含在sample中 
-ID:/workspace/testCmake/Isub -ID:/workspace/testCmake/Iadd
// 同上 
-lsub -ladd -lkernel32 -luser32

创作不易,感谢点赞、关注和收藏~

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

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

相关文章

LVGL从SD卡读取图片并显示到MCU LCD屏详细笔记教程

1、前言 在上一篇LVGL专题文章中已经讲解了如何将LVGL与FatFs链接起来,实现LVGL对SD卡中的数据进行读写操作。本文在上一文的基础上,将实现LVGL读取文件系统中的图片文件(BMP、PNG、JPG),并显示到MCU设备中的LCD屏中。…

转行软件测试必需要知道的知识

1前言 随着现在互联网行业的迅猛发展,越来越多的人想涌入进来,因为大家都觉得IT行业工资高,做测试门槛又低,是的,入门门槛确实比较低,但是要做好的话,还是有点难的,毕竟术业有专攻嘛…

网约车资格证考试攻略(必备宝典)

考试分数详情及攻略如下: 一、理论部分:(电脑操作,鼠标勾选) 1、全国试题,满分50分,40分过关,每位学员要练习到45分才行; 2、地方试题,满分25分&#xff0c…

Vue3源码调试-第三篇

前言 上两篇已经调试完packages/runtime-dom/src/index.ts下的createApp函数的第一行了,接下来我们看下一行 injectNativeTagCheck 首先说下这个__DEV__估计也是定义在dev.js下,又或者是哪里的,这里控制台输出是true,那我估计是…

Nginx: 代理场景下Nginx接收用户请求包体的处理

Nginx 反向代理图 当用户发过来一个request body的时候,Nginx 是如何处理这样一个body这个body 它对应的就是我们客户请求的一些具体内容 1 )proxy_request_bufering 指令 接收包体的两种方式 接收完全部包体再发送一边接收包体一边发送 接收包体的两种…

前端项目部署到服务器上(nginx)

我这个之前已经部署过项目,所以要进行这个操作 docker imagedocker rm -f nginx //用于强制删除名为“nginx”的容器docker ps //用于列出当前正在运行的Docker容器docker volume -fdocker volume prune //用于删除所有未使用的Docker数据卷,‌释放存…

day11JS-面向对象和js中的设计模式

1. 面向对象 1.1 什么是面向对象 面向对象是一种编程思想,JS就是基于这个思想构建出来的一门编程语言,所以JS中存在对象、类、实例的概念。 对象:万物皆对象。 构造函数(类):把具有某一特征的内容可以划分…

穿梭虚实之间:3DGS与NeRF如何辅助机器人遥控操作?

导读: 本研究介绍了一种用于机器人遥控操作的新型辐射场可视化技术,研究者提出了一种在线训练辐射场的方法,能够实时从多个摄像头获取数据,支持多种辐射方法,包括NeRF和3DGS。该系统与现有的ROS遥控操作系统集成&#…

惠海H6501 DCDC降压恒压ic 60V72V80V100V转24V36V48V实地架构低功耗 仪表仪器供电 兼容XX9487

H6501是一款高压降压型开关稳压器,可输出高达1A的持续电流至负载。它集成了一个 高压高端MOSFET,提供2.5A的典型峰值电流限。其4.5V至48V的宽输入电压范围可适用于各种降压应用,是汽车、工业和照明应用的理想之选。采用滞环电压控制模式&…

行为识别实战第二天——Yolov5+SlowFast+deepsort: Action Detection(PytorchVideo)

Yolov5SlowFastdeepsort 一、简介 YoloV5SlowFastDeepSort 是一个结合了目标检测、动作识别和目标跟踪技术的视频处理框架。这一集成系统利用了各自领域中的先进技术,为视频监控、体育分析、人机交互等应用提供了一种强大的解决方案。 1. 组件说明: Y…

golang笔记——Go堆内存管理

前言 本文主要记录个人学习Golang堆内存管理,涉及到的相关内容,算是对个人所学知识点的梳理与总结。从非常宏观的角度看,Go的堆内存管理就是下图这个样子 学习内存管理,肯定首先需要了解内存管理的基本知识,我会按照 内…

C++笔记10•容器适配器:stackqueue priority_queue•

从C中看stack&queue&priority_queue 1.stack的介绍 官方stack实现: 本质是一个数组 1. stack 是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。 2. stack 是作为容器适…

【C/C++】typedef用法

typedef用法讲解&#xff0c;时隔半年&#xff0c;再看typedef。 &#x1f381;typedef可以简化结构体关键字 #include<iostream> using namespace std;struct Person {char name[64];int age; };void test01() {struct Person p { "张三",18 };//不用type…

【设计模式-代理】

定义 代理模式是一种结构型设计模式&#xff0c;它提供了对象的替代者或占位符&#xff0c;用来控制对这个对象的访问。通过代理模式&#xff0c;一个类可以代表另一个类来执行某些操作。这种模式常用于增强对象的功能或控制对对象的访问。 特点 控制访问&#xff1a;代理模…

day01 1.c++对c的扩充

#include <iostream>using namespace std;int main() {string s1;cout << "请输入一个字符串&#xff1a;";getline(cin,s1);int count10,count20,count30,count40;int len s1.length();for(int i0;i<len;i){if((s1[i]>a&&s1[i]<z) ||…

BeanPostProcessor和Ordered

1. 概述 BeanPostProcessor 和 Ordered 接口用于在Spring容器初始化Bean的过程中进行自定义处理&#xff0c;并控制处理顺序 2. BeanPostProcessor BeanPostProcessor 接口允许你在Spring容器初始化Bean的前后对Bean进行自定义处理。它有两个方法&#xff1a; postProcessB…

zabbix对接Grafana

1.grafana安装 Download Grafana | Grafana Labs sudo yum install -y https://dl.grafana.com/oss/release/grafana-11.1.4-1.x86_64.rpm 2.zabbix插件安装 Grafana 默认并没有 zabbix 数据源的支持&#xff0c;只有安装了zabbix插件&#xff0c;才可以在grafana中添加zabbi…

峟思固定测斜仪的工作原理与应用

固定测斜仪作为一种精密的测量仪器&#xff0c;在地质工程、土木工程、矿山安全等领域中发挥着至关重要的作用。它通过测量土体或岩体内部的水平位移&#xff0c;为工程安全监测提供了可靠的数据支持。本文将详细介绍固定测斜仪的工作原理、结构组成以及其在实际应用中的表现。…

一文读懂 DDD领域驱动设计

DDD&#xff08;Domain-Driven Design&#xff0c;领域驱动设计&#xff09;是一种软件开发方法&#xff0c;它强调软件系统设计应该以问题领域为中心&#xff0c;而不是技术实现为主导。DDD通过一系列手段如统一语言、业务抽象、领域划分和领域建模等来控制软件复杂度&#xf…

快手小店自动回复机器人脚本

快手小店自动回复机器人是一种利用人工智能AI技术&#xff0c;能够根据用户的会话咨询内容自动回复的工具。这种机器人可以帮助快手小店主快速、高效地回复客户消息&#xff0c;提升店铺的客户服务质量和销售效率。 甜羊浏览器是一款基于Chromium内核开发的国产浏览器&#xff…