“深入浅出”系列之QT:(6)如何在一个项目中调用另一个项目

在Qt中,如果想在一个项目中调用另一个项目,这通常意味着想要在一个CMake构建的项目中集成或依赖另一个CMake构建的项目。

1‌.子模块或子目录方式‌:
如果另一个项目可以作为一个子模块或子目录包含在当前项目中,可以使用add_subdirectory命令在CMake中添加它。这样,子项目的CMake配置将作为父项目配置的一部分被处理。

# 在主CMakeLists.txt中                    

 add_subdirectory(path/to/your/subproject)                                

 确保子项目有自己的CMakeLists.txt文件,并且其构建系统是与主项目兼容的。

2‌.外部项目方式(使用ExternalProject)‌:
如果子项目是一个独立的外部项目,并且你不想或不能将其源代码直接包含在你的主项目中,你可以使用CMake的ExternalProject模块来下载、配置和构建外部项目。

# 首先,你可能需要包含ExternalProject模块

include(ExternalProject)

# 然后,定义外部项目

ExternalProject_Add( external_project_name

    DOWNLOAD_DIR ${CMAKE_BINARY_DIR}/external/project_name

    SOURCE_DIR ${CMAKE_BINARY_DIR}/external/project_name/src

    BINARY_DIR ${CMAKE_BINARY_DIR}/external/project_name/build

    CONFIGURE_COMMAND <configure_command>

    BUILD_COMMAND <build_command>

    INSTALL_COMMAND <install_command>

# ... 其他选项 )

这种方法允许你控制外部项目的下载、配置、构建和安装过程。

3‌.静态或动态链接库方式‌:
如果另一个项目已经编译成了一个静态库(.a文件)或动态库(.so.dll文件),你可以在你的主项目中链接这个库。你需要在CMake中指定库的路径和要链接的库文件。

# 指定库的路径 link_directories(/path/to/your/library)

# 链接库 target_link_libraries(your_target_name your_library_name)

确保库文件的路径在LD_LIBRARY_PATH环境变量中(对于Linux和macOS),或者在系统的动态链接库搜索路径中(对于Windows)。

4‌.使用Qt的qmake构建系统时的特殊处理‌:
如果你的主项目是使用Qt的qmake构建的,而不是CMake,那么你需要将另一个CMake项目的构建结果(如库文件)集成到qmake项目中。这通常涉及到在qmake的项目文件(.pro文件)中指定库文件的路径和名称。

# 在.pro文件中 LIBS += -L/path/to/your/library -lyour_library_name

对于CMake构建的子项目,你可能需要先单独构建它,然后将生成的库文件和其他必要的文件复制到主项目可以访问的位置。

在Qt和CMake的上下文中,最常见和推荐的方法是使用子目录方式(如果子项目可以很容易地包含在主项目中)或静态/动态链接库方式(如果子项目已经编译成了库)。这些方法提供了较好的集成度和灵活性。如果你选择使用ExternalProject方式,请注意它可能会增加构建的复杂性和时间,因为外部项目会在每次构建主项目时被下载和构建(除非你已经缓存了构建结果)。

要把一个项目编译成一个静态库(.a 文件)或动态库(.so.dll 文件),需要按照以下步骤:

1. 编写源代码

首先,确保项目源代码是组织良好的,并且有一个清晰的构建系统(如 CMake 或 Makefile)。

2. 配置构建系统

使用 CMake

如果使用了 CMake,在 CMakeLists.txt 文件中指定要生成的库类型。以下是一个简单的例子:

project(MyLibrary)# 设置项目名称

set(CMAKE_CXX_STANDARD 11) # 指定 C++ 标准

set(SOURCE_FILES src/file1.cpp src/file2.cpp)# 添加源文件

add_library(MyStaticLib STATIC ${SOURCE_FILES})# 添加一个静态库目标

# 或者添加一个动态库目标

# add_library(MyDynamicLib SHARED ${SOURCE_FILES})

在这个例子中,MyStaticLib 是静态库的目标名称,而 MyDynamicLib 是动态库的目标名称(注释掉了,因为通常只会选择其中一个)。${SOURCE_FILES} 包含了要编译的源文件列表。

使用 Makefile

如果使用 Makefile,需要编写规则来编译源文件并生成库文件。以下是一个简单的 Makefile 片段,用于生成静态库:

# 编译器和编译器标志

CXX = g++ CXXFLAGS = -std=c++11

# 源文件和对象文件

SRCS = src/file1.cpp src/file2.cpp OBJS = $(SRCS:.cpp=.o)

# 库文件名称

TARGET = libMyStaticLib.a

# 编译规则

all: $(TARGET) $(TARGET): $(OBJS) @echo "Creating static library $(TARGET)..." @ar rcs $(TARGET) $(OBJS) %.o: %.cpp @echo "Compiling $<..." @$(CXX) $(CXXFLAGS) -c $< -o $@

# 清理规则 clean: @echo "Cleaning up..." @rm -f $(OBJS) $(TARGET)

对于动态库,你需要将 TARGET 变量改为 libMyDynamicLib.so(Linux)或相应的 .dll 名称(Windows),并调整编译和链接规则以生成动态库。

3. 编译库

使用 CMake

在项目的根目录下运行以下命令:

mkdir build

cd build

cmake ..

make

这将创建一个 build 目录,并在其中生成静态库或动态库文件。

使用 Makefile

在项目的根目录下运行 make 命令:

make

这将根据 Makefile 中的规则编译源文件并生成库文件。

4. 使用库

一旦库文件生成,你可以在其他项目中使用它。对于静态库,你需要在编译时指定库文件的路径和名称,并使用 -L(指定库目录)和 -l(指定库名称,不包括前缀 lib 和文件扩展名)选项。对于动态库,你还需要确保库文件在运行时是可访问的,通常是通过设置 LD_LIBRARY_PATH 环境变量(Linux)或将库文件放在系统的动态链接库搜索路径中(Windows)。

注意事项

  • 确保你的源代码中没有 main 函数,因为库不应该包含入口点。
  • 对于动态库,你可能还需要处理平台特定的细节,比如导出符号(在 Windows 上使用 __declspec(dllexport))和导入符号(在 Windows 上使用 __declspec(dllimport))。
  • 在编写和使用库时,考虑库的 API 设计和文档,以便其他开发者能够轻松地使用你的库。

扩展:

1.动态链接库和静态链接库有什么区别

动态链接库(Dynamic Link Library, DLL)和静态链接库(Static Link Library)在程序编译和运行时的行为上有着显著的区别。以下是它们的主要区别:

  1. 链接时机‌:

    • 动态链接库:在程序运行时被加载和链接。这意味着程序在编译时并不包含这些库的代码,而是在运行时从外部文件中加载。
    • 静态链接库:在程序编译时就被完全集成到程序中。库代码在编译时就被复制到最终的可执行文件中。
  2. 文件大小和内存占用‌:

    • 动态链接库:使用动态链接库的程序通常具有更小的文件大小,因为库代码不包含在可执行文件中。但如果多个程序使用相同的库,这些程序可以共享内存中的同一份库副本,从而减少总体内存占用。
    • 静态链接库:会增加最终可执行文件的大小,因为每一个使用该库的程序都包含了一份完整的库代码副本。这可能导致更高的磁盘空间和内存占用,尤其是在多个程序使用相同库的情况下。
  3. 部署和更新‌:

    • 动态链接库:使得部署和更新变得更加简单。当库需要更新时,只需替换掉系统中的DLL文件,而不需要重新编译使用该库的每个程序。
    • 静态链接库:中的代码更新需要重新编译所有使用该库的程序。
  4. 兼容性和依赖问题‌:

    • 动态链接库:可能导致所谓的“DLL地狱”,即版本冲突和缺失问题,因为不同的程序可能依赖于同一DLL的不同版本。
    • 静态链接库:由于是编译到程序中的,不会有版本冲突的问题,但这也意味着更新库版本需要重新编译程序。
  5. 平台和语言限制‌:

    • 动态链接库:在不同的操作系统平台(如Windows的DLL和Linux的SO文件)和不同的编程语言间可能存在兼容性问题。
    • 静态链接库:通常与特定的编译器和平台紧密相关,可能在跨平台时遇到限制。
  6. 使用场景‌:

    • 动态链接库:更适用于需要频繁更新或者多个程序共享代码的情况。
    • 静态链接库:更适用于小型、独立的应用程序,或者对性能有特别要求的场合。

总的来说,动态链接库和静态链接库各有优劣,选择使用哪一种通常取决于应用程序的特定需求和部署环境。

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

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

相关文章

基于SpringBoot的洗浴管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

直流无刷电机控制(FOC):电流模式

目录 概述 1 系统框架结构 1.1 硬件模块介绍 1.2 硬件实物图 1.3 引脚接口定义 2 代码实现 2.1 软件架构 2.2 电流检测函数 3 电流环功能实现 3.1 代码实现 3.2 测试代码实现 4 测试 概述 本文主要介绍基于DengFOC的库函数&#xff0c;实现直流无刷电机控制&#x…

51单片机——串口通信(重点)

1、通信 通信的方式可以分为多种&#xff0c;按照数据传送方式可分为串行通信和并行通信&#xff1b; 按照通信的数据同步方式&#xff0c;可分为异步通信和同步通信&#xff1b; 按照数据的传输方向又可分为单工、半双工和全双工通信 1.1 通信速率 衡量通信性能的一个非常…

oracle位运算、左移右移、标签算法等

文章目录 位运算基础与或非同或同或应用场景 异或异或应用场景 什么是真值表 oracle基础函数创建bitor(按位或)函数bitnot(按位非)函数bitxor(按位异或)函数左移函数BITSHIFT()函数(实测不可用&#xff0c;废弃掉该方案)右移函数(略&#xff0c;有此场景吗?) 实际应用资质字典…

VS2015 + OpenCV + OnnxRuntime-Cpp + YOLOv8 部署

近期有个工作需求是进行 YOLOv8 模型的 C 部署&#xff0c;部署环境如下 系统&#xff1a;WindowsIDE&#xff1a;VS2015语言&#xff1a;COpenCV 4.5.0OnnxRuntime 1.15.1 0. 预训练模型保存为 .onnx 格式 假设已经有使用 ultralytics 库训练并保存为 .pt 格式的 YOLOv8 模型…

python无需验证码免登录12306抢票 --selenium(2)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 [TOC](python无需验证码免登录12306抢票 --selenium(2)) 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 就在刚刚我抢的票&#xff1a;2025年1月8日…

本地手集博客id“升级”在线抓取——简陋版——(2024年终总结1.1)

我之前每每发布笔记都用csv纯文本记录&#xff0c;一个机缘巧得文章列表api实现在线整理自已的文章阅读量数据。 (笔记模板由python脚本于2025年01月10日 18:48:25创建&#xff0c;本篇笔记适合喜欢钻牛角尖的coder翻阅) 【学习的细节是欢悦的历程】 Python官网&#xff1a;htt…

工业 4G 路由器赋能远程医疗,守护生命线

在医疗领域&#xff0c;尤其是偏远地区的医疗救治场景中&#xff0c;工业 4G 路由器正发挥着无可替代的关键作用&#xff0c;宛如一条坚韧的 “生命线”&#xff0c;为守护患者健康持续赋能。 偏远地区医疗资源相对匮乏&#xff0c;常常面临着专业医生短缺、诊疗设备有限等困境…

【python基础——异常BUG】

什么是异常(BUG) 检测到错误,py编译器无法继续执行,反而出现错误提示 如果遇到错误能继续执行,那么就捕获(try) 1.得到异常:try的执行,try内只可以捕获一个异常 2.预案执行:except后面的语句 3.传入异常:except … as uestcprint(uestc) 4.没有异常:else… 5.鉴定完毕,收尾的语…

Nginx入门笔记

Nginx入门笔记 一、Nginx基本概念二、代理1、正向代理2、反向代理 三、准备工作1、CentOS 7安装nginx&#xff08;1&#xff09;. 安装必要的依赖&#xff08;2&#xff09;下载nginx&#xff08;3&#xff09;编译安装&#xff08;4&#xff09;编译并安装 Nginx(5)启动nginx …

半导体数据分析: 玩转WM-811K Wafermap 数据集(一) AI 机器学习

在半导体行业&#xff0c;工程师依靠 CP Yield&#xff08;生产过程中芯片的合格率&#xff09;、WAT&#xff08;晶圆验收测试&#xff09;和 Particle 的晶圆图模式来识别工艺问题。然而&#xff0c;在没有人工干预的情况下将这些晶圆图模式分类是一项重大挑战。许多论文都研…

初学者关于对机器学习的理解

一、机器学习&#xff1a; 1、概念&#xff1a;是指从有限的观测数据中学习(或“猜 测”)出具有一般性的规律&#xff0c;并利用这些规律对未知数据进行预测的方法.机器学 习是人工智能的一个重要分支&#xff0c;并逐渐成为推动人工智能发展的关键因素。 2、使用机器学习模型…

GPU算力平台|在GPU算力平台部署Qwen-2通义千问大模型的教程

文章目录 一、GPU平台介绍算力平台概述 二、人工智能应用开发需要GPU算力平台GPU算力原理账号注册流程Qwen-2通义千问大模型的部署登录/注册选择SettingsURL配置选择模型部署完成进行问答 一、GPU平台介绍 算力平台概述 GPU算力平台是一个专注于GPU加速计算的专业云服务平台&…

Vue3(elementPlus) el-table替换/隐藏行箭头,点击整行展开

element文档链接&#xff1a; https://element-plus.org/zh-CN/component/form.html 一、el-table表格行展开关闭箭头替换成加减号 注&#xff1a;Vue3在样式中修改箭头图标无效&#xff0c;可能我设置不对&#xff0c;欢迎各位来交流指导 转变思路&#xff1a;隐藏箭头&…

【C++】C++11(二)

目录 九、可变参数模板十、lambda表达式10.1 C98中的一个例子10.2 lambda表达式10.3 lambda表达式语法10.3.1 lambda表达式各部分说明10.3.2 捕获列表说明 10.4 函数对象与lambda表达式 十一、包装器11.1 function包装器11.2 bind 十二、线程库12.1 线程12.1.1 thread类的简单介…

针对数据库系统安全的漏洞扫描加固工具【WebSocket + MySQL】

一、系统背景 随着信息技术的迅猛发展和互联网的普及&#xff0c;数据库作为存储、管理和检索大量数据的关键组件&#xff0c;其安全性对于企业和组织来说至关重要。然而&#xff0c;由于网络环境的复杂性和攻击手段的多样性&#xff0c;数据库面临着越来越多的安全威胁&#…

Photon最新版本PUN 2.29 PREE,在无网的局域网下,无法连接自己搭建的本地服务器

1.图1为官方解答 2.就是加上这一段段代码&#xff1a;PhotonNetwork.NetworkingClient.SerializationProtocol SerializationProtocol.GpBinaryV16; 完美解决 unity 商店最新PUN 2 插件 不能连接 &#xff08;环境为&#xff1a;本地局域网 无外网情况 &#xff09; …

贪心算法(五)

目录 一、单调递增的数字 二、坏了的计算器 三、合并区间 四、无重叠区间 五、用最少数量的箭引爆气球 一、单调递增的数字 单调递增的数字 贪心策略&#xff1a; 对于这道题&#xff0c;相邻数字相等&#xff0c;也表示是递增的。 解题代码&#xff1a; class Soluti…

数据结构——栈的实现

今天&#xff0c;我们来写一下关于栈的博文。 1.首先我们先了解一下什么是栈&#xff1f; 一&#xff1a;概念&#xff1a; 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶&#xff0c;另…

Vue进阶(贰幺贰)npm run build多环境编译

文章目录 一、前言二、实施三、总结&#xff1a;需要打包区分不同环境四、拓展阅读 一、前言 项目开发阶段&#xff0c;会涉及打包部署到多个环境应用场景&#xff0c;在不同环境中&#xff0c;需要进行项目层面的区分&#xff0c;做不同的操作&#xff0c;可以利用打包的--mo…