|
| 1 | +# ============================================================ |
| 2 | +# Qt Unified Deployment Utilities |
| 3 | +# ============================================================ |
| 4 | +# 提供动态注册机制,让子项目自动注册到统一部署列表 |
| 5 | + |
| 6 | +# 定义一个全局列表变量,用于收集所有需要部署的可执行文件 |
| 7 | +set(QT_DEPLOY_EXECUTABLES "" CACHE INTERNAL "List of executables for Qt deployment") |
| 8 | + |
| 9 | +# ============================================================ |
| 10 | +# 宏: cf_register_qt_deployment |
| 11 | +# ============================================================ |
| 12 | +# 子项目调用此宏注册自己到统一部署列表 |
| 13 | +# |
| 14 | +# 用法: |
| 15 | +# cf_register_qt_deployment(target_name) |
| 16 | +# |
| 17 | +macro(cf_register_qt_deployment TARGET_NAME) |
| 18 | + list(APPEND QT_DEPLOY_EXECUTABLES ${TARGET_NAME}) |
| 19 | + set(QT_DEPLOY_EXECUTABLES "${QT_DEPLOY_EXECUTABLES}" CACHE INTERNAL "List of executables for Qt deployment") |
| 20 | +endmacro() |
| 21 | + |
| 22 | +# ============================================================ |
| 23 | +# 函数: cf_setup_unified_qt_deployment |
| 24 | +# ============================================================ |
| 25 | +# 在顶层调用,设置统一的 Qt 部署 |
| 26 | +# 必须在所有子项目 add_subdirectory 之后调用 |
| 27 | +# |
| 28 | +function(cf_setup_unified_qt_deployment) |
| 29 | + if(WIN32 AND NOT CMAKE_CROSSCOMPILING AND QT_DEPLOY_EXECUTABLES) |
| 30 | + # 找到 windeployqt |
| 31 | + find_program(WINDEPLOYQT_EXECUTABLE windeployqt |
| 32 | + HINTS "${CMAKE_PREFIX_DIR}/bin" "${_qt_install_prefix}/bin" |
| 33 | + ) |
| 34 | + |
| 35 | + if(WINDEPLOYQT_EXECUTABLE) |
| 36 | + set(DEPLOY_BIN_DIR "${CMAKE_BINARY_DIR}/bin") |
| 37 | + set(DEPLOY_MARKER "${DEPLOY_BIN_DIR}/.deploy_done") |
| 38 | + |
| 39 | + message(STATUS "Setting up unified Qt deployment for: ${QT_DEPLOY_EXECUTABLES}") |
| 40 | + |
| 41 | + # 创建统一的部署 target |
| 42 | + add_custom_target(deploy_qt_dlls ALL) |
| 43 | + |
| 44 | + # 让部署 target 依赖所有已注册的可执行文件 |
| 45 | + foreach(exe ${QT_DEPLOY_EXECUTABLES}) |
| 46 | + if(TARGET ${exe}) |
| 47 | + add_dependencies(deploy_qt_dlls ${exe}) |
| 48 | + # 确保输出到 bin 目录 |
| 49 | + set_target_properties(${exe} PROPERTIES |
| 50 | + RUNTIME_OUTPUT_DIRECTORY ${DEPLOY_BIN_DIR} |
| 51 | + ) |
| 52 | + else() |
| 53 | + message(WARNING "Registered deployment target '${exe}' not found") |
| 54 | + endif() |
| 55 | + endforeach() |
| 56 | + |
| 57 | + # 使用第一个可执行文件作为 windeployqt 的入口 |
| 58 | + list(GET QT_DEPLOY_EXECUTABLES 0 FIRST_EXE) |
| 59 | + |
| 60 | + # 执行部署 |
| 61 | + add_custom_command(TARGET deploy_qt_dlls POST_BUILD |
| 62 | + COMMAND ${CMAKE_COMMAND} -E env QT_HASH_SEED=0 |
| 63 | + "${WINDEPLOYQT_EXECUTABLE}" |
| 64 | + --dir "${DEPLOY_BIN_DIR}" |
| 65 | + --no-compiler-runtime |
| 66 | + --no-translations |
| 67 | + --no-system-d3d-compiler |
| 68 | + --no-opengl-sw |
| 69 | + --verbose 1 |
| 70 | + "$<TARGET_FILE:${FIRST_EXE}>" |
| 71 | + COMMAND ${CMAKE_COMMAND} -E touch "${DEPLOY_MARKER}" |
| 72 | + COMMENT "Unified Qt deployment to ${DEPLOY_BIN_DIR}" |
| 73 | + VERBATIM |
| 74 | + ) |
| 75 | + else() |
| 76 | + message(WARNING "windeployqt not found, skipping automatic Qt deployment") |
| 77 | + endif() |
| 78 | + endif() |
| 79 | +endfunction() |
0 commit comments