Qt优雅的组织项目结构三(使用CMakeLists进行模块化配置)——————附带详细示例代码

文章目录

Qt优雅的组织项目结构三(使用CMakeLists进行模块化配置)------------------附带详细示例代码

0 背景

之前写过使用.cmake来进行项目的分模块化管理,但是发现分层后的项目结构并不是十分清晰,不同模块的代码还是混在了一起,而不是每个模块的代码都单独分离出来。子模块还是公用着主模块的构建配置。

使用.cmake前:

使用.cmake后:

因此这里使用CmakeLists.txt来对项目进行分模块化管理。可以将子项目完全独立管理,每个子项目可以有自己的构建配置

使用子模块CMakeLists.txt前:

使用子模块CMakeLists.txt后:

可以看到子模块的代码被完全分离出来,更方便进行管理。

1 实践

  • 1,创建项目;


  • 2,修改CMakeLists.txt的内容为;
cpp 复制代码
# 设置cmake的最低版本
cmake_minimum_required(VERSION 3.16)

# 定义项目名称、项目版本、变成语言
project(TestCMakeLists VERSION 0.1 LANGUAGES CXX)

# 自动处理界面文件
set(CMAKE_AUTOUIC ON)
# 自动处理信号与槽
set(CMAKE_AUTOMOC ON)
# 自动处理资源文件
set(CMAKE_AUTORCC ON)

# 指定 C++ 语言标准版本为C++17
set(CMAKE_CXX_STANDARD 17)

# 强制要求指定的标准必须被满足。如果不支持C++17,CMake 配置阶段会直接报错并终止,不会尝试降级编译
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 保证代码的跨平台可移植性。 禁止编译器使用 GNU 扩展(如 GCC 的 gnu++17)或其他非标准的编译器扩展,强制使用严格的 ISO C++ 标准(即 c++17)。
set(CMAKE_CXX_EXTENSIONS OFF)


# 寻找Qt版本,并精确加载具体的 Qt 版本配置。
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

set(PROJECT_NAME "TestCMakeLists")

set(PROJECT_SOURCES
        main.cpp
)

#  调用编译器(如 `g++, cl.exe`)将源代码编译成目标文件`(.o 或 .obj)`,
# 然后调用链接器将这些目标文件和依赖库链接成一个完整的、操作系统可以直接加载的二进制文件`exe`
add_executable(${PROJECT_NAME}
    ${PROJECT_SOURCES}

)

# 把库链接到目标执行程序上
target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

# 为构建目标设置特定的属性(发布专业、规范的软件时,必不可少)
set_target_properties(${PROJECT_NAME} PROPERTIES
    WIN32_EXECUTABLE TRUE
)

把main函数修改为:

cpp 复制代码
// #include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // MainWindow w;
    // w.show();
    return a.exec();
}
  • 3,新建form文件夹,把UI相关的文件移到文件夹中;
  • 4,在form文件中,新建CMakeLists.txt文件,然后在根目录的CMakeLists.txt中添加如下内容,并重新构建;

放到add_executable之前:

cpp 复制代码
# 将子项目作为独立模块管理
add_subdirectory(Form) 

修改后的文件为:

cpp 复制代码
# 设置cmake的最低版本
cmake_minimum_required(VERSION 3.16)

# 定义项目名称、项目版本、变成语言
project(TestCMakeLists VERSION 0.1 LANGUAGES CXX)

# 自动处理界面文件
set(CMAKE_AUTOUIC ON)
# 自动处理信号与槽
set(CMAKE_AUTOMOC ON)
# 自动处理资源文件
set(CMAKE_AUTORCC ON)

# 指定 C++ 语言标准版本为C++17
set(CMAKE_CXX_STANDARD 17)

# 强制要求指定的标准必须被满足。如果不支持C++17,CMake 配置阶段会直接报错并终止,不会尝试降级编译
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 保证代码的跨平台可移植性。 禁止编译器使用 GNU 扩展(如 GCC 的 gnu++17)或其他非标准的编译器扩展,强制使用严格的 ISO C++ 标准(即 c++17)。
set(CMAKE_CXX_EXTENSIONS OFF)


# 寻找Qt版本,并精确加载具体的 Qt 版本配置。
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

set(PROJECT_NAME "TestCMakeLists")

set(PROJECT_SOURCES
        main.cpp
)

# (新添加内容)将子项目作为独立模块管理
add_subdirectory(Form) 

#  调用编译器(如 `g++, cl.exe`)将源代码编译成目标文件`(.o 或 .obj)`,
# 然后调用链接器将这些目标文件和依赖库链接成一个完整的、操作系统可以直接加载的二进制文件`exe`
add_executable(${PROJECT_NAME}
    ${PROJECT_SOURCES}

)

# 把库链接到目标执行程序上
target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

# 为构建目标设置特定的属性(发布专业、规范的软件时,必不可少)
set_target_properties(${PROJECT_NAME} PROPERTIES
    WIN32_EXECUTABLE TRUE
)

重写构建项目,得到新的项目结构:

  • 5,修改form文件夹中的CMakeLists.txt的内容为下面的内容,然后重新构建;
cpp 复制代码
# 设置cmake的最低版本
cmake_minimum_required(VERSION 3.16)

# 定义项目名称、项目版本、变成语言
project(FORM VERSION 0.1 LANGUAGES CXX)

# 自动处理界面文件
set(CMAKE_AUTOUIC ON)
# 自动处理信号与槽
set(CMAKE_AUTOMOC ON)
# 自动处理资源文件
set(CMAKE_AUTORCC ON)

set(PROJECT_NAME "FORM")

# 设置源文件
set(SOURCES
    mainwindow.cpp

)
# 设置头文件
set(HEADERS
    mainwindow.h

)
# 设置UI文件
set(FORMS
    mainwindow.ui

)

# 创建动态链接库
add_library(${PROJECT_NAME} STATIC
    ${SOURCES}
    ${HEADERS}
    ${FORMS}
)

# 链接Qt库
target_link_libraries(${PROJECT_NAME}  PRIVATE Qt5::Widgets)

# 设置库的包含目录
target_include_directories(${PROJECT_NAME}  PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
  • 6 ,修改根目录下的CMakeLists.txt文件,然后更改main函数;

末尾添加如下内容:

cpp 复制代码
# 把库链接到目标执行程序上
target_link_libraries(${PROJECT_NAME} PRIVATE FORM)

修改后CMakeLists.txt文件为:

cpp 复制代码
# 设置cmake的最低版本
cmake_minimum_required(VERSION 3.16)

# 定义项目名称、项目版本、变成语言
project(TestCMakeLists VERSION 0.1 LANGUAGES CXX)

# 自动处理界面文件
set(CMAKE_AUTOUIC ON)
# 自动处理信号与槽
set(CMAKE_AUTOMOC ON)
# 自动处理资源文件
set(CMAKE_AUTORCC ON)

# 指定 C++ 语言标准版本为C++17
set(CMAKE_CXX_STANDARD 17)

# 强制要求指定的标准必须被满足。如果不支持C++17,CMake 配置阶段会直接报错并终止,不会尝试降级编译
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 保证代码的跨平台可移植性。 禁止编译器使用 GNU 扩展(如 GCC 的 gnu++17)或其他非标准的编译器扩展,强制使用严格的 ISO C++ 标准(即 c++17)。
set(CMAKE_CXX_EXTENSIONS OFF)


# 寻找Qt版本,并精确加载具体的 Qt 版本配置。
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

set(PROJECT_NAME "TestCMakeLists")

set(PROJECT_SOURCES
        main.cpp
)

# 将子项目作为独立模块管理
add_subdirectory(Form)

#  调用编译器(如 `g++, cl.exe`)将源代码编译成目标文件`(.o 或 .obj)`,
# 然后调用链接器将这些目标文件和依赖库链接成一个完整的、操作系统可以直接加载的二进制文件`exe`
add_executable(${PROJECT_NAME}
    ${PROJECT_SOURCES}

)

# 把库链接到目标执行程序上
target_link_libraries(${PROJECT_NAME} PRIVATE FORM)

target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

# 为构建目标设置特定的属性(发布专业、规范的软件时,必不可少)
set_target_properties(${PROJECT_NAME} PROPERTIES
    WIN32_EXECUTABLE TRUE
)

然后,修改main函数的代码为:

cpp 复制代码
//#include "mainwindow.h" //这种方式也可以
#include "form/mainwindow.h"


#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

重新构建,运行代码即可。

2 扩展

名称 链接
pri模块化管理代码 链接
.cmake模块化管理代码 链接
CMakeLists.txt模块化管理代码 链接

附录

完整的项目代码见此。

相关推荐
小冷coding1 小时前
【MySQL】MySQL 插入一条数据的完整流程(InnoDB 引擎)
数据库·mysql
Elias不吃糖1 小时前
Java Lambda 表达式
java·开发语言·学习
guygg881 小时前
一级倒立摆MATLAB仿真程序
开发语言·matlab
情缘晓梦.2 小时前
C语言指针进阶
java·开发语言·算法
鲨莎分不晴2 小时前
Redis 基本指令与命令详解
数据库·redis·缓存
专注echarts研发20年2 小时前
工业级 Qt 业务窗体标杆实现・ResearchForm 类深度解析
数据库·qt·系统架构
世转神风-2 小时前
qt-字符串版本与数值版本互转
开发语言·qt
极客代码2 小时前
深入解析C语言中的函数指针:原理、规则与实践
c语言·开发语言·指针·状态机·函数·函数指针
w-w0w-w3 小时前
C++模板参数与特化全解析
开发语言·c++