编辑的话请把自己的名字加到作者名单里
DDE v23 beta3 即将随 deepin v23 beta 3 发布(你阅读到这个文章的时候可能已经发布了)。为了方便各个其它发行版的包维护者可以更方便的移植 DDE 到对应的发行版,这里提供一篇简要的移植指南,用以描述常见的移植问题和解决方案。
下面对项目名称的称呼均以 GitHub 对应的原始仓库名为准。 {.note}
DDE 此次 beta2 -> beta3 的更新中,dde-application-manager 进行了大规模重构;dde-launchpad 取代 dde-launcher 成为了新的启动器/开始菜单应用;新的技术预览项目 dde-shell 和 treeland 也随此次发布提供了初步版本,以及为了服务 dde-launcher 和 dde-shell,dtk 也开始提供 Qt 6 版本。
由于这些项目的版本间互相影响,我们建议移植人员参照 deepin v23 beta3 所使用的包版本进行打包(随后会把完整的版本参照列表贴到这里),下面会对主要的部分进行详细说明。
作为 DDE 组件与应用的基础依赖,DTK 现开始提供 Qt 6 支持。适用于 beta 3 的版本参照如下:
package | version |
---|---|
dtkcommon | 5.6.21 |
dtkcore | 5.6.22 |
dtkgui | 5.6.22 |
dtkwidget | 5.6.22 |
dtkdeclarative | 5.6.24 |
qt5integration | 5.6.20 |
qt5platform-plugins | 5.6.22 |
dtk6core | 6.0.4 |
dtk6gui | 6.0.5 |
dtk6widget | 6.0.4 |
dtk6declarative | 6.0.7 |
qt6integration | 6.0.4 |
qt6platform-plugins | 6.0.4 |
由于 dtkdeclarative 和 dtkgui 存在一些发布前的紧急修复,所以这两个组件存在版本号未对齐的情况。请直接参照上述表格的版本进行打包,以便确保 dtk 自身互相依赖的版本无误。
关于 qt5platform-plugins,现有的 dwayland 插件可能对非 DDE 环境(例如 KDE)的 wayland 用户存在影响,可参照 linuxdeepin/developer-center#7217 打对应的 patch 规避影响。
dtk6 曾对 Qt 6.2, Qt 6.4 和 Qt 6.6 均进行过适配,但我们目前的研发与测试主要使用 Qt 6.6 版本,故我们建议使用尽可能新的 Qt 6 版本。
目前,使用 dtk6 的正式组件有 dde-application-manager 以及 dde-launchpad,技术预览组件有 dde-shell, treeland。
dde-application-manager 自 1.1.0 版本起进行了完整重构(此次随 beta 3 发布的版本是 1.1.8),接口存在完全不兼容的变动。故原本依赖重构前 dde-application-manager 的应用程序和组件均需要进行更新。比较典型的组件为 dde-dock 与 dde-file-manager。
dde-launchpad 取代了 dde-launcher,原 dde-launcher 由于大量缺陷以及对旧 dde-application-manager 的强依赖,已不再可用。如果您的发行版在使用 dde-launcher,现在可以废弃 dde-launcher 并使用 dde-launchpad 替代了。
尽管在 deepin 中,dde-launchpad 使用的是 Qt 6 构建的版本,dde-launchpad 本身仍然提供了选项来控制使用 Qt 5 或是 Qt 6。我们建议在允许的情况下尽可能使用 Qt 6 而不是 Qt 5,以及无论 Qt 5 或是 Qt 6 支持,请都不要忘记安装 qt5/6integration 插件以及 qt5/6platform-plugins,否则 dde-launchpad 可能会缺失圆角与模糊效果。同样,强烈建议配合最新 DTK 版本构建来获得最佳显示效果。
另外,随 dde-launchpad 一并发布了 dde-application-wizard 项目。此项目是一个守护进程,提供对旧的 dde-application-manager 所提供的卸载服务接口的兼容支持,但可被移植到支持 packagekit 的发行版,故您可以考虑打包移植此组件。如果您的发行版不支持 packagekit,则可考虑暂时 patch dde-launchpad 来隐藏菜单中的卸载按钮,后续 dde-launchpad 会提供 DConfig 来便于发行版定制这些菜单项。
技术预览阶段的组件均可酌情决定是否打包。
dde-shell 目前是技术预览阶段的项目。dde-shell 旨在将 DDE 桌面环境插件化与模块化,降低开发难度,使各个组件的替换变得更加容易,并且提供更好的桌面环境集成支持。
dde-shell 目前包含 shell 本体,以及预制的新 dock 插件和通知中心插件。
treeland 目前是技术预览阶段的项目,兼顾 Wayland 窗口合成器和显示管理功能。treeland 除需要 dtk6declarative 外,还依赖新项目包括 waylib 和 qwlroots。需要使用 Qt 版本 >= 6.6.0, wlroots 版本 >= 0.17.0 编译 qwlroots/waylib。
同时我们放弃了对 deepin-kwin wayland 的支持(更新 dde-session 后会屏蔽入口),DDE 所有 wayland 相关的支持均由 Treeland 提供。
treeland 目前是技术预览阶段的项目,提供了输入法的抽象层。目前,deepin-im 仅期望在 treeland 环境下使用。它会设置 QT_IM_MODULE
等环境变量的值来影响实际使用的输入法模块。
如果您希望得到移植相关的帮助,请考虑加入我们 DDE 移植小组的在线交流群(下列房间有桥接,任选其一即可),一起展开相关的交流:
#dde-port:deepin.org
本月对 NixOS DDE 做了进一步完善,已经比较适合在实体机上使用了。
现在 deepin v23 的版本即将发布,github 大部分 DDE 软件已经升级到了 23 版本,由于 20 和 23 版本不完全兼容,dde-nixos 将使用 v20 分支继续维护/测试 v20 版本的 DDE, main 分支尝试 v23 版本。
目前的主要工作是将 v20 版本的移植工作转移到上游,方便更多用户使用。同时 review 机制也可以找到并处理现有写法的不规范之处。Nixpkgs 合并进程请关注:https://github.com/linuxdeepin/dde-nixos/issues/9
目前已经有一部分应用可在官方仓库下载。
此外 @SamLukeYes 构建了 NixOS DDE 的 iso,可以直接使用: https://github.com/SamLukeYes/nixos-dde-iso/releases/tag/22.11.20230113
dtk
create icon [] engine failed.[theme:]
问题dde-control-center:
dde-daemon
deepin-kwin 相关软件:
dde-account-faces
deepin-system-monitor
配置 Garnix CI
gio-qt
deepin-boot-maker
dpa-ext-gnomekeyring
deepin-font-manager
dde-file-manager
dde-app-services
dde-network-core
其他:
qt5integration 未全局安装,安装后虽然 qt 主题无问题,但是会导致启动器缺失图标等问题。建议 qt 继续使用 breeze 主题
目前 deepin-greeter 无法正常使用,不过使用其他主题或者用 sddm 也是可以启动 DDE 的。
deepin-kwin 的问题,等待修复。通过控制中心关闭再打开特效,可以临时解决。
snipets 我愿意称为程序员的ctrl+c ctrl+v最大的竞争对手,sniptes适用于遇到很多重复代码却又没法去提取代码特点抽象成类的情况。比如写注释的时候。
这是一个极好的工具用于高效率办公(摸鱼)
然后你就需要选择对应的语言,这里我以doxygen注释文件为例子: 打开之后会得到这样一个文件:
{
// Place your snippets for doxygen here. Each snippet is defined under a snippet name and has a prefix, body and
// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
// same ids are connected.
// Example:
// "Print to console": {
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
}
这个文件都是注释组成,自然也没有任何功能,我们要做的是对其进行修改,以支持我们自己的代码片段
先以一个比较简单的例子作为内容:
{
// Place your snippets for doxygen here. Each snippet is defined under a snippet name and has a prefix, body and
// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
// same ids are connected.
// Example:
// "Print to console": {
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
"dox dtkwidget": {
"prefix": "da",
"body": [
"@fn void Dtk::Widget::DAlertControl::${2:function}",
"@brief ${3:info}"
]
}
}
我们来逐行解释:dox dtkwidget指的是这个代码片段的命名,你可以使用任何你喜欢的命名来代替它
然后就是一个键值对 “prefix” 的值一般是一个字符串,这个字符串也是可以自定义的,含义就是你在代码文件里面输入这个字符串(在某一行的开头)后会弹出选项询问你是否使用代码片段:比如这个就是da,你在某一行的开头打出da这俩字符,就会弹窗询问你是否替换
同时会显示对于代码片段的命名
body键值对就是最重要的一部分,这个里面就保存的你需要的代码片段,
请注意,其中每一行都代表的是你之后生成的代码的一行,如上代码片段生成的代码就是
@fn void Dtk::Widget::DAlertControl::function
@brief info
如果你现在已经复制了我的代码片段,不妨新建一个dox文件试试。打出da之后会弹出选项,按tab键确认之后就会出现这个代码,不过会让你填写function的值,填写完毕之后就按tab键切换到info需要你填写info的值
不过这样还不是代码片段的全部实力,它还能更强大点:
"dox about dtkwidget": {
"prefix": "dd",
"body": [
"@property ${1|QColor,void,bool|} Dtk::Widget::DAlertControl::${2:function}",
"@brief 返回${3:info}",
"",
"@fn void Dtk::Widget::DAlertControl::set${2/(.*)/${1:/capitalize}/i}",
"@brief 设置${3:info}",
"@sa DAboutDialog::${2:function}"
]
}
比如这样
你可以自己试试这个会发生什么
对的 它还支持正则表达式的替换
现在看看我正在用的doxygen的代码片段
{
"dox about DtkGui": {
"prefix": "dd",
"body": [
"@property Dtk::Gui::DDciIconPalette::${2:function}",
"@brief ${2}属性",
"@sa READ方法: void Dtk::Widget::DDciIconPalette::${2:function}",
"@sa WRITE方法: void Dtk::Widget::DDciIconPalette::set${2/(.*)/${1:/capitalize}/i}",
"",
"@fn ${1|QColor,void,bool|} Dtk::Widget::DDciIconPalette::${2:function}",
"@brief 返回${3:info}",
"@sa DDciIconPalette::${2:function}",
"",
"@fn void Dtk::Widget::DDciIconPalette::set${2/(.*)/${1:/capitalize}/i}",
"@brief 设置${3:info}",
"@sa DDciIconPalette::${2:function}"
]
},
"dox dtkwidget": {
"prefix": "da",
"body": [
"@fn void Dtk::Widget::DDciIconPalette::${2:function}",
"@brief ${3:info}"
]
}
}
我可以通过这个代码片段一键生成属性的get和set方法的doxygen注释
自小组成立以来,已经为 DDE 的移植做出了很多贡献,本文做出了一些总结。如有补充或批改,可向 sig-dde-porting 提出 pr。
NixOS 的移植从今年 3 月开始,到现在已经有了实用的可能,今后会用一篇文章单独介绍。未来会每月更新进展,关注的同学可以订阅本站 rss。
deepin-system-monitor,dde-clipboard,dde-session-shell…
29 个相关 pr https://github.com/linuxdeepin/developer-center/issues/3167
16 个相关 pr https://github.com/linuxdeepin/developer-center/issues/3374
大约 8 处
10 个相关 pr https://github.com/linuxdeepin/developer-center/issues/3345
至少 17 个相关 pr,事实上应该远多于 17,存在多个修改顺便提在一个 pr 的情况。
4 处以上
解决 2 处,但仍有 1 处难以处理(https://github.com/linuxdeepin/dde-session-shell/pull/120)
justforlxz 已经多次修复 dde-kwin 对 kwin 的适配问题,但每次 kwin 每次更新都会重新带来很多问题。正在移植中的 deepin-kwin 将会解决这个麻烦,目前可以使用 Arch(aur)或者 dde-nixos 先行体验。
dtkcore:
dde-control-center:
deepin-movie:
dde-grand-search:
deepin-screen-recorder:
修复 GStreamer 音频播放:
deepin-editor:
deepin-compressor:
修复个别图标丢失的问题(部分 dci 图标需要 qtimageformats 支持)
这是第一篇 deepin-m1 sig 的博客,我非常的激动,因为 deepin 现在已经可以在 m1 设备上启动了。
目前在 m1 上启动 Linux 的项目进展最快的是 Asahi Linux,他们是 Linux m1 的项目发起者,同时也是 Asahi Linux 的维护者,目前 Asahi Lina 正在努力开发 m1 GPU 驱动,已经实现了绝大部分底层的功能,正在做渲染队列的工作,相信很快就可以为 Linux 带来开源的 m1 GPU 驱动。
debian 和 fedora 也基于 Asahi installer 制作了发行版本,我们的工作也是从这里开始的。
经过分析,发现 Asahi installer 已经预留了更换 rootfs 的接口,这使得我们的工作异常顺利,很快便完成了第一版的安装文件。
目前 m1 启动 Linux 的流程是先启动 Asahi m1n1,由 m1n1 启动 u-boot,再由 u-boot 启动 grub。
m1n1 是一个非常不错的项目,可以通过 usb 进行串口调试,方便进行驱动逆向和调试,也可以测试启动 elf。
在 m1 上安装 Linux,需要先进入一次 macOS 的恢复模式,利用恢复模式将文件内容写入,目前这已经是最好的解决方案了,目前小组正在整理相关文档和脚本,预计下个月可以对外提供正式的安装脚本和视频教程。还有很多功能没有准备好,例如一些 x86 软件无法运行,m1 只支持 16k 页内存等,可能会带来很多软件的兼容性问题,我们也欢迎更多的人加入 deepin-m1 sig 组中,提供更多的帮助。
enjoy live!
这是一个模板文章。各个 SIG 在实际使用此博客模板时可根据实际需求对此模板进行任何调整。
我们要求 deepin 社区中的小组每季度至少能有一到两次对公众公开的小组成果展示,用以分享成果,使得社区大众均能受益。通过使用此博客模板,SIG 即可直接在自己的小组博客站点中提供小组成果的相应博客介绍,而 SIG 委员会以及其它感兴趣的小组即可直接利用 RSS 订阅来获得相应的内容更新。
对于成果公示类的文章,您即可通过“成果公示”或类似的标签来标记文章,这样,在此标签内的文档就会被生成到同一标签类别的 RSS 之中,以供订阅了。
这是一个模板文章。各个 SIG 在实际使用此博客模板时可根据实际需求对此模板进行任何调整。
我们要求 deepin 社区中的小组每季度至少能有一到两次对公众公开的小组成果展示,用以分享成果,使得社区大众均能受益。通过使用此博客模板,SIG 即可直接在自己的小组博客站点中提供小组成果的相应博客介绍,而 SIG 委员会以及其它感兴趣的小组即可直接利用 RSS 订阅来获得相应的内容更新。
对于成果公示类的文章,您即可通过“成果公示”或类似的标签来标记文章,这样,在此标签内的文档就会被生成到同一标签类别的 RSS 之中,以供订阅了。
这是一个模板文章。各个 SIG 在实际使用此博客模板时可根据实际需求对此模板进行任何调整。
我们要求 deepin 社区中的小组每季度至少能有一到两次对公众公开的小组成果展示,用以分享成果,使得社区大众均能受益。通过使用此博客模板,SIG 即可直接在自己的小组博客站点中提供小组成果的相应博客介绍,而 SIG 委员会以及其它感兴趣的小组即可直接利用 RSS 订阅来获得相应的内容更新。
对于成果公示类的文章,您即可通过“成果公示”或类似的标签来标记文章,这样,在此标签内的文档就会被生成到同一标签类别的 RSS 之中,以供订阅了。
生成 Config.cmake 文件路径要求与 pkg-config 一致
相关修改:
cmake 官方提供了 CMakeFindDependencyMacro 模块,专门用在 Config.cmake 文件中,find_dependency 和 find_package 用法完全相同,因此可以简单的把原来的 find_package 替换成 find_dependency。
find_dependency 的优点是如果 A 的 Config.cmake 寻找 B 的,如果失败 find_package 只会提示 B 的错误,而 find_dependency 还在报错中输出调用链,清晰显示是谁在找 B。
find_dependency 应该在 set 路径之后。
与 pkg-config 的 Requires 类似,这里只 find 传播的构建依赖。
使用 FULL 版本的 GNUInstallDirs 变量虽然正确,但还有一个缺陷,生成的是绝对路径,库必须安装到对应目录才可以。而 configure_package_config_file 可以自动计算相对的路径,适用性更广泛。
configure_package_config_file(misc/PkgNameConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/PkgNameConfig.cmake
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/PkgName"
PATH_VARS INCLUDE_INSTALL_DIR TOOL_INSTALL_DIR
)
INSTALL_DESTINATION 是 Config.cmake 的安装路径,但这里并不会安装,只是用来计算相对路径的,所以 install 还是需要写的。
PATH_VARS 传入 PkgNameConfig.cmake.in 里会用到的路径变量。
为了使用 configure_package_config_file,Config.cmake.in 也需要做出以下变化:
在开头写一行 @PACKAGE_INIT@,这会展开生成 CMakePackageConfigHelpers 提供的宏,包括set_and_check,check_required_components。
使用 set_and_check 替代 set 设置路径,可以在引入时检查对应的路径文件是否存在。(注意如果拆包了其他包的文件就不要 check 了)。
路径变量前面加 PACKAGE,如 @INCLUDE_INSTALL_DIR@ 改成 @PACKAGE_INCLUDE_INSTALL_DIR@,需要上面 configure_package_config_file 的 PATH_VARS 参数传进来。
文件后面使用 check_required_components(PkgName) 检查组件,即使没有拆分组件也应该检查,明确告诉 cmake 该包没有组件。
对于新增的库,建议使用新式 cmake 写法,使用 Targets,而非手动设置路径:
建议参考: Installing a Config.cmake file
find_package 有两个模式,Modules Mode 和 Config Mode,在 Modules Mode下,find_package(PkgName) 会寻找命名为 FindPkgName.cmake 的模块,由此模块负责寻找,这种模块一般是由 cmake 官方提供或者调用者自己编写。Config Mode 就是寻找 PkgNameConfig.cmake 模块了,由库自己提供。
find_package(DtkCore)
message("${DtkCore_VERSION}") # 6.2 以前没有提供
message("${DtkCore_LIBRARIES}")
message("${DtkCore_LIBRARY_DIRS}") # !没有提供
message("${DtkCore_INCLUDE_DIRS}") # !没有提供
find_package(Dtk REQUIRED Core Gui Widget)
# 与 pkg_check_modules 不同,后面是同一(组)软件提供的不同 components,等价于:
find_package(Dtk)
find_package(DtkCore)
find_package(DtkGui)
find_package(DtkWidget)
find_package 提供的变量请检查 Config.cmake 提供了什么,不像 pkg_check_modules 那样命名统一,在 6.2 以前,提供 DTKCORE_INCLUDE_DIR, 6.2 之后使用 DtkCore_INCLUDE_DIR(旧版变量仍保留)。
使用 find_package 引入 dtk 的软件,如果用了 DtkCore_INCLUDE_DIRS 请修改,这是 pkg_check_modules 引入才有的变量,另外 DTKCORE_INCLUDE_DIR 升级后 建议换成 DtkCore_INCLUDE_DIR。Gui,Widget 同理。
参考资料:
对于没有提供 pkg-config 也没有提供 Config.cmake 并且 cmake 官方没有提供对应模块的,建议自行写一个 FindXXX.cmake 模块
通过 find_path,find_library 函数计算出 foo_INCLUDE_PATH, foo_LIBRARY。
通过 FindPackageHandleStandardArgs 模块提供的 find_package_handle_standard_args 根据 foo_INCLUDE_PATH, foo_LIBRARY 是否有值设置 foo_FOUND,这样是让 find_package 识别此模块所需要的。
一般会把 foo_INCLUDE_PATH, foo_LIBRARY 标记为高级(mark_as_advanced),不再 cmake gui 显示。
编写模块自由度很高,还可以根据需求检查 check_function_exists,check_symbol_exists 影响 foo_FOUND 而且只需要编写一次,其他项目可以直接复用。
修改示例:
使用 dconfig_override_files 请不要忘记通过 find_package(Dtk)
引入 dtkcommon 提供的模块,而不是靠 DtkWidget 的传播依赖(实际上不应该传播 dtkcommon 的)。