wxWidgets 打包指南

跳转至: 导航, 搜索

wxWidgets 打包指南指导您如何使用开放式构建服务逐步为 openSUSE 编译使用 wxWidgets 的应用程序或函数库的软件包。

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