DDE 移植小组成果展示
自小组成立以来,已经为 DDE 的移植做出了很多贡献,本文做出了一些总结。如有补充或批改,可向 sig-dde-porting 提出 pr。
NixOS 的移植从今年 3 月开始,到现在已经有了实用的可能,今后会用一篇文章单独介绍。未来会每月更新进展,关注的同学可以订阅本站 rss。
自小组成立以来,已经为 DDE 的移植做出了很多贡献,本文做出了一些总结。如有补充或批改,可向 sig-dde-porting 提出 pr。
NixOS 的移植从今年 3 月开始,到现在已经有了实用的可能,今后会用一篇文章单独介绍。未来会每月更新进展,关注的同学可以订阅本站 rss。
对于供他人调用的库(尤其是活跃开发中,接口经常变化的)来说,版本信息非常重要。版本变化意味这接口变化。应用引入库时也应该检查版本号,方便其他人编译。比如,某个开发库 A 新增了一个头文件,在升级了这个库依赖后引入了这个头文件。外部开发者想要编译这个软件, 最后只能得到 “xxx.h not found” 的编译错误。 如果头文件命名和库名有关还好点,很多时候根本看不出来到达是那里出错了,是自己的环境被破坏了,还是自己安装的某个依赖版本太高了还是太低了,如果是,是具体哪个依赖,正确的版本又是什么。这需要花费很多时间才能解决。如果加上版本检查,在编译开始之前就可以发现问题。
在指定安装路径时,应当使用变量而非写死安装目录,以便于在不完全符合 FHS 的系统上安装,提高程序的可移植性。对于使用何种变量, GUN 提出了适用于 unix 系统的 GNU标准安装目录,GNU/Linux 上使用的就是这套标准的变体。cmake 官方提供了 GNUInstallDirs 模块,定义了一组标准的变量,用于安装不同类型文件到规范指定的目录中。
不推荐做法: 根据硬编码路径判断某个文件是否存在。比如判断 QFile().exists(/usr/bin/Foo)
。
推荐做法:根据 PATH 寻找可执行文件, 一般不需要自行读取 PATH,比如 QT 可以使用:
Exist = !QStandardPaths::findExecutable("Foo").isEmpty();
比如 glib 可以使用 find_program_in_path。
修改示例:
同样,推荐用 PATH 寻找,尽量不使用绝对路径。
Qt 的 QProcess 会自动处理 PATH 环境变量,因此 QProcess::execute("/usr/bin/touch", QStringList() << sessionCacheFile)
可以直接改成
QProcess::execute("touch", QStringList() << sessionCacheFile)
。
修改示例:
尽量不要硬编码 /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.foo.includes 提供头文件位置。xxx.h
是相对提供的路径寻找。
生成 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 可以自动计算相对的路径,适用性更广泛。
pkg-config 是一个在源代码编译时查询已安装的库的使用接口的计算机工具软件。pkg-config原本是设计用于Linux的,但现在在各个版本的BSD、windows、Mac OS X和Solaris上都有着可用的版本。
它输出已安装的库的相关信息,包括:
CMake 中有许多关于编译器和链接器的设置。当你需要添加一些特殊的需求,你应该首先检查 CMake 是否支持这个需求,如果支持的话,你就可以不用关心编译器的版本,一切交给 CMake 来做即可。 更棒的是,你可以在 CMakeLists.txt
表明你的意图,而不是通过开启一系列标志 (flag) 。