提高可移植性的建议[目录]

使用硬编码的路径会因为操作系统的不同而导致可能无法正常使用,比如 Arch Linux 不使用 /usr/libexec (对应文件会放/usr/lib),NixOS 不使用 /lib, /bin, /usr, 等等。 此外如果使用 linglong 或者 flatpak 等特殊格式打包,同样无法使用传统的硬编码路径。 为了可移植性,应当尽可能避免硬编码。 对于安装文件路径,qmake 应尽可能使用 PREFIX 变量而非绝对路径,cmake 除了 CMAKE_INSTALL_PREFIX 外,还提供对于移植非常友好的 GNUInstallDirs 模块,所有的硬编码都应当改用 GNUInstallDirs: 安装路径使用 GNUInstallDirs 既然安装路径不同系统有区别,源码中的硬编码自然也需要尽可能避免,遵守 XDG 规范可以避免大量硬编码: 源码中的硬编码路径 规范导出和使用 pkg-config 规范导出和使用 Config.cmake 规范版本相关信息 cmake 对一些编译参数有封装,官方的封装有着更好的适用性,比如对不同编译器平台同样功能的参数可能有区别,还可以检查编译器是否支持。 规范编译参数

DDE v23 正式版移植简要指南

编辑的话请把自己的名字加到作者名单里 DDE v23 首个正式版即将随 deepin v23 发布(你阅读到这个文章的时候可能已经发布了)。为了方便各个其它发行版的包维护者可以更方便的移植 DDE 到对应的发行版,这里提供一篇简要的移植指南,用以描述常见的移植问题和解决方案。 下面对项目名称的称呼均以 GitHub 对应的原始仓库名为准。 {.note} 概览 即便本次从版本号字面来看可能并没有较大变动,但事实上,本次相比 beta3 -> rc 而言仍然是存在比较大的变化的。本次中,dde-shell 加载托盘插件的策略做了大幅调整,转变为通过 dde-tray-loader 加载插件,托盘区域的插件也放弃了原有的插件,转而移植并使用了来自原 UOS 20 专业版的托盘插件。此外,为了为后续的应用权限管控做准备,本次也对包括 dde-launchpad、dde-shell 等在内的项目调整了其 DSG 配置文件 所使用的应用 ID(DSG_APP_ID),故对于移植到其它发行版的情况,若存在相应的 DConfig OEM 配置则也需进行调整。另外,为了解决一些已知的开源合规问题,我们也将原本位于 dtkcore 中的日志部分分离为了一个单独的组件,名为 dtklog。 由于这些项目的版本间互相影响,我们强烈建议移植人员参照 deepin v23 正式版所使用的包版本进行打包(也务必遵循依赖顺序打包)。下面会对主要的部分进行详细说明。 需要注意的是,由于此文章编写时间早于版本发布时间,故最终版本镜像中使用的版本可能高于下面列出的版本。我们尽可能确保此文章的准确性,但若您需要获取 ISO 镜像中使用的确切软件版本列表,请挂载 ISO 后参阅 LIVE/FILESYSTEM.MANIFEST (也可能是 LIVE/FILESYS0.MAN)路径对应的文件的内容。 主要组件 DTK 与 DTK6 DTK 是 DDE 组件与应用的基础依赖,适用于 RC 的版本参照如下: package version dtkcommon 5.6.32 dtklog 0.0.1 dtkcore 5.6.32 dtkgui 5.6.32 dtkwidget 5.
Read full post

dde-nixos 近期进展公告

目前 dde-nixos 已经分叉,mian 分支进行 v23 的维护,目前主要更新了 dtk 和部分 deepin 开头的应用, dde 开头的核心应用移植暂未实现,dbus 接口不兼容,因此目前不可日常使用。 gomod 分支用于测试使用 buildGoModule 完成构建,仅验证可行性,实际使用还需要调整硬编码相关的 patch。 日常使用 DDE 需要切换 v20 分支,会优先使用已经提交到上游的应用: dde-nixos = { url = "github:linuxdeepin/dde-nixos/v20"; inputs.nixpkgs.follows = "nixpkgs"; }; 在 v20 分支,dtk 使用 5.6.3 不再升级,deepin 应用会保持最新的 v20 版的最新版本(不会上 6.0.0),dde 应用冻结为 1 月份打包时测试可用的版本,一般不再升级: 既除了 deepin 应用,其他应用只有在 v23 移植完成后再更新。 目前 NixOS 23.05 — Feature Freeze & Release Blockers 已经开始,进度请关注: https://github.com/NixOS/nixpkgs/issues/224457#issuecomment-1501383113 向上游贡献的主要调整: 调整 patch 在 dde-nixos 中,编写了 getPatchFrom, replaceAll 等函数帮助 patch 硬编码路径,但打包时为上游添加函数是难以接受的,因此所有的 patch 都需要使用 substituteInPlace 重写:
Read full post

dde-nixos 2023 年 1 月成果展示

本月对 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

Read full post

DDE 移植小组成果展示

自小组成立以来,已经为 DDE 的移植做出了很多贡献,本文做出了一些总结。如有补充或批改,可向 sig-dde-porting 提出 pr。

NixOS 的移植从今年 3 月开始,到现在已经有了实用的可能,今后会用一篇文章单独介绍。未来会每月更新进展,关注的同学可以订阅本站 rss。

Read full post

合理利用开发文件的版本信息

对于供他人调用的库(尤其是活跃开发中,接口经常变化的)来说,版本信息非常重要。版本变化意味这接口变化。应用引入库时也应该检查版本号,方便其他人编译。比如,某个开发库 A 新增了一个头文件,在升级了这个库依赖后引入了这个头文件。外部开发者想要编译这个软件, 最后只能得到 “xxx.h not found” 的编译错误。 如果头文件命名和库名有关还好点,很多时候根本看不出来到达是那里出错了,是自己的环境被破坏了,还是自己安装的某个依赖版本太高了还是太低了,如果是,是具体哪个依赖,正确的版本又是什么。这需要花费很多时间才能解决。如果加上版本检查,在编译开始之前就可以发现问题。

Read full post

在 GNU/Linux 中使用 GNUInstallDirs 优化 cmake 安装路径

使用 GNUInstallDirs.cmake模块

在指定安装路径时,应当使用变量而非写死安装目录,以便于在不完全符合 FHS 的系统上安装,提高程序的可移植性。对于使用何种变量, GUN 提出了适用于 unix 系统的 GNU标准安装目录,GNU/Linux 上使用的就是这套标准的变体。cmake 官方提供了 GNUInstallDirs 模块,定义了一组标准的变量,用于安装不同类型文件到规范指定的目录中。

Read full post

尽可能避免使用 hardcode 路径

可执行程序 判断某个可执行程序是否存在 不推荐做法: 根据硬编码路径判断某个文件是否存在。比如判断 QFile().exists(/usr/bin/Foo)。 推荐做法:根据 PATH 寻找可执行文件, 一般不需要自行读取 PATH,比如 QT 可以使用: Exist = !QStandardPaths::findExecutable("Foo").isEmpty(); 比如 glib 可以使用 find_program_in_path。 修改示例: https://github.com/linuxdeepin/dde-network-core/pull/56 https://github.com/linuxdeepin/dde-session-shell/pull/127 执行某个可执行程序 同样,推荐用 PATH 寻找,尽量不使用绝对路径。 Qt 的 QProcess 会自动处理 PATH 环境变量,因此 QProcess::execute("/usr/bin/touch", QStringList() << sessionCacheFile) 可以直接改成 QProcess::execute("touch", QStringList() << sessionCacheFile)。 修改示例: https://github.com/linuxdeepin/deepin-downloader/pull/27 动态库路径 尽量不要硬编码 /urs/lib qt 应用可以使用 QLibraryInfo::location(QLibraryInfo::LibrariesPath) 头文件 绝对不要有 #include </usr/include/xxx.h> 这种代码,c/c++ 头文件会自动在 /usr/include 里寻找,直接使用 #include <xxx.h> 。 此外,如果库提供了 pkg-config 文件,提供的 -I 参数会指定头文件位置,如果提供 Config.cmake (cmake用)文件,一般会提供 Foo_INCLUDE_DIR 变量,如果提供 .pri (qmake 用)文件,由 QT.
Read full post

规范导出和使用 Config.cmake 文件

生成 Config.cmake 文件 生成 Config.cmake 文件路径要求与 pkg-config 一致 应该提供 FooConfig.cmake.in 使用 FULL 版本的 GNUInstallDirs 变量替换路径 相关修改: use configure_file set path in DdeDockConfig.cmake 使用 find_dependency 代替 find_package 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 传播的构建依赖。 使用 configure_package_config_file 代替 configure_file 使用 FULL 版本的 GNUInstallDirs 变量虽然正确,但还有一个缺陷,生成的是绝对路径,库必须安装到对应目录才可以。而 configure_package_config_file 可以自动计算相对的路径,适用性更广泛。
Read full post

规范导出和使用 pkg-config 文件

使用 pkg-config

pkg-config 是一个在源代码编译时查询已安装的库的使用接口的计算机工具软件。pkg-config原本是设计用于Linux的,但现在在各个版本的BSD、windows、Mac OS X和Solaris上都有着可用的版本。

它输出已安装的库的相关信息,包括:

  • C/C++编译器需要的输入参数
  • 链接器需要的输入参数
  • 已安装软件包的版本信息
Read full post