重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
qt-compatibility-build by re2zero/deepin-skills
npx skills add https://github.com/re2zero/deepin-skills --skill qt-compatibility-build通过自动检测 Qt5/Qt6 并动态映射 DTK 版本,统一了 CMake 配置以支持 deepin V25/V20 双版本,消除了整个构建系统中硬编码的版本引用。
| 文件 | Deepin 版本 | Qt 版本 |
|---|---|---|
debian/control | V25 | Qt6 |
debian/control.1 | V20 | Qt5 |
原因 : control(无后缀)= 最新版本 (V25),control.1(带后缀)= 前一个版本 (V20)。
digraph when_to_use {
"Qt/CMake project?" [shape=diamond];
"V25/V20 dual support?" [shape=diamond];
"Hard-coded Qt/DTK?" [shape=diamond];
"Use this skill" [shape=box];
"Wrong tool" [shape=box];
"Qt/CMake project?" -> "V25/V20 dual support?" [label="yes"];
"V25/V20 dual support?" -> "Hard-coded Qt/DTK?" [label="yes"];
"Hard-coded Qt/DTK?" -> "Use this skill" [label="yes"];
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
在以下情况使用:
target_link_libraries 中硬编码了 Qt5:: 或 Qt6::find_package 或链接中硬编码了 Dtk:: 或 Dtk6::在以下情况不要使用:
| 任务 | 命令/模式 |
|---|---|
| 自动检测 Qt | find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) |
| 映射 DTK 到 Qt | if (QT_VERSION_MAJOR MATCHES 6) set(DTK_VERSION_MAJOR 6) |
| 动态查找 Qt | find_package(Qt${QT_VERSION_MAJOR} COMPONENTS ${QT} REQUIRED) |
| 动态查找 DTK | find_package(Dtk${DTK_VERSION_MAJOR}Widget REQUIRED) |
| 动态 Qt 链接 | Qt${QT_VERSION_MAJOR}::Core |
| 动态 DTK 链接 | Dtk${DTK_VERSION_MAJOR}::Core |
| V25 构建 | cmake -B build -DQT_DIR=/usr/lib/x86_64-linux-gnu/cmake/Qt6 |
| V20 构建 | cmake -B build5 -DQT_DIR=/usr/lib/x86_64-linux-gnu/cmake/Qt5 |
注意 : -DQT_DIR 对于本地构建便利是可选的。如果未指定,CMake 会自动检测。
# Auto-detect Qt version (tries Qt6 first, falls back to Qt5)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
message(STATUS "Found Qt version: ${QT_VERSION_MAJOR}")
# Map to DTK version (Qt6→DTK6, Qt5→DTK5)
if (QT_VERSION_MAJOR MATCHES 6)
set(DTK_VERSION_MAJOR 6)
else()
set(DTK_VERSION_MAJOR "")
endif()
message(STATUS "Build with DTK: ${DTK_VERSION_MAJOR}")
之前(硬编码):
find_package(Qt6 COMPONENTS Core Gui Widgets Network REQUIRED)
find_package(DtkWidget REQUIRED)
之后(动态):
set(QT Core Gui Widgets Network DBus Sql Svg Test WebChannel WebSockets)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS ${QT} REQUIRED)
find_package(Dtk${DTK_VERSION_MAJOR}Widget REQUIRED)
find_package(Dtk${DTK_VERSION_MAJOR}Core REQUIRED)
find_package(Dtk${DTK_VERSION_MAJOR}Gui REQUIRED)
之前(硬编码):
target_link_libraries(mylib
Dtk::Core
Dtk::Gui
Qt6::Network
)
之后(动态):
target_link_libraries(mylib
Dtk${DTK_VERSION_MAJOR}::Core
Dtk${DTK_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
)
替换模式:
Qt5:: → Qt${QT_VERSION_MAJOR}::Qt6:: → Qt${QT_VERSION_MAJOR}::Dtk:: → Dtk${DTK_VERSION_MAJOR}::Dtk6:: → Dtk${DTK_VERSION_MAJOR}::创建 cmake/translation-generate.cmake:
function(TRANSLATION_GENERATE QMS)
find_package(Qt${QT_VERSION_MAJOR}LinguistTools QUIET)
if (NOT Qt${QT_VERSION_MAJOR}_LRELEASE_EXECUTABLE)
set(QT_LRELEASE "/lib/qt${QT_VERSION_MAJOR}/bin/lrelease")
message(STATUS "NOT found lrelease, set QT_LRELEASE = ${QT_LRELEASE}")
else()
set(QT_LRELEASE "${Qt${QT_VERSION_MAJOR}_LRELEASE_EXECUTABLE}")
endif()
if(NOT ARGN)
message(SEND_ERROR "Error: TRANSLATION_GENERATE() called without any .ts path")
return()
endif()
file(GLOB TS_FILES "${ARGN}/*.ts")
set(${QMS})
foreach(TSFIL ${TS_FILES})
get_filename_component(FIL_WE ${TSFIL} NAME_WE)
set(QMFIL ${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.qm)
list(APPEND ${QMS} ${QMFIL})
add_custom_command(
OUTPUT ${QMFIL}
COMMAND ${QT_LRELEASE} ${TSFIL} -qm ${QMFIL}
DEPENDS ${TSFIL}
COMMENT "Running ${QT_LRELEASE} on ${TSFIL}"
VERBATIM
)
endforeach()
set_source_files_properties(${${QMS}} PROPERTIES GENERATED TRUE)
set(${QMS} ${${QMS}} PARENT_SCOPE)
endfunction()
用法:
include(translation-generate)
TRANSLATION_GENERATE(QM_FILES ${CMAKE_SOURCE_DIR}/translations)
add_custom_target(${PROJECT_NAME}_qm_files DEPENDS ${QM_FILES})
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}_qm_files)
install(FILES ${QM_FILES} DESTINATION share/${PROJECT_NAME}/translations)
debian/control (V25/Qt6):
Build-Depends:
cmake,
pkg-config,
qt6-base-dev,
qt6-tools-dev,
qt6-svg-dev,
libdtk6widget-dev,
libdtk6core-dev
debian/control.1 (V20/Qt5):
Build-Depends:
cmake,
pkg-config,
qtbase5-dev,
qttools5-dev,
libqt5svg5-dev,
libdtkwidget-dev,
libdtkcore-dev
| 用途 | V25 (Qt6) | V20 (Qt5) |
|---|---|---|
| 基础 | qt6-base-dev | qtbase5-dev |
| 工具 | qt6-tools-dev | qttools5-dev |
| SVG | qt6-svg-dev | libqt5svg5-dev |
| DTK Widget | libdtk6widget-dev | libdtkwidget-dev |
| DTK Core | libdtk6core-dev | libdtkcore-dev |
| 错误 | 为何错误 | 修复方法 |
|---|---|---|
硬编码 Qt5::Core / Qt6::Core | 强制使用特定 Qt 版本 | 使用 Qt${QT_VERSION_MAJOR}::Core |
硬编码 Dtk::Core / Dtk6::Core | 强制使用特定 DTK 版本 | 使用 Dtk${DTK_VERSION_MAJOR}::Core |
缺少 DTK_VERSION_MAJOR | DTK 无法映射到 Qt 版本 | 添加从 Qt 检测到该变量的映射 |
仅使用 control 而没有 control.1 | 不支持 V20 | 创建两个 control 文件 |
| 在单个 control 文件中使用 OR 依赖 | 应使用单独的文件 | 拆分为 control 和 control.1 |
| 仅测试一个 Qt 版本 | 双版本支持必须两者都工作 | 测试 V25 和 V20 构建 |
未使用 find_package(QT NAMES Qt6 Qt5 ...) | 无法自动检测两者 | 使用正确的 find_package 模式 |
QT_VERSION_MAJOR 变量DTK_VERSION_MAJOR 变量DTK_VERSION_MAJOR 变量 → DTK 无法映射到 Qt 版本find_package(QT NAMES Qt6 Qt5 ...) → 无法检测两个版本每周安装数
50
仓库
GitHub 星标数
6
首次出现
2026年1月22日
安全审计
安装于
opencode38
gemini-cli36
cursor35
codex35
github-copilot34
amp32
Unifies CMake configuration for deepin V25/V20 dual-version support by automatically detecting Qt5/Qt6 and dynamically mapping DTK versions, eliminating hard-coded version references throughout the build system.
| File | Deepin Version | Qt Version |
|---|---|---|
debian/control | V25 | Qt6 |
debian/control.1 | V20 | Qt5 |
Why : control (no suffix) = latest version (V25), control.1 (with suffix) = previous version (V20).
digraph when_to_use {
"Qt/CMake project?" [shape=diamond];
"V25/V20 dual support?" [shape=diamond];
"Hard-coded Qt/DTK?" [shape=diamond];
"Use this skill" [shape=box];
"Wrong tool" [shape=box];
"Qt/CMake project?" -> "V25/V20 dual support?" [label="yes"];
"V25/V20 dual support?" -> "Hard-coded Qt/DTK?" [label="yes"];
"Hard-coded Qt/DTK?" -> "Use this skill" [label="yes"];
}
Use when:
Qt5:: or Qt6:: in target_link_librariesDtk:: or Dtk6:: in find_package or linkingDo NOT use when:
| Task | Command/Pattern |
|---|---|
| Auto-detect Qt | find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) |
| Map DTK to Qt | if (QT_VERSION_MAJOR MATCHES 6) set(DTK_VERSION_MAJOR 6) |
| Dynamic Qt find | find_package(Qt${QT_VERSION_MAJOR} COMPONENTS ${QT} REQUIRED) |
| Dynamic DTK find | find_package(Dtk${DTK_VERSION_MAJOR}Widget REQUIRED) |
| Dynamic Qt linking | Qt${QT_VERSION_MAJOR}::Core |
| Dynamic DTK linking |
Note : -DQT_DIR is optional for local build convenience. CMake auto-detects if not specified.
# Auto-detect Qt version (tries Qt6 first, falls back to Qt5)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
message(STATUS "Found Qt version: ${QT_VERSION_MAJOR}")
# Map to DTK version (Qt6→DTK6, Qt5→DTK5)
if (QT_VERSION_MAJOR MATCHES 6)
set(DTK_VERSION_MAJOR 6)
else()
set(DTK_VERSION_MAJOR "")
endif()
message(STATUS "Build with DTK: ${DTK_VERSION_MAJOR}")
Before (hard-coded):
find_package(Qt6 COMPONENTS Core Gui Widgets Network REQUIRED)
find_package(DtkWidget REQUIRED)
After (dynamic):
set(QT Core Gui Widgets Network DBus Sql Svg Test WebChannel WebSockets)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS ${QT} REQUIRED)
find_package(Dtk${DTK_VERSION_MAJOR}Widget REQUIRED)
find_package(Dtk${DTK_VERSION_MAJOR}Core REQUIRED)
find_package(Dtk${DTK_VERSION_MAJOR}Gui REQUIRED)
Before (hard-coded):
target_link_libraries(mylib
Dtk::Core
Dtk::Gui
Qt6::Network
)
After (dynamic):
target_link_libraries(mylib
Dtk${DTK_VERSION_MAJOR}::Core
Dtk${DTK_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Network
)
Replacement pattern:
Qt5:: → Qt${QT_VERSION_MAJOR}::Qt6:: → Qt${QT_VERSION_MAJOR}::Dtk:: → Dtk${DTK_VERSION_MAJOR}::Dtk6:: → Dtk${DTK_VERSION_MAJOR}::Create cmake/translation-generate.cmake:
function(TRANSLATION_GENERATE QMS)
find_package(Qt${QT_VERSION_MAJOR}LinguistTools QUIET)
if (NOT Qt${QT_VERSION_MAJOR}_LRELEASE_EXECUTABLE)
set(QT_LRELEASE "/lib/qt${QT_VERSION_MAJOR}/bin/lrelease")
message(STATUS "NOT found lrelease, set QT_LRELEASE = ${QT_LRELEASE}")
else()
set(QT_LRELEASE "${Qt${QT_VERSION_MAJOR}_LRELEASE_EXECUTABLE}")
endif()
if(NOT ARGN)
message(SEND_ERROR "Error: TRANSLATION_GENERATE() called without any .ts path")
return()
endif()
file(GLOB TS_FILES "${ARGN}/*.ts")
set(${QMS})
foreach(TSFIL ${TS_FILES})
get_filename_component(FIL_WE ${TSFIL} NAME_WE)
set(QMFIL ${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.qm)
list(APPEND ${QMS} ${QMFIL})
add_custom_command(
OUTPUT ${QMFIL}
COMMAND ${QT_LRELEASE} ${TSFIL} -qm ${QMFIL}
DEPENDS ${TSFIL}
COMMENT "Running ${QT_LRELEASE} on ${TSFIL}"
VERBATIM
)
endforeach()
set_source_files_properties(${${QMS}} PROPERTIES GENERATED TRUE)
set(${QMS} ${${QMS}} PARENT_SCOPE)
endfunction()
Usage:
include(translation-generate)
TRANSLATION_GENERATE(QM_FILES ${CMAKE_SOURCE_DIR}/translations)
add_custom_target(${PROJECT_NAME}_qm_files DEPENDS ${QM_FILES})
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}_qm_files)
install(FILES ${QM_FILES} DESTINATION share/${PROJECT_NAME}/translations)
debian/control (V25/Qt6):
Build-Depends:
cmake,
pkg-config,
qt6-base-dev,
qt6-tools-dev,
qt6-svg-dev,
libdtk6widget-dev,
libdtk6core-dev
debian/control.1 (V20/Qt5):
Build-Depends:
cmake,
pkg-config,
qtbase5-dev,
qttools5-dev,
libqt5svg5-dev,
libdtkwidget-dev,
libdtkcore-dev
| Purpose | V25 (Qt6) | V20 (Qt5) |
|---|---|---|
| Base | qt6-base-dev | qtbase5-dev |
| Tools | qt6-tools-dev | qttools5-dev |
| SVG | qt6-svg-dev | libqt5svg5-dev |
| DTK Widget | libdtk6widget-dev |
| Mistake | Why It's Wrong | Fix |
|---|---|---|
Hard-coded Qt5::Core / Qt6::Core | Forces specific Qt version | Use Qt${QT_VERSION_MAJOR}::Core |
Hard-coded Dtk::Core / Dtk6::Core | Forces specific DTK version | Use Dtk${DTK_VERSION_MAJOR}::Core |
Missing DTK_VERSION_MAJOR |
QT_VERSION_MAJOR variableDTK_VERSION_MAJOR variableDTK_VERSION_MAJOR variable → DTK won't map to Qt versionfind_package(QT NAMES Qt6 Qt5 ...) → Won't detect both versionsWeekly Installs
50
Repository
GitHub Stars
6
First Seen
Jan 22, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode38
gemini-cli36
cursor35
codex35
github-copilot34
amp32
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
127,000 周安装
Dtk${DTK_VERSION_MAJOR}::Core |
| V25 build | cmake -B build -DQT_DIR=/usr/lib/x86_64-linux-gnu/cmake/Qt6 |
| V20 build | cmake -B build5 -DQT_DIR=/usr/lib/x86_64-linux-gnu/cmake/Qt5 |
libdtkwidget-dev |
| DTK Core | libdtk6core-dev | libdtkcore-dev |
| DTK won't map to Qt version |
| Add variable mapping from Qt detection |
Only using control without control.1 | Won't support V20 | Create both control files |
| Using OR dependencies in single control | Should use separate files | Split into control and control.1 |
| Only testing one Qt version | Both must work for dual support | Test V25 and V20 builds |
Not using find_package(QT NAMES Qt6 Qt5 ...) | Won't auto-detect both | Use correct find_package pattern |