Distcc cross-compling between x86_64 and x86 for gentoo

Cross-compiling是一件比较麻烦的事情,需要正确的cross architecture toolchains才能顺利进行。在Gentoo上,由于有工具crossdev的帮助,只要emerge crossdev && crossdev -t x86_64就可以生成cross architecture toolchains。因此,在所有的机器都是gentoo的情况下,按照Gentoo官方Howto——DistCC Cross-compiling Guide进行设置就可以了。

但是在利用distcc进行x86_64和x86之间的cross compiling时,可以有简单一些的解决办法。特别是当helper boxes并非gentoo,而是其他发行版比如debian时,因为没有相应的方法生成工具链,必须用别的办法才行。

distcc在helper box上只做两件事情——对源文件编译和汇编,其他工作如预处理和连接都是在运行emerge命令的机器上完成的。x86_64和x86的gcc不需要其他工具链的协助就可以互相生成目标代码(选项 -m32 -m64),因而不需要工具链的支持就能配置好cross-compile。可以参考gentoo-wiki上的一篇文章:TIP AMD64-x86-distcc,该文是利用amd64的机器帮助x86编译(我是反过来)。文章提到必须是multilib的amd64 profile,我猜可能不需要multilib的支持——因为helper box只做编译汇编,不涉及连接库和运行时库,也就不关multilib的事~~另外该文的方法必须在emerge时设置CC=gcc CXX=g++ CFLAGS=”-m64 ${CFLAGS}”。这些改动都不是很安全或者方便。

假设本机的arch是amd64,本机需要emerge,本机是distcc的client;提供distcc服务的helper boxes则是i686的arch。Gentoo Portage一般采用${CHOST}-gcc的形式调用gcc。

  1. 在helper box不存在x86_64-pc-linux-gnu-gcc的情况下(比如是debian或是没有用crossdev生成工具链的gentoo),直接进行distcc就会出现helper box找不到x86_64-pc-linux-gnu-gcc的错误。一种解决方法是设置本地的CC=gcc CXX=g++,但这样做portage会提醒将来可能会出现问题。
  2. 在helper box存在x86_64-pc-linux-gnu-gcc的情况下(这显然是gentoo helper box利用crossdev生成了工具链),设置CC=gcc CXX=g++又反而不对了(这会调用helper box的native gcc)。

所以直接设CC=gcc CXX=g++会带来问题。为了让helper box上不论是否有x86_64-pc-linux-gnu-gcc都能一致的操作,可以采用的办法是让helper box去适应本机(而不是本机去适应helper box),即在所有的helper box上建立x86_64-pc-linux-gnu-gcc。

另一点是-m64这个选项:本机或crossdev生成的x86_64-pc-linux-gnu-gcc都不需要-m64这个选项(默认生成64位代码),但i686的gcc必须用-m64才能生成64位代码。但直接在本地的CFLAGS中加上-m64是危险的。一个仍然不太安全(最安全自然是用crossdev)的方法是把-m64选项放到helper box里。

最终需要做的事情如下:

  • 本地设置(运行emerge的机器,x86_64):让distcc总是调用x86_64-pc-linux-gnu-gcc。具体原因和做法见DistCC Cross-compiling Guide,这里给出命令:
    cd /usr/lib/distcc/bin
    rm c++ g++ gcc cc
    vim x86_64-pc-linux-gnu-wrapper

    其中x86_64-pc-linux-gnu-wrapper的内容为:

    #!/bin/bash
    exec /usr/lib/distcc/bin/x86_64-pc-linux-gnu-g${0:[-2]} "$@"

    然后运行

    chmod a+x x86_64-pc-linux-gnu-wrapper
    ln -s x86_64-pc-linux-gnu-wrapper cc
    ln -s x86_64-pc-linux-gnu-wrapper gcc
    ln -s x86_64-pc-linux-gnu-wrapper g++
    ln -s x86_64-pc-linux-gnu-wrapper c++
  • distcc服务器设置:对于有crossdev的机器,crossdev -t x86_64就可以;对于没有或不想用crossdev的,做法如下:
    cd /usr/local/bin
    vim x86_64-pc-linux-gnu-wrapper

    其中x86_64-pc-linux-gnu-wrapper的内容为:

    #!/bin/bash
    `echo $(basename $0) |sed -e "s/x86_64-pc-linux-gnu-//"` -m64 "$@"

    然后运行

    chmod a+x x86_64-pc-linux-gnu-wrapper
    ln -s x86_64-pc-linux-gnu-wrapper x86_64-pc-linux-gnu-gcc
    ln -s x86_64-pc-linux-gnu-wrapper x86_64-pc-linux-gnu-g++
    ln -s x86_64-pc-linux-gnu-wrapper x86_64-pc-linux-gnu-c++

另外为了方便选择emerge时是否distcc,可以利用alias代替修改make.conf。在/etc/bash/bashrc(或其他相应文件)加上

alias demerge='FEATURES="distcc" MAKEOPTS="-j5" emerge'
发表评论?

0 条评论。

发表评论


注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">

Switch to our mobile site