让ubuntu也来帮gentoo编译
最近,貌似关于gentoo的新闻越来越多了。刚又听说,chrome OS的宿主系统已经从ubuntu转向gentoo了,其实,我对这个倒是一点都不感到意外,gentoo对于这种特定的应用,可定制性显然比ubuntu强很多,让我来选的话也会选gentoo的。只是觉得一向低调的gentoo被google这么一搞,也许以后都没有办法再低调了,哈哈。
好像有点扯远了,说到gentoo,大家肯定会想到无休止的编译,也确实,gentoo的编译是比较费时间的,尤其是在性能不怎么强悍的机器上,比如跑着chrome的上网本里。如果你另外有几台强悍些的台式机或者服务器的话,其实可以把编译的工作分担一部分给强悍的机器。这时候就要用到distcc了。
distcc是一个通过网络进行分布式编译的工具,它包含两部分,一部分是服务端程序 distccd,一部分是客户端程序 distcc。大致的原理就是,distcc连接一个或多个distccd,有编译任务的时候,distcc依次并行地把C或C++文件分发给各distccd,distccd调用它们本地的编译器编译出 .o 文件以后,再发回给distcc,另外,configure和link等工作还是由客户端自己来完成。
这样一来,对各服务端的系统也就有了一个额外的要求:必须保证服务端和客户端的gcc版本是一致的,否则出来的.o肯定link不了啊,呵呵。
如果你的客户端和服务端都装的是gentoo,采用的一样的架构和keywords,那其实这个要求还是很好满足的:两边都升到最新即可,这样配置方法可以参考官方文档。
但是如果你想用装着ubuntu、fedora、RHEL等发行版的服务端的话,就有点困难了,gentoo如果开了~x86的话,gcc的版本很容易就比这些发行版高出一大截了。
本文就是要解决这个问题的:
解决的思路,就是利用chroot,在各发行版里构建一套没有内核的gentoo系统(因为有kernel也用不着嘛),然后把里面的编译环境都升级到最新,再在里面安装运行distccd。
条件是你需要有server的root权限。
方法其实也不难,大致如下:
#建立gentoo的根目录,这里最好有>1.5G的硬盘空间,不然会不够用 mkdir gentoo cd gentoo #可以从 http://www.gentoo.org/main/en/mirrors.xml 这里选择速度快的mirror。 #下载你需要的架构的stage3 wget http://gentoo.cs.nctu.edu.tw/gentoo/releases/x86/current-stage3/stage3-i686-20100126.tar.bz2 #下载最新的portage树,其实不下也是可以的,不过后面emerge --sync的时候会慢些。 wget http://gentoo.cs.nctu.edu.tw/gentoo/snapshots/portage-latest.tar.bz2 #释放文件 tar xvf stage3-i686-20100126.tar.bz2 -C . tar xvf portage-latest.tar.bz2 -C usr/ #清理现场 rm stage3-i686-20100126.tar.bz2 portage-latest.tar.bz2 |
然后,为了方便起见,在当前目录写一个gogentoo的脚本,内容如下,加上可执行权限:
#!/bin/bash [[ $UID == 0 ]] || { echo "Must be root to go gentoo."; exit 0; } cp /etc/resolv.conf etc/ mount -t proc proc proc/ mount -o bind /dev dev/ chroot . /bin/bash |
然后执行 sudo ./gogentoo 就进入gentoo环境了。进去以后执行:
env-update source /etc/profile #添加 ~x86 的keywords,请按需修改成你自己的。 nano /etc/make.conf #更新系统 emerge --sync emerge -avuDN world #完成以后,一般还需要gcc-config到最新的gcc版本。然后清理系统 emerge --depclean -av #最后安装distcc emerge distcc |
到了这里,服务端的软件环境就算准备完毕了,你可以对比下两边的
gcc --version |
的输出,看看是否完全一致。
不过,如果你在chroot环境下,直接执行 /etc/init.d/distccd start 来启动服务的话,多半是会遇到错误的,会提示什么udev有问题,我也没深究。不过既然不让启动服务的话,我手工启动总好了吧,于是执行:
distccd --port 3632 --log-file /var/log/distccd --log-level critical --allow client的IP -N 15 |
这样启动的distccd也照样能工作,哈哈。
以上步骤在 i686-pc-linux-gnu 的gentoo client 和 ubuntu 9.10 的server上试验通过。理论上这样做好的gentoo,应该是可以从ubuntu打包出来,到其他发行版直接用的,这样就很方便做出一个灰常强大的编译集群了,哈哈,改天试试看。
接下来就是配置你的client来使用这个server了,这个就和普通的没区别了,这里也先不讨论了,如有必要,另外再写一篇就好,呵呵。
Iven Day 在 2010年02月23日 16:09 说:【 】
真能折腾啊……
xifs 在 2010年02月23日 16:41 说:【 】
distccd很和谐。。。嘿嘿
wd 在 2010年02月23日 17:30 说:【 】
我靠,我怎么没想到,旁边n多机器呢,这就弄去,嘿嘿
Dig 在 2010年02月24日 09:53 说:【 】
你们手边怎么这么多台机器呢。。。。。
问下哦,怎么从u盘装gentoo 啊,下载了 amd64 minimal-install 的 iso ,按照文档 http://www.gentoo.org/doc/en/liveusb.xml 的方法,作成u盘,在某台非 64位的老笔记本上能引导,但在64位的某台式机上启动,就出现 Boot error ,不能安装
bones7456 在 2010年02月24日 14:25 说:【 】
检查下bios设置什么的吧
sita 在 2010年02月24日 14:19 说:【 】
嗯,用了arch,现在尽量也不用aur,虽然很好,但是很心疼
ehu4ever 在 2010年02月24日 14:55 说:【 】
这有用过funtoo的朋友不?
请说一下自己的体验……
Eth2net 在 2010年02月25日 10:08 说:【 】
有个疑问,chroot环境下开启的进程/服务,exit之后,这个进程运行在什么位置?
bones7456 在 2010年02月25日 10:38 说:【 】
如果你有把proc之类的挂进去的话,那进程也到主系统的init下面去了,你可以到主系统下面用pstree看到。
oceanboo 在 2010年02月25日 12:44 说:【 】
TNND,真折腾。
leafduo 在 2010年03月01日 16:34 说:【 】
keywords 之类的不需要一样的吧?
USE 都必须一样吗?
我觉得是直接把源码发过去,所以 USE 之类的应该无所谓的吧?
bones7456 在 2010年03月01日 16:40 说:【 】
USE用默认的就好,应该不会有影响的,但是 keywords 不同的话,可能影响gcc版本。
leafduo 在 2010年03月01日 20:43 说:【 】
噢,是说 amd64 ~amd64 这种 keywords 啊……
简明现代魔法 在 2010年03月11日 21:44 说:【 】
这个wp主题阅读起来稍稍有些麻烦..
lds 在 2011年01月01日 13:51 说:【 】
不错啊 就是没那么多电脑