openSUSE:Build Service Concept CrossDevelopment
OBS 中的交叉构建
OBS 中的交叉构建功能是正常 OBS 开发的一部分。它允许您使用模拟器构建、测试和运行针对其他处理器架构的应用程序。模拟器已经是 OBS 的正常组成部分。由于下面描述的要求,实践证明该功能是 OBS 中进行的正常开发与附加软件包的组合来实现的。更新:按需下载和交叉开发现已提交到 svn trunk。无需安装其他版本,只需正常的 OBS 快照即可。
OBS 中的交叉构建项目
交叉构建的作者是 Martin Mohring、Jan-Simon Möller 和 Marcus Hüwe(提供完整的按需下载功能)。在 Hackweek III 之前和期间,这些概念及其实现与 OBS 团队进行了讨论和审查。按需下载功能最初独立于交叉构建开发,可以单独使用。
交叉构建的类型
- 类型 1:使用一个大型软件包在 OBS 中构建完整的软件包集。示例包括 busybox 和 uClibc buildroot 系统
- 类型 2:通过修改所有单个软件包以针对交叉目标进行构建,将包含交叉工具的完整发行版放入一个项目。无法使用针对目标平台的原始软件包。
- 类型 3:与类型 2 相比,构建系统被修改为可以构建和使用原始源软件包和二进制软件包到仓库中
- 类型 4:为了使兼容性更好,构建系统中使用模拟器来提供原始目标系统。现在,甚至可以运行原始二进制文件。还可以运行测试套件。
通过将不同范围的软件包组合在一个项目中,也可以实现这些类型的混合。
OBS 中交叉构建的要求
该项目的目标是将交叉构建支持放入 OBS 作为一种通用、正交的功能。它应该尽可能地表现得像被模拟的原始系统。
为此,OBS 中最初用于构建不同目标的发行版也应用于交叉构建。构建的新架构类型应该通过简单地选择像 arm、mips、sh4 这样的 CPU 架构(就像目前支持的架构一样)而无需过多思考来实现透明化。从技术上讲,交叉构建应该使用已经使用的技术和基础设施,例如虚拟机、模拟器、chroot 环境,用于新的目的,就像目前用于构建软件包、项目甚至完整发行版一样。
交叉构建应该可以在本地构建中使用 "osc build",也可以在服务器端构建中使用 OBS 和工作站。构建环境应该以扩展的方式用于支持交叉构建。
作为这种兼容性的一个例子,除了目前适用于 i586、x86_64 和 ppc 架构的 openSUSE 和 Debian 发行版之外,交叉构建应该能够无缝地与 arm、mips 和相同发行版的其他版本一起工作,而无需进行太多干预。对于 Debian:Etch,arm、mips、powerpc、sparc 和许多其他架构都是开箱即用的。特别是,由于其在嵌入式和移动应用中的广泛使用,arm 架构应该能够很好地工作。
非交叉构建的代码路径应该表现得与没有交叉构建时完全一样。
对于交叉构建,按需下载功能、本地二进制仓库和远程 OBS 仓库应该可以透明地使用。
关于 QEMU
Qemu 模拟器是一个开源项目,它实现了完整的系统模拟以及所谓的用户模拟,能够使其他 CPU 上运行特定操作系统的二进制文件。
模拟的 CPU 包括 arm、powerpc、x86、sparc 和不断增加的新 CPU 列表,可以在项目网站上找到。QEMU 目前可以在 linux、bsd 和 darwin 上运行。QEMU 的用户模式支持允许您在无需设置完整的可引导系统的情况下运行 linux 和 bsd 二进制文件。
在 OBS 中标记交叉构建
交叉构建只需通过在项目和软件包描述中使用构建主机或工作站的架构以外的其他架构来标记,如以下示例所示。计划将此作为调度程序和工作站配置的可配置功能。
OBS 中的按需下载功能
OBS 中交叉构建的状态
类型 1、2 和 4 的交叉构建现已成功实施和测试。还计划实施类型 3 和类型 4 交叉构建的组合,以提高性能,在完成类型 4 交叉构建实施后。已经进行了此组合的可行性测试。
通用的交叉构建代码已进入子版本库。带有交叉构建的 OBS 版本现在是正常 OBS 代码的一部分(截至 OBS 1.5 版本 - 功能冻结于 2008 年 12 月)。开发快照通过 openSUSE:Tools:{Devel,Unstable}/obs-all-svn 在 build.o.o 上提供。QEMU 副本在 openSUSE:Tools:{Devel,Unstable}/qemu-svn 下提供。
此外,我们正在研究一种更优雅的解决方案,以便在工作站/本地构建在模拟器中启动之前,将 qemu 软件包安装到 chroot 中。并且 OBS 中的 KIWI 支持也应该能够与交叉构建仓库一起工作。
最后,提供用于从 Deb 或 Rpmmd 树下载完整发行版的软件包基础和元数据的功能也将合并到交叉构建中,以便更容易地为支持多种架构的现有发行版(如 openSUSE 或 Debian)运行交叉构建。始终保留发行版的完整副本可能会导致二进制仓库服务器上的大量存储需求。例如,openSUSE 11.0 需要大约 16 GB 的软件包空间用于每个架构的完整发行版,其中大约 8 GB 是所有架构之间共享的软件包,而大约 8 GB 是每个架构所需的特定于架构的软件包。安装 Debian:Etch 用于 i586、x86_64、ppc 和 arm 可能会导致需要 40 GB 的磁盘空间,同时已经共享 noarch 软件包。
按需下载功能已部分合并并正在工作。我们已经将其用作测试基础,以更广泛地测试与交叉构建 OBS 提供的 qemu 的质量。
为了获得有关 linux 发行版可以“交叉构建化”的程度的良好数据,已经对 openSUSE 的 400 个软件包子集进行了类型 2 交叉构建实施的研究。
到目前为止,交叉构建已成功测试,可以与 按需下载、远程 OBS 和 本地复制 仓库类型一起工作。
路线图
有关交叉开发支持的路线图,请参阅 OBS 通用开发路线图。到目前为止,交叉开发支持已经进入 OBS svn 仓库。
一些实践
如果 Adrian 为 Arm 提供 Debian:Etch 软件包,则可以跳过此步骤。您需要以 root 用户身份安装软件包。我假设您有大约 55 GB 的可用硬盘空间,并且需要通过互联网下载大约 36 GB。该示例适用于具有 x86_64 处理器的 openSUSE 11.0 机器。
安装交叉构建 OBS
当前,如果您决定运行自己的 OBS,openSUSE:Tools:Devel 项目中的 obs-all-cross 软件包提供了用于可以运行交叉构建的 OBS 的即用型软件包
现在,首先保存您旧的 /etc/sysconfig/obs-server
# mv /etc/sysconfig/obs-server /etc/sysconfig/obs-server.old
现在,编辑新的 /etc/sysconfig/obs-server 文件。您有一些可能性。通常,您也会运行 x86_64 和 i586 的 OBS 调度程序,因此选择包含 armv4l 的行
## Path: Applications/OBS ## Description: define for which architectures the packages should get build ## Type: stringlist ## Default: "i586" ## Config: OBS # # This needs to be a space seperated list of all supported architectures OBS_SCHEDULER_ARCHITECTURES="i586 x86_64 armv4l"
现在您的 OBS 已经准备好再次启动。启动所有内容 ,但不要启动调度程序。
交叉构建的 "qemu" 更新
要运行交叉构建,您还需要在所有工作站节点或您打算使用 "osc build" 进行本地构建的本地主机上安装特定版本的 qemu。这些软件包也提供在 openSUSE:Tools:Devel 项目的 qemu-svn+gcc3 软件包中。
将交叉构建项目添加到您的 OBS
您现在有 3 种选择可以将项目添加到您的 obs 中以运行交叉构建
- 通过将二进制文件的本地副本放入仓库服务器中创建一个项目
- 使用远程 OBS 功能创建一个项目。由于目前官方 OBS 中没有这样的项目,因此此处未描述此方法
- 使用新的按需下载功能创建一个项目。这通常是最快的方法,并可以节省大量的磁盘空间
将带有本地副本的交叉构建项目添加到您的 OBS
现在,根据您的本地 OBS 设置,您可以修改或添加一个名为 Debian:Etch 的新项目。完成后,添加一个更新的架构记录,将新的架构 armv4l 添加到其中
# osc -A api.opensuse.org meta prj Debian:Etch >de.xml
现在使用您选择的任何编辑器编辑文件 "de.xml",并更改架构块
...
<repository name="standard">
<arch>i586</arch>
<arch>x86_64</arch>
<arch>armv4l</arch>
</repository>
...
现在将更改后的文件保存到您的本地 OBS 中。如果您使用按需下载,请将 "Packages" 文件从 Deb 发行版复制到 :full 目录下的 <arch>/:full 中。
接下来,将元 prjconf 从 api.opensuse.org 复制到您的本地 OBS
# osc -A api.opensuse.org meta prjconf Debian:Etch >de.conf # osc -A <your local ip> meta prjconf -F de.conf Debian:Etch
为了完成安装,您现在最终需要从官方 OBS 安装 x86_64 和 i586 的副本(下载大约 22 GB 并需要一段时间)
# obs_mirror_project Debian:Etch standard i586 # obs_mirror_project Debian:Etch standard x86_64
之后,应该创建并填充了适当的目录 "/srv/obs/build/Debian:Etch/standard/i586/:full" 和 "/srv/obs/build/Debian:Etch/standard/x86_64/:full",其中包含大量的 .deb 文件。
然后您还需要 Debian:Etch 的 Arm 二进制文件,位于 3 个完整的 DVD 上。下载它们(另外大约 13 GB)
# wget -c -q ftp://ftp.tu-chemnitz.de/pub/linux/debian/debian-cd/4.0_r4a/arm/iso-dvd/MD5SUMS # wget -c -q ftp://ftp.tu-chemnitz.de/pub/linux/debian/debian-cd/4.0_r4a/arm/iso-dvd/debian-40r4a-arm-DVD-1.iso # wget -c -q ftp://ftp.tu-chemnitz.de/pub/linux/debian/debian-cd/4.0_r4a/arm/iso-dvd/debian-40r4a-arm-DVD-2.iso # wget -c -q ftp://ftp.tu-chemnitz.de/pub/linux/debian/debian-cd/4.0_r4a/arm/iso-dvd/debian-40r4a-arm-DVD-3.iso
然后检查 MD5SUMS 以确保下载正确。使用以下命令挂载镜像
# mkdir ./mnt # mount -o,ro -t iso9660 ./debian-40r4a-arm-DVD-1.iso ./mnt -o loop=/dev/loop3
然后将所有名称为 "*.deb" 的文件从所有 3 个 DVD 复制到 "/srv/obs/build/Debian:Etch/standard/armv4l/:full"。最后,以 obsrun 用户身份更改所有文件的所有权
# chown -R obsrun.obsrun /srv/obs/build/Debian:Etch/standard
将带有按需下载的交叉构建项目添加到您的 OBS
如果您使用 按需下载 功能,则无需从 DVD 镜像获取完整的软件包。在 Deb 元数据格式的情况下(由下载指令中的 mtype 字段指示),您为每个架构获取一个 Packges 文件,并将其放置在 :full 目录中
..... # cd /srv/obs/build/Debian:Etch/standard/armv4l/:full # wget -c -q ftp://ftp.de.debian.org/debian/dists/etch/main/binary-arm/Packages.bz2 # bunzip2 Packages.bz2 .....
用于 arm、i586、ppc 和 x86_64 Debian:Etch 发行版的项目描述现在包含以下字段
.....
<download baseurl="http://ftp.de.debian.org/debian" metafile="Packages" mtype="debmd" arch="armv4l" />
<download baseurl="http://ftp.de.debian.org/debian" metafile="Packages" mtype="debmd" arch="i586" />
<download baseurl="http://ftp.de.debian.org/debian" metafile="Packages" mtype="debmd" arch="ppc" />
<download baseurl="http://ftp.de.debian.org/debian" metafile="Packages" mtype="debmd" arch="x86_64" />
<repository name="standard">
<arch>armv4l<arch>
<arch>i586<arch>
<arch>ppc<arch>
<arch>x86_64<arch>
</repository>
.....
运行您的第一个交叉构建
现在您完成了服务器上的操作,可以再次启动调度程序。它应该在 OBS 监视网页上显示一行:“armv4l:正在运行大约...” ,表明您的本地 OBS 服务器上的所有操作都已正确完成。调度程序现在需要一段时间才能启动并重新扫描新的二进制文件。
现在我们准备好运行第一个 "osc build" 命令进行交叉构建。为此,您需要一个能够构建 Debian:Etch 目标的软件包。我建议您将例如 openSUSE:Tools/lzma 复制到您的本地 OBS 中。然后在元 prj 数据中关闭 armv4l 目标的构建,并在软件包 lzma 中打开 arm 目标
.....
<build>
<disable arch='armv4l'/>
</build>
<publish>
<disable arch='armv4l'/>
</publish>
.....
<repository name="Debian_Etch">
<path repository="Debian_Etch" project="openSUSE:Tools"/>
<arch>i586<arch>
<arch>x86_64<arch>
<arch>armv4l<arch>
</repository>
.....
现在,检出软件包并尝试你的第一次交叉构建
$ cd <goto some local dir>
$ osc -A <local obs ip> co openSUSE:Tools/lzma
$ cd openSUSE:Tools/lzma
$ osc -A <local obs ip> build --userootforbuild --clean Debian_Etch armv4l lzma.dsc
Building lzma.dsc for Debian_Etch/armv4l
Getting buildinfo from server
Updating cache of required packages
Writing build configuration
Getting buildconfig from server
Running build
sudo /usr/bin/build --root=/var/tmp/oscbuild-root/martin/Debian_Etch/armv4l --rpmlist=/tmp/rpmlist.gpIne8 --dist=/tmp/buildconfig.8xD3vp lzma.dsc --clean
--changelog --arch=armv4l
logging output to /var/tmp/oscbuild-root/martin/Debian_Etch/armv4l/.build.log...
Memory limit set to 5418004KB
Using BUILD_ROOT=/var/tmp/oscbuild-root/martin/Debian_Etch/armv4l
Using BUILD_ARCH=armv4l
jupiter started "build lzma.dsc" at Mon Sep 1 01:42:01 CEST 2008.
processing specfile /tmp/obs-update/tmp/openSUSE:Tools/lzma/lzma.dsc...
running changelog2spec --target debian --file /tmp/obs-update/tmp/openSUSE:Tools/lzma/lzma.dsc
...............cut off in the middle.................
dh_compress
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dpkg-gencontrol: warning: unknown substitution variable ${misc:Depends}
dh_md5sums
dh_builddeb
dpkg-deb: building package `lzma' in `../lzma_4.32-6_arm.deb'.
dpkg-genchanges
dpkg-genchanges: including full source code in upload
dpkg-buildpackage: full upload; Debian-native package (full source is included)
/var/tmp/oscbuild-root/martin/Debian_Etch/armv4l/usr/src/packages/DEBS/lzma_4.32-6_arm.deb
祝贺你,你成功了。
你可以在 buildroot 内部试验生成的 chroot 环境
$ sudo chroot /var/tmp/oscbuild-root/martin/Debian_Etch/armv4l/
root's password:
# uname -a
Linux jupiter 2.6.25.11-0.1-default #1 SMP 2008-07-13 20:48:28 +0200 armv5tel GNU/Linux
# file /bin/bash
/bin/bash: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.1, dynamically linked (uses shared libs), for GNU/Linux 2.4.1, stripped
# ldd /bin/bash
libncurses.so.5 => /lib/libncurses.so.5 (0x42084000)
libdl.so.2 => /lib/libdl.so.2 (0x420cf000)
libc.so.6 => /lib/libc.so.6 (0x420db000)
/lib/ld-linux.so.2 (0x40081000)
我们现在有一个很棒的新玩具可以玩了!继续愉快地编程吧。