CMake教程6:调用lib、dll

之前我们学到了如何编写一个可执行程序和Library,在继续学习之前,需要解释下target,在cmake中我们可以给executablelibrary设置一个target名字,这样可以方便我们在后续对target进行更加详细的属性设置。

本节我们将学习如何在项目中引用lib,相关的api有:

 

makefile

复制代码

link_libraries(<item>... ...) # item链接到所有目标中 target_link_libraries(<target> ... <item>... ...) # 将item链接到指定的target中

其中item参数支持的情况比较多,提前介绍几种情况:

  • lib name:提供库的名字,让cmake去查找对应的库文件绝对路径
  • lib fullpath:直接一步到位给出库文件的绝对路径
  • target name: 根据target的属性,让cmake查找对应库文件的绝对路径

target_xxx的命令颗粒度更细,是比较高版本的命令。

app调用有源代码的lib

这种情况是有lib的源代码,我们将lib以源代码的方式链接到项目内

项目结构为:

  • main.cpp
  • lib.cpp
  • CMakeLists.txt
 

makefile

复制代码

# app cmake_minimum_required(VERSION 3.0.0) set(app "demo") project(${app} VERSION 0.1.0) add_executable(${app} main.cpp) # lib set(lib "my-lib") project(${lib}) add_library(${lib} ./lib.cpp) # 将lib链接到app target_link_libraries(${app} ${lib})

需要注意的target_link_libraries

  • 第一个target参数来自add_executable的第一个参数
  • 后续item参数来自add_library的第一个参数

app调用第三方lib、dll

这种情况是我们使用第三方的lib,只有头文件和库文件(.a、.dll、*.so

方式1:imported-libraries

 

bash

复制代码

# 设置target名字为dll,并且是一个外部导入的lib # GLOBAL选项可以将target的作用域变为全局,默认是只在目录内可见 add_library(dll SHARED IMPORTED GLOBAL) # 设置target dll的详细属性,dll/lib 不区分debug/release的情况 set_target_properties(dll PROPERTIES # 指向lib,windows必须设置此项 IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/dll.lib # 指向dll、so等 IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/dll.dll ) # 设置debug/release set_target_properties(dll PROPERTIES IMPORTED_IMPLIB_DEBUG ${CMAKE_CURRENT_LIST_DIR}/dll_debug.lib IMPORTED_IMPLIB_RELEASE ${CMAKE_CURRENT_LIST_DIR}/dll_release.lib IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_LIST_DIR}/dll_debug.dll IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_LIST_DIR}/dll_release.dll ) target_link_libraries(app dll)

这里我们使用的是set_target_properties,可以同时给多个target设置多个不同的属性:

 

scss

复制代码

set_target_properties( target1 target2 ... PROPERTIES prop1 value1 prop2 value2 ... )

方式2:将指定的库文件直接链接到target的不同配置

 

bash

复制代码

target_link_libraries(${target} debug ${debug_fullpath}) target_link_libraries(${target} optimized ${release_fullpath})

这两种方式都可以,原因是target_link_libraries的item参数既可以是target name,也可以是lib fullpath

在xcode中,对应的工程配置为:

  • 当为target name时,出现在command的args中

    image.png

  • 当为lib fullpath时,在xcode中的位置在Linking/Others Linker Flags:

    image.png

无论使用哪种方式,注意dll、lib必须是存在的,底层查找lib时,不会自动补充lib前缀。

include头文件目录问题

以上仅仅是告诉编译器lib文件的位置在哪里,我们需要添加头文件目录,编译器才能识别到lib api

方式1:直接添加头文件目录,缺点是要手动把使用到的lib include path一个一个加进去,比较麻烦

 

bash

复制代码

# 注意:要放在add_executable、add_library前边才有效 include_directories("a/b/c/")

方式2:给lib target中添加,只要项目依赖了这个target,就会自动将目录添加到项目中

 

makefile

复制代码

# 注意:要放在add_library后边才有效 target_include_directories(lib INTERFACE # 权限控制,类比:public/private/protected ${CMAKE_CURRENT_SOURCE_DIR}/ )

方式3:和方式2没啥区别,写法不同而已

 

makefile

复制代码

set_property(TARGET lib PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR} )

推荐使用第2种方式。

lib包含目录问题

这种情况对应的是我们target_link_libraries的item参数是lib name,为了让CMake可以通过lib name找到对应的lib文件 ,所以我们才需要设置库包含目录,如果item参数是lib pathtarget name,则不需要设置库包含目录。

相关的命令有link_directoriestarget_link_directories,区别参考上文。

作者:xu__yanfeng
链接:https://juejin.cn/post/7157618014311940126
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

相关文章

mysql 03.查询(重点)

先准备测试数据&#xff0c;代码如下&#xff1a; -- 创建数据库 DROP DATABASE IF EXISTS mydb; CREATE DATABASE mydb; USE mydb;-- 创建student表 CREATE TABLE student (sid CHAR(6),sname VARCHAR(50),age INT,gender VARCHAR(50) DEFAULT male );-- 向student表插入数据…

【黑产攻防道02】如何对抗黑产的图像识别模型

全文8799字&#xff0c;预计阅读时间约25分钟&#xff0c;建议收藏后阅读 验证码本质上自带一层答案的语义&#xff0c;这是天然的区分人和自动程序的地方。无论使用哪一种方式破解验证码&#xff0c;都必须识别出答案。 在多年与黑产破解者的博弈对抗的过程中&#xff0c;我…

zabbix整合prometheus的数据

1 zabbix安装 官方文档参考 https://www.zabbix.com/download?zabbix6.0&os_distributioncentos&os_version7&componentsproxy&dbmysql&ws https://www.zabbix.com/download?zabbix4.0&os_distributioncentos&os_version7&componentsserver…

Jmeter 连接 MySQL 数据库脚本

1、创建线程组 2、创建 JDBC Connection Configuration 3、创建 JDBC Request 4、最终创建的目录 5、重点来了 5.1 在百度中下载个 MySQL-connector-Java-8.0.28.jar&#xff0c;放在 jmeter 的 bin 目录下 5.2 在测试计划中&#xff0c;将 jar 包添加到脚本中 5.3 输入参…

[Docker精进篇] Docker镜像构建和实践 (三)

前言&#xff1a; Docker镜像构建的作用是将应用程序及其依赖打包到一个可移植、自包含的镜像中&#xff0c;以便在不同环境中快速、可靠地部署和运行应用程序。 文章目录 Docker镜像构建1️⃣是什么&#xff1f;2️⃣为什么&#xff1f;3️⃣镜像构建一、用现有容器构建新镜像…

网络通信原理TCP字段解析(第四十七课)

字段含义Source Port(源端口号)源端口,标识哪

opencv实战项目-停车位计数

手势识别系列文章目录 手势识别是一种人机交互技术&#xff0c;通过识别人的手势动作&#xff0c;从而实现对计算机、智能手机、智能电视等设备的操作和控制。 1. opencv实现手部追踪&#xff08;定位手部关键点&#xff09; 2.opencv实战项目 实现手势跟踪并返回位置信息&a…

Wlan安全——认证与加密方式(WPA/WPA2)

目录 终端认证技术 WEP认证 PSK认证 802.1x认证与MAC认证 Portal认证 数据加密技术 WEP加密 TKIP加密 CCMP加密 TKIP和CCMP生成密钥所需要的密钥信息 802.11安全标准 WEP共享密钥认证、加密工作原理 WEP共享密钥认证 WEP加解密过程 PSK认证以及生成动态密钥的工…

NLP文本匹配任务Text Matching [无监督训练]:SimCSE、ESimCSE、DiffCSE 项目实践

NLP文本匹配任务Text Matching [无监督训练]&#xff1a;SimCSE、ESimCSE、DiffCSE 项目实践 文本匹配多用于计算两个文本之间的相似度&#xff0c;该示例会基于 ESimCSE 实现一个无监督的文本匹配模型的训练流程。文本匹配多用于计算两段「自然文本」之间的「相似度」。 例如…

基于docker实现主从复制

1&#xff1a;实现主从复制这个过程我是趟过坑的&#xff0c;后面是自己动手搞了几遍都成功了以后才开始决定记录的&#xff0c;&#xff08;所以有的截图和上下文对不上的&#xff0c;比如说docker容器的名字对应不上&#xff0c;大家就用自己的就好&#xff09;&#xff0c;打…

LeetCode 141.环形链表

文章目录 &#x1f4a1;题目分析&#x1f4a1;解题思路&#x1f514;接口源码&#x1f4a1;深度思考❓思考1❓思考2 题目链接&#x1f449; LeetCode 141.环形链表&#x1f448; &#x1f4a1;题目分析 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中…

antd5源码调试环境启动(MacOS)

将源码下载至本地 这里antd5 版本是5.8.3 $ git clone gitgithub.com:ant-design/ant-design.git $ cd ant-design $ npm install $ npm start前提&#xff1a;安装python3、node版本18.14.0(这是本人当前下载的版本&#xff09; python3安装教程可参考&#xff1a;https://…