cmake多模块架构, DLL依赖编译

news2024/11/16 11:29:50

整体结构:
在这里插入图片描述

最外层的cmakelist

CMakeLists.txt

project(cmakeMulPackage)
cmake_minimum_required(VERSION 3.17)
set(CMAKE_CXX_STANDARD 11)

#设置环境相关
message("====================set env.cmake===================")
message("CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}")
set(PROJECT_LIBRARY_DIR ${PROJECT_SOURCE_DIR}/Library)
set(PROJECT_LIBRARY_INCLUDE_DIR ${PROJECT_LIBRARY_DIR}/${CMAKE_BUILD_TYPE}/include)
set(PROJECT_LIBRARY_LIB_DIR ${PROJECT_LIBRARY_DIR}/${CMAKE_BUILD_TYPE}/lib)
set(PROJECT_LIBRARY_DLL_DIR ${PROJECT_LIBRARY_DIR}/${CMAKE_BUILD_TYPE}/dll)
message("PROJECT_LIBRARY_DIR is ${PROJECT_LIBRARY_DIR}")
message("PROJECT_LIBRARY_INCLUDE_DIR is ${PROJECT_LIBRARY_INCLUDE_DIR}")
message("PROJECT_LIBRARY_LIB_DIR is ${PROJECT_LIBRARY_LIB_DIR}")
message("PROJECT_LIBRARY_DLL_DIR is ${PROJECT_LIBRARY_DLL_DIR}")

#同时生成lib与DLL
message("PROJECT_BINARY_DIR is ${PROJECT_BINARY_DIR}")
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) #DLL生成路径
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) #lib生成路径
set(CMAKE_PDB_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) #pdb生成路径

# 处理编译字符集问题
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")

#设置QT相关配置
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_PREFIX_PATH D:/Library/Qt5.14.2/5.14.2/msvc2017_64/lib/cmake) # 配置QT路径
find_package(Qt5 COMPONENTS # 查找QT的模块
        Core
        Gui
        Widgets
        REQUIRED)
message(STATUS "CMAKE_PREFIX_PATH is ${CMAKE_PREFIX_PATH}")

message("====================set include path.cmake===================")
#定义头文件需要寻址的路径
include_directories(
        ${PROJECT_LIBRARY_INCLUDE_DIR} #头文件
        App/include #模块头文件
        AppModuleA/include #模块头文件
        AppModuleB/include #模块头文件
)
#定义库文件需要寻址的路径
link_directories(
        ${PROJECT_LIBRARY_LIB_DIR}
)

message("====================set sub directory.cmake===================")
#添加一个子目录并构建该子目录
add_subdirectory(AppModuleA)
add_subdirectory(AppModuleB)
add_subdirectory(App)



主程序

CMakeLists.txt

#定义头文件路径
include_directories(./include)

#把目录src和inc下面的所有文件作为变量存储
file(GLOB_RECURSE SRC_FILES "src/*")
file(GLOB_RECURSE INC_FILES "include/*")

# 针对存在Q_OBJECT宏的文件,需要MOC,则把其他模块的.h文件加进来了
set(MOC_FILES
        ${PROJECT_SOURCE_DIR}/AppModuleB/include/module_b.h
)

#生成可执行exe
add_executable(cmakeMulPackage ${SRC_FILES} ${INC_FILES} ${MOC_FILES})

#加载依赖的库
target_link_libraries(cmakeMulPackage
    AppModuleA
    AppModuleB
)

#将生成的依赖复制到可执行目录下
message("====================set copy final.cmake===================")
file(GLOB_RECURSE MY_COMPONENTS "${PROJECT_LIBRARY_DLL_DIR}/*")
if (WIN32 AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
    #拷贝依赖的DLL和exe
    foreach (MY_COMPONENT ${MY_COMPONENTS})
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${MY_COMPONENT}" "${PROJECT_BINARY_DIR}")
        message(STATUS "COPY DLL ${MY_COMPONENT}")
    endforeach (MY_COMPONENT)
endif ()

main_app.h

//
// Created by zhe.xiao on 2023/12/15.
//

#pragma once
#include <iostream>

class MainApp
{
public:
    static void run();
};

main_app.cpp

//
// Created by zhe.xiao on 2023/12/15.
//

#include "main_app.h"
#include "module_a.h"
#include "module_b.h"

void MainApp::run()
{
    std::cout << "hello main" << "\n";
    ModuleA::run();

    auto moduleA = new ModuleB();
    moduleA->start();

    auto tModule = new ModuleB();
    tModule->start();

    std::this_thread::sleep_for(std::chrono::seconds(10));
}


main.cpp

#include "main_app.h"

int main() {
    MainApp::run();

    return 0;
}

AppModuleA 子模块

CMakeLists.txt

#定义头文件路径
include_directories(./include)

#把目录src和inc下面的所有文件作为变量存储
file(GLOB_RECURSE SRC_FILES "src/*")
file(GLOB_RECURSE INC_FILES "include/*")

#生成库
add_library(AppModuleA SHARED ${SRC_FILES} ${INC_FILES})

module_a.h

//
// Created by zhe.xiao on 2023/12/15.
//

#pragma once


class ModuleA
{
public:
    static void run();
};

module_a.cpp

//
// Created by zhe.xiao on 2023/12/15.
//

#include "module_a.h"
#include <iostream>

void ModuleA::run()
{
    std::cout << "ModuleA run" << "\n";
}


AppModuleB 子模块

CMakeLists.txt

#定义头文件路径
include_directories(./include)

#把目录src和inc下面的所有文件作为变量存储
file(GLOB_RECURSE SRC_FILES "src/*")
file(GLOB_RECURSE INC_FILES "include/*")

#生成库
add_library(AppModuleB SHARED ${SRC_FILES} ${INC_FILES})

#添加依赖库
target_link_libraries(AppModuleB Qt5::Core)

module_b.h

//
// Created by zhe.xiao on 2023/12/15.
//

#pragma once

#include <QThread>

class ModuleB: public QThread
{
    Q_OBJECT

public:
    ModuleB(QObject* parent = nullptr);

    ~ModuleB();

protected:
    void run();
};



module_b.cpp

//
// Created by zhe.xiao on 2023/12/15.
//

#include "module_b.h"
#include <iostream>
#include <QString>

ModuleB::ModuleB(QObject* parent) : QThread(parent)
{

}

ModuleB::~ModuleB()
{

}

void ModuleB::run()
{
    std::cout << "ModuleB run" << "\n";

    QString data("QString data");
    std::cout << data.toStdString() << "\n";
}

三方依赖的DLL和头文件

主要通过设置环境变量定义具体路径。
在这里插入图片描述

然后通过add_custom_command进行拷贝dll到生成路径

message("====================set copy final.cmake===================")
file(GLOB_RECURSE MY_COMPONENTS "${PROJECT_LIBRARY_DLL_DIR}/*")
if (WIN32 AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
    #拷贝依赖的DLL和exe
    foreach (MY_COMPONENT ${MY_COMPONENTS})
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${MY_COMPONENT}" "${PROJECT_BINARY_DIR}")
        message(STATUS "COPY DLL ${MY_COMPONENT}")
    endforeach (MY_COMPONENT)
endif ()

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

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

相关文章

TG-5510cb: txo高稳定性+105℃高温

TG-5510CB是一款高稳定性TCXO&#xff0c;可提供CMOS或限幅正弦输出&#xff0c;5G基站和边缘计算的额定温度为85C&#xff0c;需要室外安装、小型化和无风扇运行。与其他TCXO相比&#xff0c;实验室提供了许多改进&#xff0c;如低温度斜率和相位噪声。符合GR-1244-CORE地层3和…

详细教程 - 从零开发 Vue 鸿蒙harmonyOS应用 第一节

关于使用Vue开发鸿蒙应用的教程,我这篇之前的博客还不够完整和详细。那么这次我会尝试写一个更加完整和逐步的指南,从环境准备,到目录结构,再到关键代码讲解,以及调试和发布等,希望可以让大家详实地掌握这个过程。 一、准备工作 下载安装 DevEco Studio 下载地址&#xff1a;…

AD20-Excel创建IC类元件库

目录 准备模板AD操作 准备模板 AD操作 结果生成如下&#xff1a; over&#xff01;&#xff01;&#xff01;

【教学类-06-18】20231216 (按“列”正序题)X-Y之间“加法题+题”(1页最多0-13。不考虑空格补全)

作品展示&#xff1a;按列排序&#xff0c;从小到大正序&#xff08;有空格&#xff09; 背景需求&#xff1a; 55格模板&#xff0c;很多幼儿都是按照“列”的方式&#xff0c;从上到下&#xff0c;从左向右完成题目的。 视觉上&#xff0c;两列之间间距大&#xff08;给孩子…

labelme标注json文件检查标注标签(修改imageWidth,imagePath,imageHeight)

# !/usr/bin/env python # -*- encoding: utf-8 -*- #---wzhimport os import json# 这里写你自己的存放照片和json文件的路径 json_dir =rC:\Users\Lenovo\Desktop\json3 json_files = os.listdir(json_dir

广西开放大学形成性考核 平时作业 统一资料 参考

试卷代号&#xff1a;1293 心理学 参考试题 一、选择题&#xff08;每个3分&#xff0c;共30分&#xff0c;含单选和多选&#xff0c;请将正确答案的字母序号填入括号中&#xff09; 1.人们通常把下列图形知觉为一个连续、完整的形状&#xff0c;说明图形知觉遵循( )。…

(第61天)多租户架构(CDB/PDB)

背景介绍 Oracle 的 CDB 和 PDB 是 Oracle 12C 及以上版本中引入的新概念,用于管理多租户数据库环境。 Oracle 数据库是商业数据库领域中的翘楚,其强大的功能和高可靠性备受企业用户追捧。而随着云计算和大数据时代的到来,Oracle 也不断推出新的技术以适应这些变化。CDB 技…

关于自动化用例设计的思考!

为什么要设计用例&#xff1f; 作为质量保证(QA)人员&#xff0c;设计测试用例的重要性不亚于开发人员编写技术实现方案。如果实现方案设计不周&#xff0c;编码阶段将可能遇到许多问题&#xff1b;同理&#xff0c;如果我们未能设计测试用例&#xff0c;产品质量就难以得到充…

在thinkphp5.1 自定义验证规则 获取get 传递的值的时候 传递了 值 能够获取到 验证出错

控制器: public function teamDetail(){if(request()->isGet()){$team_id $this->request->get(team_id, );$this->validate->scene(teamDetail)->check($team_id);if ($this->validate->getError()) {return resultArray(lang(strval($this->vali…

基于ssm金旗帜文化培训学校网站的设计与开发论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对培训学校展示信息管理混乱&#xff0c;出错率高&#xff0c;信息安全…

SpringBoot Starter机制(自定义Start案例,实际开发场景中的短信模拟,AOP实现日志打印)

前言&#xff1a; 在我们上一篇博客中&#xff0c;实现Freemarke的增删改查&#xff0c;今天分享的是关于SpringBoot Starter机制-- 1.SpringBoot Starter 1.1.什么是SpringBoot Starter SpringBoot中的starter是一种非常重要的机制(自动化配置)&#xff0c;能够抛弃以前繁杂…

Spring MVC开发流程

1.Spring MVC环境基本配置 Maven工程依赖spring-webmvc <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.9.RELEASE</version> </dependency>web.xml配置Dispatche…

ubuntu安装详细步骤

一&#xff0c;先下载vmware 1&#xff0c;第一步打开上面链接 下载网址 : https://www.vmware.com/products/workstation-pro/wo rkstation-pro-evaluation.html 许可证 JU090-6039P-08409-8J0QH-2YR7F ZF3R0-FHED2-M80TY-8QYGC-NPKYF FC7D0-D1YDL-M8DXZ-CYPZE-P2AY6 ZC3T…

【数据结构第 6 章 ④】- 用 C 语言实现图的深度优先搜索遍历和广度优先搜索遍历

目录 一、深度优先搜索 1.1 - 深度优先搜索遍历的过程 1.2 - 深度优先搜索遍历的算法实现 二、广度优先搜索 2.1 - 广度优先搜索遍历的过程 2.2 - 广度优先搜索遍历的算法实现 和树的遍历类似&#xff0c;图的遍历也是从图中某一顶点出发&#xff0c;按照某种方法对图中所…

6.23删除二叉搜索树中的节点(LC450-M)

算法&#xff1a; 一共有五种可能的情况&#xff1a; 第一种情况&#xff1a;没找到删除的节点&#xff0c;遍历到空节点直接返回了找到删除的节点 第二种情况&#xff1a;左右孩子都为空&#xff08;叶子节点&#xff09;&#xff0c;直接删除节点&#xff0c; 返回NULL为根…

鸿蒙4.0开发 - DevEco Studio如何使用Previewer窗口预览器报错

DevEco Studio预览器概况在HarmonyOS应用开发过程中&#xff0c;通过使用预览器&#xff0c;可以查看应用的UI效果&#xff0c;方便开发者实时查看应用的运行效果&#xff0c;随时调整代码。 1.正常启动 打开预览器的位置在DevEco Studio编辑界面的右上角部分&#xff0c;竖排…

基于VGG-16+Android+Python的智能车辆驾驶行为分析—深度学习算法应用(含全部工程源码)+数据集+模型(三)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据预处理2. 模型构建3. 模型训练及保存1&#xff09;模型训练2&#xff09;模型保存 4. 模型生成1&#xff09;模型导入及调用2&#xff09;相关代码&#xff08;1&#xff09;布局文件&#xff08;2&#xff…

独立站低成本流量:优化用户体验,实现精准营销

在当今的数字化时代&#xff0c;获取流量是每个网站成功的关键。然而&#xff0c;随着竞争的加剧&#xff0c;流量获取的成本也在逐渐上升。对于许多独立站来说&#xff0c;如何低成本的获取流量变得越来越具有挑战性。本文Nox聚星将和大家探讨独立站如何通过网站优化和精准营销…

云演CTF Blog

1、啥也搞不了&#xff0c;扫目录。出来个console 2、有显示锁掉了 3、抓包&#xff0c;改返回包 改成true&#xff0c;放包 不好意思&#xff0c;不会了&#xff0c;哈哈哈哈哈哈哈哈哈 你会的话&#xff0c;请告诉我&#xff0c;大佬