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

15 篇文章 0 订阅

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

最外层的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 ()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值