在Gentoo下交叉编译
“Sometimes it pays to stay in bed in Monday, rather than spending the rest of the week debugging Monday’s code. “ – Dan Salomon
前几天揽了个“脏活”,交叉编译raspbian的文件系统镜像。好久没干过这么繁琐的 事了,写篇日志分享一下gentoo下如何更好的解决交叉编译问题。
嵌入式系统的编译环境
为某个平台开发软件,首先需要一个编译环境。一般来说,编译环境包括三部分:工具 链/运行环境/编译方法。对于嵌入式系统来说,常见的编译环境有三种:
本地环境。如很流行的Ubuntu for ARM,利用官方制作好的目标机镜像(通常包含了 编译环境),直接在目标机上编译/安装软件,与PC机开发完全一样。这种方法简单省 事。缺点也显而易见,编译速度慢,耗时长,特别是较大的软件包(如xbmc)的时候, 程序员不是停下来喝杯咖啡就可以收摊,恐怕得打场通宵dota后才能看到结果 了…(或许distcc能有所改善)
虚拟环境。在PC上建立目标机的虚拟环境,如QEMU-ARM,然后chroot到虚拟环境 中编译/安装软件。这种方法利用了PC的处理能力,速度比本地环境要快得多,但 QEMU并不能完美的模拟目标机环境,如不支持某些系统调用等,这可能导致它不能 正确的编译某些软件。
交叉编译。为目标机交叉编译软件,这是最常规的办法,也是上面两种方法实现的基 础。说交叉编译是“脏活”,是因为需要手工解决软件包的所有依赖问题,手工编译 每一个软件包,并且解决软件包对目标机兼容问题… 看网上铺天盖地关于求教/指导 某个软件包如何正确交叉编译就知道,有多少程序员在被它虐?
gentoo下的交叉编译
gentoo是一个metadistribution,从源代码构建整个系统,同时支持很多不同的体 系如alpha/arm/hppa/ppc/sh/sparc/s390等,也为交叉编译提供了便利的工具,这是 其它二进制发行版没有办法比拟的(scratchbox也显得弱爆了)。
gentoo下的交叉编译通过crossdev和portage来实现。portage带来的好处是自 动解决依赖和自动升级更新系统,跟本机环境一样。
制作工具链
crossdev用来制作交叉工具链,并且还提供了交叉编译环境下的emerge的辅助脚本。如 下编译arm平台的工具链:
$ sudo crossdev -t arm-supertux-linux-gnueabi
这样,crossdev最终制作了符合“gentoo规范”的arm交叉编译器。
运行环境
crossdev生成/usr/arm-supertux-linux-gnueabi/目录作为目标系统 $buildroot。编译后生成的目标会被emerge到$buildroot,编译时依赖的环境(如 链接库/头文件/pkgconfig等)也都在$buildroot。
交叉编译
有了工具链/运行环境,使用的crossdev封装过的emerge,就可以自由的emerge了。 如交叉编译bash:
$ sudo emerge-arm-supertux-linux-gnueabi -avu bash
porage会自动把bash的依赖如ncurses/readline一起emerge到$buildroot。 交叉编译就是变得如此简单…
碰到的问题
站在巨人的肩膀上可以看的更远,前提是我们先要爬上巨人的肩膀。portage是一个快 速更新迭代的系统,并不完美,维护者没有办法测试每个软件包的所有兼容性。所以, 当你想安装一个图形环境如$emerge -avu enlightenment时,很可能会出现错误。但 portage提供了细粒度的控制帮助解决这样的问题。下面是我碰到过一些情形和解决方 法:
由于软件包的环境变量引起的问题,如链接库指向了/usr/bin,而非 $buildroot。可以配置$buldroot/etc/portage/env/目录下相应的文 件,portage会自动source该文件,从而改变编译时的环境。
portage没有包含该软件或portage自身的bug引起,如默认使能了某个在目标机 平台不能使用的特性。建立一个针对目标机的overlay,自己编写相应软件包的 ebuild文件指导portage进行交叉编译。
当某个软件包分阶段编译时,如perl编译时先生成miniperl,通过miniperl最 后生成perl目标映像。由于miniperl被交叉编译器生成目标机的映像,正常情况 下不能主机环境中继续运行生成最终的目标映像。这就要借助qemu-arm+binfmt模 拟目标机环境,让miniperl在主机环境中也能无缝的运行。
从形式上看,处理上面几种情况,也是“脏活”。不仅需要了解该软件包的编译环境, 还需要了解portage的原理,还要知道ebuild的书写语法。但是,与传统的交叉编译 方式比起来,这是一劳永逸的工作,别人使用我的运行环境和overlay,即不需再做什 么就能生成最终的目标机系统。
三年前,使用以上的方法上制作了gentoo+xserver+enlightenment的目标机系统,并 在mini2440的开发板上运行起来。这种方法也大大减少了编译目标机系统中200+的软 件包的编译时间和维护工作量。
新的portage系统引入了新的特性,如果有谁在新的实践中发现了新的问题或主意,欢迎跟 我联系?
~EOF~ 2013.03.12
阅读(4556) | 评论(2) | 转发(0) |