wxWidgets 打包指南
构建服务教学 - 技巧和花样 - 跨发行版打包 - Debian 打包指南 - 打包检查
桌面菜单分类 - 打包常用的 RPM 宏 - 小脚本片段 - SysVinit 脚本 - 源代码服务
OBS 打包互助问答 - 打包黑名单
目录
wxWidgets 变种
wxWidgets 存在着多种应用程序二进制接口 ABI 和应用程序编程接口 API 互不兼容的变种。如果您忽略了这个事实,然后就去编译你自己的 wxWidgets
共享库,很有可能会与系统的函数库不兼容导致安装冲突或者程序崩溃。这就是你为什么需要本教学中的一些额外步骤的原因。
根据你选择的开发包,它会链接到某个特定的 wxWidgets
应用程序二进制接口变种上。自 openSUSE 11.4 起将 wxWidgets
的三个变种被放在不同的包中分发。
STL 变种
带有标准模板库界面和 Unicode 的 wxWidgets-devel
是上游推荐的新应用程序二进制接口(ABI)。
wx container 变种
wxWidgets-wxcontainer-devel
包含了过时的 wx container 界面和 Unicode 支持。
ANSI 变种
wxWidgets-ansi-devel
包含了过时的 wxcontainer 界面却没有 Unicode 支持,目前已经非常中古了。(Factory 里已经没有包在链接到它了。)ANSI 变种只编译了 wx container 应用程序二进制接口支持。
Python 裙带包
python-wxWidgets
目前基于 STL 变种。其他的变种没有编译。
其他版本
你也可以在 OBS 的 X11:wxWidgets
中找到其他的 wxWidgets
版本分支。
编译依赖
你应该首先尝试 wxWidgets-devel
(它是推荐的标准库版本,干净的代码用它编译不会有问题)。
只有包不能编译或者不能运行时才用 wxWidgets-wxcontainer-devel
。如果包里的代码把 wxString
等同于 char*
,那么你需要使用 wxWidgets-ansi-devel
。后面两个都是过时的版本。
注意 wx-config
应该用参数来调用 Unicode/ANSI 变种,但是目前没有办法来检测,某个包是不是兼容标准库版本的,还是仍然需要过时的 wx container 的。
spec 文件的特殊要求
根据你使用的是标准库还是 wxcontainer 变种,函数库切换了应用程序二进制接口 ABI,但函数名却没有切换。这会导致很多恶心的冲突。
这就是为什么 openSUSE 把函数库放到了专用的文件夹里的原因,因为这样包就可以依赖某个特殊版本的函数库了。但是 RPM 不喜欢这种方式,也不能理解如何去使用 RPATH 来从同名的多个函数库和二进制文件中捡出正确的版本。因此每个基于 wxWidgets 的包都必须像上面那样修复编译依赖,然后添加如下两行来修复依赖关系:
%define _use_internal_dependency_generator 0 %define __find_requires %wx_requires
如果没有上面两行,ZYPP 和 RPM 就不知道应该给你的软件包安装哪个变种的函数库了。这时你会遇到函数库缺失错误。
openSUSE 老版本
老版本的 openSUSE 只有一个开发包 - wxGTK-devel
,相当于 wxcontainer 和 ANSI 变种混在一起。由于应用程序二进制接口不兼容的问题没有分发标准库版本。python-wxWidgets
在老版本里叫做 python-wxGTK
。
上面提到的那两行不能在 openSUSE 11.4 以下使用。应该用版本代码 %if 0%{?suse_version} >= 1140 标记掉。
第三方软件包
第三方软件包会随意链接 ABI 变种,然而你却不一定知道哪个是正确的。它们需要函数库被放到标准的函数库路径里面。为了让这样的第三方库与 openSUSE 默认提供的 wxWidgets 变种兼容,这时就自动会安装 compat</compat> 包来添加特殊的 ABI 变种路径到 <code>ld.so
路径。但事实上你只可以安装使用 openSUSE 默认提供的 ABI 变种编译出的第三方软件包。
如果你的包需要 compat</compat> 包,那你可能就是搞错了。大多数时候都是你忘记了添加上面提到的两行到 spec 文件。
实例
针对 openSUSE 11.4 及以后版本的 spec 片段:
BuildRequires: wxWidgets-devel %define _use_internal_dependency_generator 0 %define __find_requires %wx_requires
与老版本的 openSUSE 兼容的 spec 片段:
%if %suse_version >= 1140 BuildRequires: wxWidgets-devel %define _use_internal_dependency_generator 0 %define __find_requires %wx_requires %else BuildRequires: wxGTK-devel %endif
通过使用 projectconf 来降低了 spec 复杂度的,与老版本兼容的代码片段:
BuildRequires: wxWidgets-devel %if %suse_version >= 1140 %define _use_internal_dependency_generator 0 %define __find_requires %wx_requires %endif
相关的 osc prjconf 内容:
%if 0%{?suse_version} < 1140 Substitute: wxWidgets-devel wxGTK-devel Substitute: wxWidgets-wxcontainer-devel wxGTK-devel Substitute: wxWidgets-ansi-devel wxGTK-devel wxGTK-compat Substitute: python-wxWidgets python-wxGTK %endif