【CMake】学习笔记2

文章目录

  • 06.指定头文件路径
  • 07.通过CMake制作库文件
    • 制作动态库或静态库
      • 制作静态库
      • 制作动态库
      • 指定动态库/静态库输出的路径
  • 08.在程序中链接静态库
  • 09.在程序中链接动态库
  • 11. 在cmake中打印日志信息
  • 12.字符串操作
    • 使用set拼接
    • 使用list拼接
    • list字符串移除
    • list其他命令

06.指定头文件路径

在编译项目源文件的时候,很多时候都需要将源文件对应的头文件路径指定出来,这样才能保证在编译过程中编译器能够找到这些头文件,并顺利通过编译。在CMake 中设置要包含的目录也很简单,通过一个命令就可以搞定了,他就是 include_directories:

include_directories(headpath)

使用示例:

cmake_minimum_required(VERSION 3.0.0)
project(test)# 指定使用C++标准
set(CMAKE_CXX_STANDARD 11)
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)# 指定头文件路径
include_directories(${PROJECT_SOURCE_DIR}/include)
add_executable(app  ${INCLUDE} ${SRC})

注意:include_directories指定的路径,并不是某一个头文件

07.通过CMake制作库文件

制作动态库或静态库

有些时候我们编写的源代码并不需要将他们编译生成可执行程序,而是生成一些动态库或者静态库提供给第三方使用,下面来讲解cmake中生成这两类库文件的方法。

制作静态库

在cmake中,如果需要制作静态库,需要使用以下命令:

add_library(库名称 STATIC 源文件1 [源文件2] ...)

在Linux中,静态库名字分为三部分:lib+库名字+.a,此处只需要指定出库名就可以了,另外两部分在生成该文件的时候会自动填充。

在windows中虽然库名和Linux格式不同,但也只需要指定出名字即可。

接下来我们将之前写的add.cpp div.cpp mult.cpp sub.cpp放在src目录下并编译生成静态库。

cmake_minimum_required(VERSION 3.15)
project(test)# 指定使用C++标准
set(CMAKE_CXX_STANDARD 11)
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
include_directories(${PROJECT_SOURCE_DIR}/include)add_library(calc STATIC ${SRC})

制作动态库

cmake_minimum_required(VERSION 3.15)
project(test)# 指定使用C++标准
set(CMAKE_CXX_STANDARD 11)
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
include_directories(${PROJECT_SOURCE_DIR}/include)add_library(calc SHARED ${SRC})

动态库是有可执行权限的,静态库是没有可执行权限的

发布给使用者:必须提供一个头文件才能知道库里有什么函数可以被调用
1. 头文件
2. 生成的静态库/动态库

指定动态库/静态库输出的路径

由于在 Linux 下生成的静态库默认不具有可执行权限,所以在指定静态库生成的路径的时候就不能使用EXECUTABLE_OUTPUT_PATH (这个只适用动态库)宏了,而应该使用LIBRARY_OUTPUT_PATH这个宏对应静态库文件和动态库文件都适用

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR})

注意:如果改路径不存在生成库文件之前会被自动创建

08.在程序中链接静态库

在cmake中,链接静态库的命令如下:

link_libraries(<static lib> [<static lib>...])

参数1:指定要链接的静态库名字,可以是全名libxxx.a, 也可以是掐头(lib)去尾(.a)之后的名字 xxx
参数2-N:要链接的其它静态库名字

如果该静态库不是系统提供的(自己制作或者第三方提供的静态库)可能出现静态库找不到的情况,此时可以将静态库路径也指定出来:

link_directories(<lib_path>) # 可以包含多个路径

link_directories既可以指定静态库路径也可以指定动态库路径

cmake_minimum_required(VERSION 3.15)
project(test)# 指定使用C++标准
set(CMAKE_CXX_STANDARD 11)# 源文件main.cpp
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)# 头文件
include_directories(${PROJECT_SOURCE_DIR}/include)# 链接静态库文件
link_libraries(calc)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib1)# 生成可执行文件
add_executable(app ${SRC})

在生成可执行文件的时候,如果链接的是静态库,静态库会被打包到可执行程序中,如果是动态库,并不会被打包到可执行程序中

09.在程序中链接动态库

在程序编写过程中,除了在项目中引入静态库,好多时候也会使用一些标准的或者第三方提供的一些动态库

cmake连接动态库的命令如下:

target_link_libraries(<target><PRIVIATE|PUBLIC|INTERFACE> <item>...[<<PRIVIATE|PUBLIC|INTERFACE> <item>...>...]
)

target:指定要加载动态库文件的名字

  1. 该文件可能是一个源文件
  2. 该文件可能是一个动态库文件
  3. 该文件可能是一个可执行文件

PRIVIATE|PUBLIC|INTERFACE:动态库访问权限,默认为PUBLIC

1.如果各个动态库之间没有依赖关系,无需做任何设置,三者没有区别,一般无需指定,使用默认的PUBLIC即可
2. 动态库的链接具有传递性,如果动态库A链接了动态库B、C,动态库D链接了动态库A,此时动态库D相当于也链接了B,C,并且可以使用动态库B,C的方法。注意:此时B,C库的链接权限必须是PUBLIC,否则D无法链接B,C库。

target_link_libraries(A B C)
target_link_libraries(D A)

PUBLIC:在public后面的库会被Link到前面的target中,并且里面的符号(库中定义的函数)也会被导出,提供给第三方使用
PRIVATE:在private后面的库仅被link到前面的target中,并且终结掉,第三方不能感知你调用了啥库
INTERFACE:在interface后面引入的库不会被链接到前面的target中,只会导出符号。即target只会知道有某个函数,但是不知道函数的拥有者是哪个动态库。

在物理内存中,动态库有且仅有一份。
target_link_libraries一般都会写到CMakeLists.txt文件最后

cmake_minimum_required(VERSION 3.15)
project(test)# 指定使用C++标准
set(CMAKE_CXX_STANDARD 11)# 源文件main.cpp
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
include_directories(${PROJECT_SOURCE_DIR}/include)link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib2)
add_executable(app ${SRC})
target_link_libraries(app calc)

要将target_link_libraries放到最后

11. 在cmake中打印日志信息

在CMake中更可以用用户显示一条信息,该命令为message

message([STATUS|WARNING|AUTHOR_WARNING|SEND_ERROR|FATAL_ERROR] "message to display" ..)

(无):重要消息
STATUS:非重要消息
WARNING:CMake警告,会继续执行
AUTHOR_WARNING:CMake警告(dev),会继续执行
SEND_ERROR:CMake错误,继续执行,但是会跳过生成的步骤
FATAL_ERROR:CMake错误,终止所有处理过程
CMake的命令行工具会在stdout上显示STATUS消息,在stderr上显示其他所有消息。CMake的GUI会在它的log区域显示所有消息。
CMake警告和错误消息的文本显示使用的是一种简单的标记语言。文本没有缩进,超过长度会回卷,段落之间以新行作为分隔符。

# 输出一条日志信息
message(STATUS "source path: ${PROJECT_SOURCE_DIR}")
# 输出警告信息
message(WARNING "source path: ${PROJECT_SOURCE_DIR}")
# 输出错误信息
message(FATAL_ERROR "source path: ${PROJECT_SOURCE_DIR}")

12.字符串操作

有时候项目中的源文件并不一定都在同一个目录下,但是这些源文件最终要一起进行编译来生成最后的可执行文件或者库文件。如果我们通过file命令对各个目录下的源文件进行搜索,最后还需要做一个字符串拼接的操作,关于字符串拼接可以使用set命令或者list命令

使用set拼接

set(变量名1 ${变量名1} ${变量名2} ...)

例子:

set(tmp hello world)
message(${tmp}) # 输出:helloworld
set(temp1 ${tmp} ${SRC})
message(${tmp1}) # 输出: helloworld+SRC字符串

使用list拼接

使用list进行字符串拼接:

list(APPEND <list>[<element> ...])

示例:

list(APPEND tmp "xxx1" "xxx2")
message(${tmp})

list字符串移除

list(REMOVE_ITEM <list><value>[<value>...])

示例:

list(REMOVE_item SRC ${CMAKE_CURRENT_DIR}/src/main.cpp) # 删除SRC中的main.cpp

list其他命令

获取list长度

list(LENGTH <list> <output variable>)

注意:”output variable“是一个字符串,并不是整数

读取列表中指定索引的元素,可以用于指定多个索引

list(GET <list> <element index> [<element index>...] <output variable>)

list:当前操作的列表
element index: 列表元素索引

  1. 从0开始编号,索引0的元素为列表第一个元素
  2. 索引也可以是负数,-1表示列表最后一个元素,-2表示列表倒数第二个元素
  3. 当索引不管是正数还是负数的时候,超过列表长度,都会报错

output variable:新创建的变量,存储指定索引元素的返回结果,也是一个列表

本文参考:
https://www.bilibili.com/video/BV14s4y1g7Zj?p=13&spm_id_from=pageDriver&vd_source=cf0b4c9c919d381324e8f3466e714d7a

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

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

相关文章

vscode中使用官方推荐的编程字体Cascadia Code字体

字体样式 > 和 有特殊效果 很多字体都支持使用连字&#xff0c;Cascadia Code 、Jetbrains Mono 、Fira Code 等 安装Cascadia Code 下载完成后解压安装 选中右键安装&#xff0c;static文件里也一样安装 VS Code 中配置设置字体和连字设置 Cascadia Code, Consolas, Couri…

使用Java连接redis的方式

除了使用 Spring Data Redis&#xff0c;Java 连接 Redis 还可以通过以下几种方式&#xff1a; 1. Jedis Jedis 是一个流行的 Java Redis 客户端库&#xff0c;提供了简单的 API 来访问 Redis。 依赖&#xff1a; <dependency><groupId>redis.clients</grou…

Spring Boot集成Jythonb并且支持三方的python依赖包

上篇文章讲了 如何在java中执行python代码&#xff0c;这篇文章讲一下如何让jython支持三方依赖包 1.什么是Jython&#xff1f; Jython是Python编程语言的JVM实现。 它旨在在Java平台上运行。 Jython程序可以导入和使用任何Java类。 就像Java一样&#xff0c;Jython程序编译为…

SX_UNIX套接字通信_15

UNIX套接字通信的优势&#xff1a; UNIX套接字通信常用于一个项目中的进程之间通信&#xff0c;UNIX提供了与网络套接字相似的特性&#xff0c;但是避免了网络延迟&#xff0c;提高了性能&#xff0c;但是它只能在同一台机器上使用&#xff0c;无法跨越网络的进程间通信 实例&…

计算机的错误计算(六十七)

摘要 计算机的错误计算&#xff08;五十六&#xff09;与&#xff08;六十六&#xff09;分别探讨了大数与 附近数的正切函数值的错误计算。本节讨论第三种类型数值&#xff1a; 附近数 的正切函数的计算精度问题。 例1. 已知 计算 先用 Go语言计算&#xff1a; packag…

STL介绍以及string类

什么是STL 是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 STL的六大组件 为什么要学习string类 C语言中的字符串 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&am…

模具监视器的技术参数有哪些

模具监视器的技术参数涵盖了多个方面&#xff0c;这些参数对于确保模具监视器的性能、稳定性和检测精度至关重要。以下是一些主要的技术参数&#xff1a; 一、显示器参数 屏幕尺寸&#xff1a;常见的模具监视器显示器尺寸为12.5英寸至13.5英寸&#xff0c;具体尺寸可能因不同…

基于RabbitMQ的消息监听器

1. 背景 机构的新增、更新、删除在微服务A中已经完成了&#xff08;微服务A已经部署&#xff0c;不能修改代码&#xff09;&#xff0c;如果在微服务A中对机构进行新增、更新、删除操作后&#xff0c;需要同步到自己的微服务B中&#xff0c;这里采用MQ消息通知的方式实现。 微…

如何建立一个既能快速记录又易于回顾的笔记系统?

在快节奏的学习和工作中&#xff0c;能够快速记录和回顾信息变得尤为重要。尤其对于编程学习者来说&#xff0c;构建一个高效、有序的笔记系统不仅可以提高学习效率&#xff0c;还能帮助我们在未来轻松回溯知识要点。本文将详细探讨如何打造一个既快速记录又易于回顾的笔记系统…

打卡第48天------单调栈

今天正式开始单调栈&#xff0c;开启新的篇章了&#xff0c;那个动态规划真的太难了。不过卡尔总结的很全面&#xff0c;真的是收获不少呀。小坚持带来大改变。加油✊ 1. 每日温度 leetcode题目链接&#xff1a;739. 每日温度 题目描述&#xff1a; 给定一个整数数组 temperat…

使用EasyExcel填充Excel并上传至OSS

在企业级应用中&#xff0c;经常需要处理数据的导入导出功能。Excel作为最常用的数据交换格式之一&#xff0c;其自动化处理尤为重要。本文将介绍如何使用EasyExcel库来填充Excel模板&#xff0c;并将生成的文件上传到对象存储服务&#xff08;OSS&#xff09;。 EasyExcel简介…

Python 异步爬虫:高效数据抓取的现代武器

标题&#xff1a;“Python 异步爬虫&#xff1a;高效数据抓取的现代武器” 在当今信息爆炸的时代&#xff0c;网络爬虫已成为数据采集的重要工具。然而&#xff0c;传统的同步爬虫在处理大规模数据时往往效率低下。本文将深入探讨如何使用 Python 实现异步爬虫&#xff0c;以提…

HTTP?HTTPS?HTTP2.0

Http HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一种用于分布式、协作式、超媒体信息系统的应用层协议。它基于TCP/IP通信协议来传递数据&#xff0c;如HTML文件、图片文件等。以下是HTTP的详细解析&#xff1a; 一、HTTP的基本…

YAML在Spring Boot中的应用

1. 基本语法 YAML使用缩进来表示层级关系&#xff0c;通常使用空格进行缩进&#xff08;推荐使用2个空格&#xff09;。 基本语法示例&#xff1a; key: value nested:key: value list:- item1- item22. 配置文件命名 在Spring Boot中&#xff0c;YAML配置文件通常命名为 a…

手撕C++入门基础

1.C介绍 C课程包括&#xff1a;C语法、STL、高阶数据结构 C参考文档&#xff1a;Reference - C Reference C 参考手册 - cppreference.com cppreference.com C兼容之前学习的C语言 2.C的第一个程序 打印hello world #define _CRT_SECURE_NO_WARNINGS 1 // test.cpp // …

RDKit在数据科学中的应用|药物筛选中的数据清理与标准化

在化学信息学和药物研发的过程中,分子数据的质量至关重要。数据清理与标准化是确保分子库数据一致性、可靠性和可比较性的关键步骤。RDKit 提供了丰富的工具,帮助用户清理和标准化分子数据,从而提高下游分析和建模的准确性。 1 数据清理的重要性 分子数据通常来自多种来源…

获取操作系统的信息(Go语言)

在 Go 语言中&#xff0c;你可以使用 runtime 和 os 包来查看操作系统的信息。以下是一些常见的操作系统信息获取方法&#xff1a; 1. 获取操作系统类型和架构信息 Go 的 runtime 包提供了基本的操作系统和架构信息&#xff1a; package mainimport ("fmt""r…

c_cpp_properties.json、launch.json、 tasks.json

在 Visual Studio Code 中&#xff0c;c_cpp_properties.json、launch.json 和 tasks.json 是三个重要的配置文件&#xff0c;它们的作用如下&#xff1a; c_cpp_properties.json&#xff1a; 这个文件用于配置 C/C 扩展的 IntelliSense、编译器路径和包括路径等。它帮助 VS Co…

Unity Dots学习 (一)

先学习怎么使用&#xff0c;再研究底层代码。Dots大家都有所耳闻。一直没时间研究&#xff0c;最近研究一下 看上图可知&#xff0c;哪怕是CPU的第三级缓存也比内存要快2-5倍。 资料&#xff1a; 《DOTS之路》第零节——前导课(1)——DOTS的5W1H问题_哔哩哔哩_bilibili 《DOT…

快速搭建全向轮小车

总体介绍 使用两块ordive控制ros-mobile app进行控制&#xff0c;odrive通过python可以轻松控制&#xff0c;ros-mobile可以进行与电脑的ros连接充当一个遥控器。 记录代码 读取rosmobile的遥控数据 #!/usr/bin/env python3import threading import time from queue import…