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模块化管理代码 链接

附录

完整的项目代码见此。

相关推荐
xuxigifxfh28 分钟前
HJ15 求int型正整数在内存中存储时1的个数
java·开发语言·华为机考
行业研究员31 分钟前
Agent Memory降低Token消耗原理解析
数据库·人工智能·oracle·腾讯云·智能体
Wokoo732 分钟前
自动化测试入门:核心场景、回归测试与 Web 自动化环境搭建
java·开发语言·测试工具
yixun_gdas33 分钟前
企业网站内容巡查的价值与方法:企业官网的合规与形象管理
数据库·内容运营
tachibana234 分钟前
Golang 中数组和切片的区别?
开发语言·后端·golang·数组·切片
见闻小天地37 分钟前
空调机房赛莱默B&G冷冻泵/冷却泵的核心技术特性分析
大数据·运维·数据库
辛迪聊物业数字化38 分钟前
物业管理系统新手部署与实操指南
数据库·物联网·架构·系统架构
智购科技无人售货机工厂店1 小时前
玻璃瓶饮料破损率突然上升,排查发现是取货口缓冲垫老化了~YH
java·开发语言·人工智能·python·eclipse
March.s1 小时前
MySQL 数据库原理与实战:从数据管理到 LAMP 建站全解
数据库·mysql
枫叶丹41 小时前
语音 AI 怎样边听边答:实时对话系统的工作原理
开发语言·人工智能·chatgpt·开源·php·agent·codex