CMakeLists.txt语法规则:部分常用命令说明四

2024-05-06 08:20

本文主要是介绍CMakeLists.txt语法规则:部分常用命令说明四,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一.  简介

前面几篇文章学习了CMakeLists.txt语法中前面几篇文章学习了CMakeLists.txt语法中部分常用命令。文章如下:

CMakeLists.txt语法规则:部分常用命令说明一-CSDN博客

CMakeLists.txt语法规则:部分常用命令说明二-CSDN博客

CMakeLists.txt语法规则:部分常用命令说明三-CSDN博客

本文继续学习 CMakeLists.txt语法中两个常用命令:target_include_directories命令 和 target_link_libraries命令。

二.  CMakeLists.txt语法规则:部分常用命令

target_include_directories命令 和 target_link_libraries命令

target_include_directories 命令为指定目标设置头文件搜索路径。
target_link_libraries 命令为指定目标设置链接库文件。
这听起来跟 include_directories link_libraries 命令有着相同的作用,确实如此,它们的 功能的确相同,但是在一些细节方面却有不同。
target_include_directories target_link_libraries 命令定义如下所示:
target_include_directories(<target> [SYSTEM] [BEFORE]<INTERFACE|PUBLIC|PRIVATE> [items1...][<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])target_link_libraries(<target><PRIVATE|PUBLIC|INTERFACE> <item>...[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)

这俩命令都有一个相同的参数 <target> 目标,这个目标指的就是譬如 add_executable add_library 命令所创建的目标。
首 先 对 于 target_include_directories 命 令 来 说 , SYSTEM BEFORE 这 两 个 选 项 与
include_directories 命令中 SYSTEM BEFORE 选项的意义相同。
如果使用 SYSTEM 选项,会把指定目录当成系统的搜索目录。 通过  BEFORE 选项可显式指定添加到列表的前面。

我们重点关注的是 INTERFACE|PUBLIC|PRIVATE 这三个选项有何不同?
通过一个示例向大家说明,譬如工程目录结构如下所示:

调用关系:

根据以上工程,我们对 INTERFACE PUBLIC PRIVATE 三个关键字进行说明:
PRIVATE 私有的。
main.c 程序调用了 libhello_world.so 。生成 libhello_world.so 时,只在 hello_world.c 中包含了 hello.h libhello_world.so 对外的头文件: hello_world.h 头文件中不包含 hello.h
而且 main.c 不会调用 hello.c 中的函数,或者说 main.c 不知道 hello.c 的存在,它只知道 libhello_world.so 的存在;
那么在 hello_world/CMakeLists.txt 中应该写入:
target_link_libraries(hello_world PRIVATE hello)
target_include_directories(hello_world PRIVATE hello)

INTERFACE 接口。
生成 libhello_world.so 时,只在 libhello_world.so 对外的头文件: hello_world.h 文件 中包含了 hello.h hello_world.c 中不包含 hello.h ,即 libhello_world.so 不使用 libhello.so 提供的功能,但是 main.c 需要使用 libhello.so 中的功能。
那么在 hello_world/CMakeLists.txt 中应该写入:
target_link_libraries(hello-world INTERFACE hello)
target_include_directories(hello-world INTERFACE hello)

PUBLIC 公开的。
PUBLIC = PRIVATE + INTERFACE 。生成 libhello_world.so 时,在 hello_world.c 和 hello_world.h 中 都 包 含 了 hello.h 。 并 且 main.c 中 也 需 要 使 用 libhello.so 提 供 的 功 能 。
那 么 在 hello_world/CMakeLists.txt 中应该写入:
target_link_libraries(hello-world PUBLIC hello)
target_include_directories(hello-world PUBLIC hello)

对于 target_include_directories命令 来说,这些关键字用于指示 何时 需要传递给目标的 包含目录列表 ,指定了 包含目录列表 的使用范围( scope ):
当使用 PRIVATE 关键字修饰时,意味着 包含目录列表 仅用于当前目标;
当使用 INTERFACE 关键字修饰时,意味着 包含目录列表 不用于当前目标、只能用于依赖该目标的其它目标,也就是说 cmake 会将 包含目录列表 传递给当前目标的依赖目标;
当使用 PUBLIC 关键字修饰时,这就是以上两个的集合, 包含目录列表 既用于当前目标、也会传递给当前目标的依赖目标。

对于 target_link_libraries命令 亦是如此,只不过 包含目录列表 换成了 链接库列表 譬如:
target_link_libraries(hello_world INTERFACE hello)
表示目标 hello_world 不需要链接 hello 库,但是对 hello_world 目标的依赖目标(依赖于 hello_world 的目标)它们需要链接 hello 库。
以上便是对 INTERFACEPUBLICPRIVATE 这三个关键字的概括性理解,所以整出这几个关键 字主要还是为了控制包含目录列表链接库列表的使用范围,这就是 target_include_directories
target_link_libraries 命令与 include_directorieslink_libraries 命令的不同之处。
target_include_directories() 功能与 target_link_libraries()的功能完全可以使用 include_directories()link_libraries()来实现。
但是笔者强烈建议大家使用 target_include_directories()和 target_link_libraries()。为什么?保持清晰!
include_directories() link_libraries() 是针对当前源码中的所有目标,并且还会向下传递(譬如通过 add_subdirectory 加载子源码时,也会将其传递给子源码)。
在一个大的工程当中,这通常不规范、有时还 会编译出现错误、混乱,所以我们应尽量使用 target_include_directories() target_link_libraries() ,保持整个 工程的目录清晰。

下一篇文章继续学习 CMakeLists.txt语法的一个常用命令: message命令。

这篇关于CMakeLists.txt语法规则:部分常用命令说明四的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/963868

相关文章

Zookeeper安装和配置说明

一、Zookeeper的搭建方式 Zookeeper安装方式有三种,单机模式和集群模式以及伪集群模式。 ■ 单机模式:Zookeeper只运行在一台服务器上,适合测试环境; ■ 伪集群模式:就是在一台物理机上运行多个Zookeeper 实例; ■ 集群模式:Zookeeper运行于一个集群上,适合生产环境,这个计算机集群被称为一个“集合体”(ensemble) Zookeeper通过复制来实现

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

log4j2相关配置说明以及${sys:catalina.home}应用

${sys:catalina.home} 等价于 System.getProperty("catalina.home") 就是Tomcat的根目录:  C:\apache-tomcat-7.0.77 <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" /> 2017-08-10

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

C++语法知识点合集:11.模板

文章目录 一、非类型模板参数1.非类型模板参数的基本形式2.指针作为非类型模板参数3.引用作为非类型模板参数4.非类型模板参数的限制和陷阱:5.几个问题 二、模板的特化1.概念2.函数模板特化3.类模板特化(1)全特化(2)偏特化(3)类模板特化应用示例 三、模板分离编译1.概念2.模板的分离编译 模版总结 一、非类型模板参数 模板参数分类类型形参与非类型形参 非类型模板

Java基础回顾系列-第一天-基本语法

基本语法 Java基础回顾系列-第一天-基本语法基础常识人机交互方式常用的DOS命令什么是计算机语言(编程语言) Java语言简介Java程序运行机制Java虚拟机(Java Virtual Machine)垃圾收集机制(Garbage Collection) Java语言的特点面向对象健壮性跨平台性 编写第一个Java程序什么是JDK, JRE下载及安装 JDK配置环境变量 pathHe

Adblock Plus官方规则Easylist China说明与反馈贴(2015.12.15)

-------------------------------特别说明--------------------------------------- 视频广告问题:因Adblock Plus的局限,存在以下现象,优酷、搜狐、17173黑屏并倒数;乐视、爱奇艺播放广告。因为这些视频网站的Flash播放器被植入了检测代码,而Adblock Plus无法修改播放器。 如需同时使用ads