From be6e20222995bd36a39f61bccab98e664a87d872 Mon Sep 17 00:00:00 2001 From: RL-Xiang Date: Thu, 20 Aug 2026 11:59:03 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3vscode=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 150 +++++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 81 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87e87bf..7cde407 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,62 +6,54 @@ project(FancyInputQt LANGUAGES C CXX ) +# ============ 全局编译设置 ============ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -# ---- 输出目录策略 ---- -# build/:仅存放 CMake 中间产物(编译对象、Makefile、生成的 QML 模块等) -# bin/ :最终产物(exe + Qt DLL + 插件),由 windeployqt 部署,开箱即用 -# 注意:不能用全局 CMAKE_RUNTIME_OUTPUT_DIRECTORY —— 已验证它会破坏 -# qt_add_qml_module 的 QML 模块嵌入,运行时报 "Module FancyInputQt contains no type named Main"。 -# 必须用 per-target 属性且放在 qt_add_qml_module 之后设置(见下方 target_link_libraries 后)。 - -# Qt 6.8.3 MinGW 套件(LGPL v3 动态链接,可免费商用) +# ============ Qt 依赖(6.8.3 MinGW,LGPL v3 动态链接) ============ find_package(Qt6 6.8 REQUIRED COMPONENTS - Core - Gui - Qml - Quick - QuickControls2 + Core Gui Qml Quick QuickControls2 ) -# QTP0004: QML 文件统一由 qt_add_qml_module 管理,无需额外 qmldir -qt_policy(SET QTP0004 NEW) -# QTP0001: QML 模块资源前缀使用 :/qt/qml//(如 :/qt/qml/FancyInputQt/、:/qt/qml/FancyInput/Controls/), -# main.cpp 中已 addImportPath("qrc:/") 使内嵌模块可被发现 +# QTP0001: QML 资源前缀为 :/qt/qml// +# QTP0004: QML 文件统一由 qt_add_qml_module 管理,无需手写 qmldir qt_policy(SET QTP0001 NEW) +qt_policy(SET QTP0004 NEW) -# ---- 阶段 0:Hello World 工程骨架 ---- -# 后续阶段:输入识别核心 → 通用函数 → 主界面 → 分窗口 → 延后功能 +# QML 模块统一输出到 build///(qmlls/qmllint 依赖此布局才能找到模块) +# 必须在 qt_add_qml_module 之前设置 +set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") +# ============ 主程序 ============ qt_add_executable(FancyInputQt src/main.cpp ) -# ---- 用户控件模块 FancyInput.Controls(独立静态库) ---- -# 自定义控件/主题统一放这里,App 主界面通过 `import FancyInput.Controls` 使用, -# 与 Qt 内置模块解耦,后续扩展新控件只需往 src/qml/controls/ 目录加 .qml 文件。 -# URI 用点分命名空间(FancyInput.Controls),避免与主模块/第三方库撞名。 -# 注意:Theme.qml 用 pragma Singleton,必须通过 QT_QML_SINGLETON_TYPE -# 源文件属性显式声明(qt_add_qml_module 只自动识别 .pragma library, -# 不会自动检测 pragma Singleton —— 见 Qt6QmlMacros.cmake 3292 行)。 -qt_add_library(FancyInputControls STATIC) +# ============ QML 模块 1:FancyInput.Controls(用户自定义控件) ============ +# 控件文件放在 src/qml/controls/ 目录下,GLOB 自动收集: +# 以后新增控件只需放 .qml 文件,无需修改本文件。 +file(GLOB CONTROLS_QML_FILES CONFIGURE_DEPENDS + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + "src/qml/controls/*.qml" +) +# Theme.qml 是 QML 单例(pragma Singleton),需显式声明 set_source_files_properties( src/qml/controls/Theme.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE ) qt_add_qml_module(FancyInputControls + STATIC # 编译为静态库,链接进 exe,无需额外部署 DLL URI FancyInput.Controls VERSION 1.0 QML_FILES - src/qml/controls/Theme.qml + ${CONTROLS_QML_FILES} ) -# ---- 主入口 QML 模块(App 自身,URI 与 exe 同名用于内嵌发现) ---- +# ============ QML 模块 2:FancyInputQt(App 主界面) ============ qt_add_qml_module(FancyInputQt URI FancyInputQt VERSION 1.0 @@ -71,75 +63,71 @@ qt_add_qml_module(FancyInputQt FancyInputControls ) +# ============ 链接 ============ target_link_libraries(FancyInputQt PRIVATE - FancyInputControls - FancyInputControlsplugin - Qt6::Core - Qt6::Gui - Qt6::Qml - Qt6::Quick - Qt6::QuickControls2 + FancyInputControls # 控件模块(含 QML 资源) + FancyInputControlsplugin # 控件模块的静态插件,必须链接,否则运行时找不到模块 + Qt6::Core Qt6::Gui Qt6::Qml Qt6::Quick Qt6::QuickControls2 ) -# ---- 输出目录:per-target 设置(必须在 qt_add_qml_module 之后) ---- -# exe 直接输出到 bin/,build/ 只留中间产物 +# ============ 输出目录 ============ +# exe 输出到 bin/,build/ 只留中间产物(须在 qt_add_qml_module 之后设置) set_target_properties(FancyInputQt PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}" ) -# ---- 构建后自动部署 Qt DLL 到 bin/(LGPL 动态链接) ---- -# 用 Qt 官方 windeployqt 把所需 DLL + 插件 + QML 依赖拷到 exe 旁, -# 保证 bin/ 目录开箱即用(双击即可运行,无需依赖 PATH)。 -# -# 体积优化(已验证,Release 从 ~63MB 减到 ~46MB): -# 1. --skip-plugin-types qmltooling -> 跳过 QML 调试插件(仅开发用) -# 2. 部署后删除未使用的 QuickControls2 风格: -# FluentWinUI3(4.8MB)/Material/Universal/Imagine —— 默认只加载 Windows/Basic/Fusion -# 3. 删除未使用模块:tls(OpenSSL)、generic(触摸屏)、多余 imageformats -# 4. 强制删除 Qt6VirtualKeyboard(GPL v3,禁止用于闭源商用!本工程未使用它, -# 只是被 windeployqt 隐式部署进来)—— 见下方裁剪命令 +# ============ 部署:windeployqt 拷贝 Qt 运行库 + 裁剪未使用组件 ============ if(WIN32) find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT6_INSTALL_PREFIX}/bin" REQUIRED) + + # 1. 拷贝所需 Qt DLL/插件/QML 到 exe 旁 add_custom_command(TARGET FancyInputQt POST_BUILD COMMAND "${WINDEPLOYQT_EXECUTABLE}" --no-translations --no-system-d3d-compiler --no-opengl-sw --skip-plugin-types qmltooling --qmldir "${CMAKE_SOURCE_DIR}/src/qml" "$" - COMMENT "windeployqt: 部署 Qt 运行库到 bin/") - # 部署后裁剪未使用的 Qt 模块/插件(体积优化) + COMMENT "部署 Qt 运行库") + + # 2. 体积优化:删除未使用的 Qt 组件 set(DEPLOY_DIR "${CMAKE_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}") + + # 2.1 未使用的 QuickControls2 风格(默认只需 Windows/Basic/Fusion) + set(UNUSED_STYLES + "${DEPLOY_DIR}/qml/QtQuick/Controls/FluentWinUI3" + "${DEPLOY_DIR}/qml/QtQuick/Controls/Material" + "${DEPLOY_DIR}/qml/QtQuick/Controls/Universal" + "${DEPLOY_DIR}/qml/QtQuick/Controls/Imagine" + "${DEPLOY_DIR}/Qt6QuickControls2FluentWinUI3StyleImpl.dll" + "${DEPLOY_DIR}/Qt6QuickControls2Material.dll" + "${DEPLOY_DIR}/Qt6QuickControls2MaterialStyleImpl.dll" + "${DEPLOY_DIR}/Qt6QuickControls2Universal.dll" + "${DEPLOY_DIR}/Qt6QuickControls2UniversalStyleImpl.dll" + "${DEPLOY_DIR}/Qt6QuickControls2Imagine.dll" + "${DEPLOY_DIR}/Qt6QuickControls2ImagineStyleImpl.dll") + + # 2.2 Qt6VirtualKeyboard(GPL v3 禁止闭源商用,本工程未使用) + set(GPL_COMPONENTS + "${DEPLOY_DIR}/qml/QtQuick/VirtualKeyboard" + "${DEPLOY_DIR}/Qt6VirtualKeyboard.dll" + "${DEPLOY_DIR}/platforminputcontexts/qtvirtualkeyboardplugin.dll") + + # 2.3 其他未使用组件 + set(UNUSED_MISC + "${DEPLOY_DIR}/tls" + "${DEPLOY_DIR}/generic" + "${DEPLOY_DIR}/imageformats/qgif.dll" + "${DEPLOY_DIR}/imageformats/qicns.dll" + "${DEPLOY_DIR}/imageformats/qtga.dll" + "${DEPLOY_DIR}/imageformats/qtiff.dll" + "${DEPLOY_DIR}/imageformats/qwbmp.dll" + "${DEPLOY_DIR}/imageformats/qwebp.dll") + add_custom_command(TARGET FancyInputQt POST_BUILD - COMMAND ${CMAKE_COMMAND} -E rm -rf - "${DEPLOY_DIR}/qml/QtQuick/Controls/FluentWinUI3" - "${DEPLOY_DIR}/qml/QtQuick/Controls/Material" - "${DEPLOY_DIR}/qml/QtQuick/Controls/Universal" - "${DEPLOY_DIR}/qml/QtQuick/Controls/Imagine" - COMMAND ${CMAKE_COMMAND} -E rm -f - "${DEPLOY_DIR}/Qt6QuickControls2FluentWinUI3StyleImpl.dll" - "${DEPLOY_DIR}/Qt6QuickControls2Material.dll" - "${DEPLOY_DIR}/Qt6QuickControls2MaterialStyleImpl.dll" - "${DEPLOY_DIR}/Qt6QuickControls2Universal.dll" - "${DEPLOY_DIR}/Qt6QuickControls2UniversalStyleImpl.dll" - "${DEPLOY_DIR}/Qt6QuickControls2Imagine.dll" - "${DEPLOY_DIR}/Qt6QuickControls2ImagineStyleImpl.dll" - COMMAND ${CMAKE_COMMAND} -E rm -rf - "${DEPLOY_DIR}/tls" - "${DEPLOY_DIR}/generic" - # Qt6VirtualKeyboard = GPL v3,禁止闭源商用,且本工程未使用 —— 强制删除 - COMMAND ${CMAKE_COMMAND} -E rm -rf - "${DEPLOY_DIR}/qml/QtQuick/VirtualKeyboard" - COMMAND ${CMAKE_COMMAND} -E rm -f - "${DEPLOY_DIR}/Qt6VirtualKeyboard.dll" - "${DEPLOY_DIR}/platforminputcontexts/qtvirtualkeyboardplugin.dll" - COMMAND ${CMAKE_COMMAND} -E rm -f - "${DEPLOY_DIR}/imageformats/qgif.dll" - "${DEPLOY_DIR}/imageformats/qicns.dll" - "${DEPLOY_DIR}/imageformats/qtga.dll" - "${DEPLOY_DIR}/imageformats/qtiff.dll" - "${DEPLOY_DIR}/imageformats/qwbmp.dll" - "${DEPLOY_DIR}/imageformats/qwebp.dll" - COMMENT "体积优化: 删除未使用的 Qt 风格/插件 + GPL 的 VirtualKeyboard") + COMMAND ${CMAKE_COMMAND} -E rm -rf ${UNUSED_STYLES} + COMMAND ${CMAKE_COMMAND} -E rm -rf ${GPL_COMPONENTS} + COMMAND ${CMAKE_COMMAND} -E rm -rf ${UNUSED_MISC} + COMMENT "体积优化: 裁剪未使用的 Qt 组件") endif()