【CMake 入门与进阶(4)】 CMakeLists.txt 语法规则基础及部分常用指令-续(附使用代码)

news2024/11/24 6:43:40

        由于篇幅问题本篇接着上文继续介绍 CMakeLists.txt 语法规则基础及常用指令。

  • aux_source_directory

        aux_source_directory 命令会查找目录中的所有源文件,其命令定义如下:

aux_source_directory(<dir> <variable>)

        从指定的目录中查找所有源文件,并将扫描到的源文件路径信息存放到变量中,譬如目录结 构如下:

├── build
├── CMakeLists.txt
└── src
  ├── 1.c
  ├── 2.c
  ├── 2.cpp
  └── main.c

        CMakeCache.txt 内容如下所示:

# 顶层 CMakeLists.txt
cmake_minimum_required("VERSION" "3.5")
project("HELLO")

# 查找 src 目录下的所有源文件
aux_source_directory(src SRC_LIST)
message("${SRC_LIST}") # 打印 SRC_LIST 变量

        进入到 build 目录下,执行 cmake ..命令,打印信息如下所示: 

         由此可见,aux_source_directory 会将扫描到的每一个源文件添加到 SRC_LIST 变量中,组成一个字符串列表,使用分号“;”分隔。

        同理,aux_source_directory 既可以使用相对路径,也可以使用绝对路径,相对路径是相对于当前源码路径。

  •  get_target_property 和 set_target_properties

        分别用于获取/设置目标的属性。

  • include_directories include_directories

        命令用于设置头文件的搜索路径,相当于 gcc 的-I 选项,其定义如下所示:

include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])

        默认情况下会将指定目录添加到头文件搜索列表(可以认为每一个 CMakeLists.txt 源码都有自己的头文 件搜索列表)的最后面,可以通过设置 CMAKE_INCLUDE_DIRECTORIES_BEFORE 变量为 ON 来改变它默认行为,将目录添加到列表前面。也可以在每次调用 include_directories 命令时使用 AFTER 或 BEFORE 选项来指定是添加到列表的前面或者后面。如果使用 SYSTEM 选项,会把指定目录当成系统的搜索目录。 既可以使用绝对路径来指定头文件搜索目录、也可以使用相对路径来指定,相对路径被解释为当前源码路径的相对路径。

        譬如工程目录结构如下所示:

├── build
├── CMakeLists.txt
├── include
│ └── hello.h
└── main.c

        源文件 main.c 中使用了 include 目录下的头文件 hello.h,CMakeLists.txt 内容如下:

# 顶层 CMakeLists.txt
cmake_minimum_required("VERSION" "3.5")
project("HELLO")

include_directories(include)
add_executable(hello main.c)

        使用 include_directories 命令将当前目录下的 include 文件夹添加到头文件搜索列表中,进入 build 目录下,执行 cmake、make 进行构建、编译,编译过程是没有问题的,不会报错提示头文件找不到;但如果去掉 include_directories(include)这条命令,编译肯定会报错,大家可以动手试试!

        默认情况下,include 目录被添加到头文件搜索列表的最后面,通过 AFTER 或 BEFORE 选项可显式指定添加到列表后面或前面:

# 添加到列表后面
include_directories(AFTER include)

# 添加到列表前面
include_directories(BEFORE include)

        当调用 add_subdirectory 命令加载子源码时,会将 include_directories 命令包含的目录列表向下传递给子源码(子源码从父源码中继承过来),我们测试下,譬如工程目录结构如下所示:

├── build
├── CMakeLists.txt
├── include
│ └── hello.h
└── src
  ├── CMakeLists.txt
  └── main.c

        src 目录下 main.c 源文件中使用了 hello.h 头文件,顶层 CMakeLists.txt 内容如下所示:

# 顶层 CMakeLists.txt
cmake_minimum_required("VERSION" "3.5")
project("HELLO")

include_directories(include)
add_subdirectory(src)

        顶层 CMakeLists.txt 源码中调用了 include_directories 将 include 目录添加到当前源码的头文件搜索列表中,接着调用 add_subdirectory 命令加载、执行子源码;src 目录下 CMakeLists.txt 内容如下所示:

# src 目录 CMakeLists.txt
add_executable(hello main.c)

        进入到 build 目录,进行构建、编译,整个编译过程是没有问题的。

  • link_directories 和 link_libraries link_directories

        命令用于设置库文件的搜索路径,相当于 gcc 编译器的-L 选项;link_libraries 命令用于 设置需要链接的库文件,相当于 gcc 编译器的-l 选项;命令定义如下所示:

link_directories(directory1 directory2 ...)
link_libraries([item1 [item2 [...]]]
                 [[debug|optimized|general] <item>] ...)

        link_directories 会将指定目录添加到库文件搜索列表(可以认为每一个 CMakeLists.txt 源码都有自己的库文件搜索列表)中;同理,link_libraries 命令会将指定库文件添加到链接库列表。link_directories 命令可以使用绝对路径或相对路径指定目录,相对路径被解释为当前源码路径的相对路径。

        譬如工程目录结构如下所示:

├── build
├── CMakeLists.txt
├── include
│ └── hello.h
├── lib
│ └── libhello.so
└── main.c

        在 lib 目录下有一个动态库文件 libhello.so,编译链接 main.c 源文件时需要链接 libhello.so;CMakeLists.txt 文件内容如下所示:

# 顶层 CMakeLists.txt
cmake_minimum_required("VERSION" "3.5")
project("HELLO")

include_directories(include)
link_directories(lib)
link_libraries(hello)
add_executable(main main.c)

        库文件名既可以使用简写,也可以库文件名的全称,譬如:

# 简写
link_libraries(hello)

# 全称
link_libraries(libhello.so)

        link_libraries 命令也可以指定库文件的全路径(绝对路径 /开头),如果不是/开头,link_libraries 会认为调用者传入的是库文件名,而非库文件全路径,譬如上述 CMakeLists.txt 可以修改为下面这种方式:

# 顶层 CMakeLists.txt
cmake_minimum_required("VERSION" "3.5")
project("HELLO")

include_directories(include)
link_libraries(${PROJECT_SOURCE_DIR}/lib/libhello.so)
add_executable(main main.c)

        与 include_directories 命令相同,当调用 add_subdirectory 命令加载子源码时,会将 link_directories 命令包含的目录列表以及 link_libraries 命令包含的链接库列表向下传递给子源码(子源码从父源码中继承过来)。 这里不再演示了,大家可以自己测试下。

  • list

        list 命令是一个关于列表操作的命令,譬如获取列表的长度、从列表中返回由索引值指定的元素、将元素追加到列表中等等。命令定义如下:

list(LENGTH <list> <output variable>)
list(GET <list> <element index> [<element index> ...]
      <output variable>)
list(APPEND <list> [<element> ...])
list(FIND <list> <value> <output variable>)
list(INSERT <list> <element_index> <element> [<element> ...])
list(REMOVE_ITEM <list> <value> [<value> ...])
list(REMOVE_AT <list> <index> [<index> ...])
list(REMOVE_DUPLICATES <list>)
list(REVERSE <list>)
list(SORT <list>)

           列表这个概念还没给大家介绍,列表其实就是字符串数组(或者叫字符串列表、字符串数组),稍后再向大家说明。

        LENGTH 选项用于返回列表长度;

        GET 选项从列表中返回由索引值指定的元素;

        APPEND 选项将元素追加到列表后面;

        FIND 选项将返回列表中指定元素的索引值,如果未找到,则返回-1。

        INSERT 选项将向列表中的指定位置插入元素。

        REMOVE_AT 和 REMOVE_ITEM 选项将从列表中删除元素,不同之处在于 REMOVE_ITEM 将删除给定的元素,而 REMOVE_AT 将删除给定索引值的元素。

        REMOVE_DUPLICATES 选项将删除列表中的重复元素。

        REVERSE 选项就地反转列表的内容。

        SORT 选项按字母顺序对列表进行排序。

  • message

        message 命令用于打印、输出信息,类似于 Linux 的 echo 命令,命令定义如下所示:

message([] "message to display" ...)

        可选的 mode 关键字用于确定消息的类型,如下:

mode说明
none(无)重要信息、普通信息
STATUS附带信息
WARNINGCMake 警告,继续处理
AUTHOR_WARNINGCMake 警告(开发),继续处理
SEND_ERRORCMake 错误,继续处理,但跳过生成
FATAL_ERRORCMake 错误,停止处理和生成
DEPRECATION如果变量 CMAKE_ERROR_DEPRECATED 或 CMAKE_WARN_DEPRECATED 分别启用,则 CMake 弃用错误或警告,否则没有消息。

        所以可以使用这个命令作为 CMakeLists.txt 源码中的输出打印语句,譬如:

# 打印"Hello World"
message("Hello World!")

未完待续...

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

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

相关文章

开发者工具调试

Console控制台 F12打开控制台 选择其他tab面板时&#xff0c;ESC打开Console面板enter直接执行Console的代码&#xff0c;shiftEnter输入多行代码 Source面板 左键单机行号设置断点&#xff0c;或在代码中添加debugger;右键单机行号设置条件断点&#xff08;条件表达式为tr…

PowerShell install 一键部署mariadb10.11

mariadb MariaDB数据库管理系统是MySQL的一个分支&#xff0c;主要由开源社区在维护&#xff0c;采用GPL授权许可 MariaDB的目的是完全兼容MySQL&#xff0c;包括API和命令行&#xff0c;使之能轻松成为MySQL的代替品。在存储引擎方面&#xff0c;使用XtraDB来代替MySQL的Inno…

ChatGPT 国内镜像网站大全(含GPT-4.0版本)之什么年代还在写传统文章。

前言&#xff1a; 临近期末&#xff0c;大量水课的节课作业都是论文&#xff0c;一篇就是几千字&#xff0c;这对于还要复习专业课的我们可以说是压力巨大&#xff1a;心理健康论文&#xff0c;安全教育论文&#xff0c;大学语文论文&#xff0c;书法赏析论文&#xff0c;劳动…

小议C++函数签名与模板返回类型

题记&#xff1a;什么事情都要追问一个为什么&#xff0c;真正理解了为什么&#xff0c;才能活学活用。 代码1 下面的代码能编译通过吗&#xff1f; #include <stdio.h> #include <stdlib.h>class X { public:int *get() { return new int(); }double *get() { r…

MATLAB矩阵的分解函数与案例举例

系列文章目录 MATLAB当中线性方程组、不定方程组、奇异方程组、超定方程组的介绍 MATLAB语句实现方阵性质的验证 MATLAB绘图函数的相关介绍——海底测量、二维与三维图形绘制​​​​​​ MATLAB求函数极限的简单介绍 文章目录 前言 1. 奇异值分解&#xff08;SVD&#x…

C++类和对象-4

在上篇C类和对象的博客中&#xff0c;我们讲述了析构函数、拷贝构造函数、浅拷贝和深拷贝的内容&#xff0c;我们紧接上文&#xff0c;开始讲述接下来的文章。 目录 1.this指针 1.1引入 1.2内容 1.3特征 1.4用法 2.静态成员 2.1内容 2.2静态数据成员 2.3静态成员函数…

Vue.js 中的国际化支持是什么?如何进行国际化支持?

Vue.js 中的国际化支持是什么&#xff1f;如何进行国际化支持&#xff1f; Vue.js 是一款流行的前端框架&#xff0c;它提供了许多方便的工具和 API&#xff0c;用于构建交互式的用户界面。其中&#xff0c;国际化支持是 Vue.js 中重要的一部分&#xff0c;它可以让我们轻松地…

如何强制删除文件夹?这样操作就能搞定!

案例&#xff1a;我想删掉一些没有用的文件夹&#xff0c;释放一些电脑内存&#xff0c;但是我发现&#xff0c;有些文件夹并不能直接被删除。怎样才能删除这些文件夹&#xff1f;有没有小伙伴有解决的办法。 在使用电脑过程中&#xff0c;我们可能会遇到一些无法正常删除文件夹…

空间计算时代来临:苹果Vision Pro震撼上市,探索真实与虚拟的新边界

目录 前言Vision Pro的外观设计Vision Pro的交互方式Vision Pro 硬件配置Vision Pro 上市时间及销售价格Vision Pro与传统XR设备不同点总结其它资料下载 前言 苹果公司在2023年6月6日的WWDC23主题演讲中正式发布了传闻已久的头显产品——Vision Pro。WWDC&#xff0c;全称为“…

LLM Accelerator:使用参考文本无损加速大语言模型推理

编者按&#xff1a;如今&#xff0c;基础大模型正在诸多应用中发挥着日益重要的作用。大多数大语言模型的训练都是采取自回归的方式进行生成&#xff0c;虽然自回归模型生成的文本质量有所保证&#xff0c;但却导致了高昂的推理成本和长时间的延迟。由于大模型的参数量巨大、推…

被App包围 苹果Vision Pro将你推入空间“大屏”

2小时&#xff0c;这是2023年苹果开发者大会&#xff08;WWDC&#xff09;首日发布会的直播总时长&#xff0c;仅YouTube上&#xff0c;就有483.9万次观看。发布会开启时&#xff0c;北京时间是6月6日凌晨1点&#xff0c;众多科技博主串流直播了这场发布会。 苹果CEO蒂姆库克引…

3.2 继续完善的Vue.js响应式系统

前文提要&#xff1a; 3.0 响应式系统的设计与实现 3.1 一个稍微完善的Vue.js响应式系统 1、解决副作用函数的死循环问题 在解决了分支的切换的问题&#xff0c;此时还有一个代码死循环的问题&#xff0c;其这个死循环很容易触发&#xff0c;如下代码&#xff1a; const dat…

Netty Incubator Codec QUIC 0.0.41.Final 发布

导读Netty Incubator Codec QUIC 是一款基于 QUIC 协议的编解码器&#xff0c;为 Netty 提供了 QUIC 协议的支持。 近日&#xff0c;该团队发布了 0.0.41.Final 版本&#xff0c;这是一个错误修复版本&#xff0c;主要包括以下变化: 允许在派发前通过添加到读完队列来合并刷新…

嵌入式软件测试笔记3 | 嵌入式软件测试开发的多V模型

3 | 嵌入式软件测试开发的多V模型 1 简单的多V模型2 迭代与并行开发2.1 开发模型2.2 嵌入式开发过程的复杂性 3 多V模型中的测试活动3.1 测试活动和因素3.2 模型开发周期中与测试相关的元素分配3.3 原型开发周期中与测试相关的元素分配3.4 最终产品开发周期中与测试相关的元素分…

NineData x 华为云正式上线

6月5日&#xff0c;NineData 企业级 SQL 开发平台正式成为华为云“联营联运”商品。通过联营联运模式&#xff0c;双方将在产品、解决方案和生态等多个方面开展深度合作&#xff0c;共同提供高效、智能、安全的数据管理服务&#xff0c;帮助客户轻松构建一站式云端数据库管理平…

【随想录】一篇水文

前排许愿池: 我是一个没有梦想的咸鱼捏 自从知道成电优营了也不给offer之后 遂开始摆烂了(哈哈) 以及看了一下数据 好像前期存的资本够多的话 后面还是能混混的 however,已经快过去2/3了 前排致谢: 感谢好人一姐的助力 果然人是靠别人活着的 或者说伟人是站在巨人…

基于显扬科技3D视觉相机的芯片外观检测系统

Part.1 行业背景 电子元器件制造业是我国的支柱产业之一&#xff0c;具有产量大、技术投入高的特点&#xff0c;因此产品质量把控与生产成本优化是电子行业关注的发展重点。 芯片作为电子元器件中的核心组成部分&#xff0c;在现代社会被广泛应用&#xff0c;在芯片生产制造过…

Redis经典五大数据类型源码及底层实现

Redis经典五大数据类型源码及底层实现 一 面试题引入二 Redis数据类型的底层数据结构三 redis是字典数据库&#xff0c;KV键值对到底是什么&#xff1f;3.1 怎样实现键值对&#xff08;key-value&#xff09;数据库的&#xff1f;3.2 redisObject结构的作用3.3 RedisObject各字…

微信支付商户接入指引(企业)

目录 一、官方指引二、申请规则三、申请流程&#xff08;一&#xff09;提交资料&#xff08;二&#xff09;签署协议&#xff08;三&#xff09;绑定场景 一、官方指引 https://kf.qq.com/faq/210423UrIRB7210423by6fQn.html 二、申请规则 1、微信支付商家仅面向企业、个体…

三分钟告诉你录音实时转写软件哪个好

真的不想录音笔记实时转写软件有哪些吗 录音实时转写软件免费有哪些&#xff1f;录音实时转写软件推荐 实时录音转文字软件哪个好&#xff1f;录音实时转写软件分享 录音实时转写软件哪个好&#xff1f;录音实时转写软件盘点 让你知道视频配音文字转语音软件有哪些 让你不…