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

news2025/1/10 4:01:52

在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.coloradmin.cn/o/2274137.html

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

相关文章

SpringcloudAlibaba黑马笔记(部分)

第一章 微服务介绍 1.1 系统架构演变 随着互联网的发展&#xff0c;网站应用的规模也在不断的扩大&#xff0c;进而导致系统架构也在不断的进行变化。 从互联网早起到现在&#xff0c;系统架构大体经历了下面几个过程 : 单体应用架构 ---> 垂直应用架构 ---> 分布 …

Redis 基础篇

一、redis 概念及特性 1.1 Redis 概念 Redis&#xff08;Remote Dictionary Server&#xff09;&#xff0c;即远程字典服务&#xff0c;是一个开源的高性能键值存储数据库&#xff0c;可以用作数据库、缓存和消息中间件。 redis 官网&#xff1a;Redis - The Real-time Data P…

DAY15 神经网络的参数和变量

DAY15 神经网络的参数和变量 一、参数和变量 在神经网络中&#xff0c;参数和变量是两个关键概念&#xff0c;它们分别指代不同类型的数据和设置。 参数&#xff08;Parameters&#xff09; 定义&#xff1a;参数是指在训练过程中学习到的模型内部变量&#xff0c;这些变量…

[离线数仓] 总结二、Hive数仓分层开发

接 [离线数仓] 总结一、数据采集 5.8 数仓开发之ODS层 ODS层的设计要点如下: (1)ODS层的表结构设计依托于从业务系统同步过来的数据结构。 (2)ODS层要保存全部历史数据,故其压缩格式应选择压缩比率,较高的,此处选择gzip。 CompressedStorage - Apache Hive - Apac…

Chromium源码windows下载和编译

官方地址&#xff1a;chromium/docs/windows_build_instructions.md at main chromium/chromium GitHub Chromium介绍 Chromium 是一个开源浏览器项目&#xff0c;旨在为所有用户构建更安全、更快、更稳定的网络体验方式。掌握Chromium的编译和开发是浏览器项目相关的开发者…

maven如何从外部导包

1.找到你项目的文件位置&#xff0c;将外部要导入的包复制粘贴进你当前要导入的项目下。 2.从你的项目目录下选中要导入的包的pom文件即可导包成功 注意一定是选中对应的pom文件 导入成功之后对应的pom.xml文件就会被点亮

力扣 跳跃游戏

每次更新目标位置时&#xff0c;实际上是在做一个局部的最优选择&#xff0c;选择跳跃能够到达当前目标位置的最远位置。因为每次更新目标位置时&#xff0c;都是基于当前能跳跃到的最远位置&#xff0c;因此最终的结果是全局最优的。 题目 从前往后遍历&#xff0c;更新可以到…

第二十八周学习周报

目录 摘要Abstract1 GFPGAN1.1 总体结构1.2 实验研究1.3 代码分析 总结 摘要 本周主要的学习内容是GFPGAN模型。GFPGAN是一种基于生成对抗网络(GAN)的模型&#xff0c;其利用封装在预训练的人脸GAN中的丰富多样的先验进行人脸图像的修复。这种生成面部先验&#xff08;GFP&…

成为LabVIEW自由开发者

成为LabVIEW自由开发者的体验可以非常丰富且具有挑战性&#xff0c;同时也充满了自我成长和多样化项目的机会。 ​ 1. 高度的灵活性与自由度 工作时间与地点&#xff1a;作为自由开发者&#xff0c;你可以自由选择工作时间和地点。你可以在家工作&#xff0c;也可以选择在咖啡…

Electron快速入门——跨平台桌面端应用开发框架

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

SpringBoot之核心配置

学习目标&#xff1a; 1.熟悉Spring Boot全局配置文件的使用 2.掌握Spring Boot配置文件属性值注入 3.熟悉Spring Boot自定义配置 4.掌握Profile多环境配置 5.了解随机值设置以及参数间引用 1.全局配置文件 Spring Boot使用 application.properties 或者application.yaml 的文…

openai swarm agent框架源码详解及应用案例实战

文章目录 简介数据类型Agent类Response类Result类Swarm类run_demo_loop交互式会话 基础应用agent-handsofffunction-callingcontext_variablestriage_agent 高阶应用通用客服机器人(support bot)构建航班服务agent 参考资料 openai 在24年10月份开源了一个教育性质的多agents协…

JVM vs JDK vs JRE

JVM是Java虚拟机的缩写&#xff0c; 用于实现Java的一次编译&#xff0c;处处运行。 Java代码写成.class后&#xff0c;由本地的虚拟机运行。 JDK&#xff08;Java Development Kit&#xff09;是一个功能齐全的 Java 开发工具包&#xff0c;供开发者使用。 JDK包含了JRE。…

【网页自动化】篡改猴入门教程

安装篡改猴 打开浏览器扩展商店&#xff08;Edge、Chrome、Firefox 等&#xff09;。搜索 Tampermonkey 并安装。 如图安装后&#xff0c;浏览器右上角会显示一个带有猴子图标的按钮。 创建用户脚本 已进入篡改猴管理面板点击创建 脚本注释说明 name&#xff1a;脚本名称。…

微信小程序用的SSL证书有什么要求吗?

微信小程序主要建立在手机端使用&#xff0c;然而手机又涉及到各种系统及版本&#xff0c;所以对SSL证书也有要求&#xff0c;如果要小程序可以安全有效的访问需要满足以下要求&#xff1a; 1、原厂SSL证书&#xff08;原厂封&#xff09;。 2、DV单域名或者DV通配符。 3、兼…

【电子通识】PWM驱动让有刷直流电机恒流工作

电机的典型驱动方法包括电压驱动、电流驱动以及PWM驱动。本文将介绍采用PWM驱动方式的恒流工作。 首先介绍的是什么是PWM驱动的电机恒流工作&#xff0c;其次是PWM驱动电机恒流工作时电路的工作原理。 PWM驱动 当以恒定的电流驱动电机时&#xff0c;电机会怎样工作呢&#xff1…

Unity学习之UGUI进阶

一、事件监听接口 1、作用 用于实现类型长按、双击、拖拽等基础控件无法实现的功能 所有控件都能够添加更多的事件监听来处理对应的逻辑 2、事件监听接口类型 &#xff08;1&#xff09;常用事件接口 &#xff08;2&#xff09;不常用事件接口 3、使用事件监听接口 &#…

电脑硬盘系统迁移及问题处理

一、系统迁移准备 1、确认你的电脑主板是否支持安装两块硬盘,如电脑主板有多个M2硬盘接口,我们将新硬盘安装到主板上,原来的老硬盘安装在第二个接口上,主板只有一个M2接口的话可以使用移动硬盘盒。 2、新硬盘安装好后,我们进入原来的系统,在 此电脑–右键–管理–磁盘管…

【NLP高频面题 - Transformer篇】Transformer的输入中为什么要添加位置编码?

Transformer的输入中为什么要添加位置编码&#xff1f; 重要性&#xff1a;★★★ Transformer 将句子中的所有词并行地输入到神经网络中。并行输入有助于缩短训练时间&#xff0c;同时有利于学习长期依赖。不过&#xff0c;并行地将词送入 Transformer&#xff0c;却不保留词…

http range 下载大文件分片

摘自&#xff1a;https://www.jianshu.com/p/32c16103715a 上传分片下载也能分 HTTP 协议范围请求允许服务器只发送 HTTP 消息的一部分到客户端。范围请求在传送大的媒体文件&#xff0c;或者与文件下载的断点续传功能搭配使用时非常有用。 检测服务器端是否支持范围请求 假…