Gentoo中的交叉编译利器–crossdev

  • 什么是Crossdev[I]
  • sys-devel/crossdev
    Available versions: 0.9.18-r10 ~0.9.19 **99999999
    Installed versions: 0.9.18-r10(03:44:50 PM 11/29/2009)
    Homepage: http://www.gentoo.org/
    Description: Gentoo Cross-toolchain generator

    交叉编译时很多嵌入式开发必须的工具,因为资料太少,遇到的问题又很难解决,所以交叉的开发环境一直让很多程序员头疼。我们就来了解一下gentoo下如何构建交叉编译环境。
    先说说工具链,工具链是用来组建一个系统的工具包集合,因为它们使用输入和输出连接在一起,所以称为链。通常工具链包括以下几部分:

      binutils–用来生成二进制的基本工具(包括汇编器和连接起)
      gcc–GNU编译器集(C和C++编译器)
      glibc/uclibc/newlib–系统C语言库
      linux-headers–系统文件库需要的内核头文件
      gdb–GNU调试工具

    一般的Gentoo系统都将工具链作为基础系统的一部分,并且将工具链配置为能生成本机的二进制文件。为了能编译其他平台上的二进制文件,就需要交叉工具链,Gentoo提供了一个简单但很强大的工具CrossDev来管理工具链,它可以编译安装任意GCC支持的交叉工具链,因为Gentoo将工具链的文件安装在平台特定的目录下,所以Crossdev得到的交叉工具链不会干扰到本地的工具链。手工编造一个交叉工具链太痛苦了。。。。

  • 工具链使用的环境变量
  • 工具链的环境变量总是让人很头疼,下面我们做个详细的介绍
    变量名—生成交叉工具链时的含义—生成目标平台二进制文件时的含义
    CBUILD–编译交叉工具链的平台—编译程序的平台
    CHOST–交叉工具链运行的平台—使用交叉工具链生成的二进制文件将运行的平台
    CTARGET–使用交叉工具链生成的二进制文件将运行的平台–使用交叉工具链生成的二进制文件将运行的平台(内容虽然重复,但设置它没有坏处,有些二进制包需要它)
    ROOT–将要安装的虚/路径
    PORTAGE_CONFIGROOT–portage能找到配置文件的虚/路径(如/etc/make.conf)
    若我们有个AMD64的gentoo机器,和一个想要开发程序的ARM PDA。那上面的变量可以设置如下:
    CBUILD–x86_64-pc-linux-gnu–x86_64-pc-linux-gnu
    CHOST–x86_64-pc-linux-gnu–arm-unknown-linux-gnu
    CTARGET–arm-unknown-linux-gnu–not set
    ROOT—[not set -- defaults to /]—[/path/where/you/install]
    PORTAGE_CONFIGROOT—[not set -- defaults to /]—-[/path/where/your/portage/env/for/arm/pda/is]

  • 一些术语
  • cross-compiler CHOST!=CTARGET的工具链
    canadian cross 加拿大式交叉编译CBUILD != CHOST && CHOST != CTARGET的工具链
    CBUILD build system 编译二进制文件所使用平台
    CHOST host system 运行二进制文件所使用平台
    CTARGET target system 编译得到的二进制文件将要运行的平台
    sysroot system root 编译器用来查找它的标准头文件和库的根目录
    hardfloat 系统用来处理浮点数学运算的硬件浮点单元(FPU)
    softfloat 若系统没有硬件FPU,就需要所有的浮点数使用定点数学运算近似
    PIE 位置无关的执行(-fPIE -pie)
    PIC 位置无关代码(-fPIC)
    CRT C语言运行时

  • 系统元组
  • 系统元组标记整个系统的特征,具体的内容由GNU config项目规定。具体的模式是机器(machine)-类型(vendor)-内核(kernel)-操作系统(operating system)。比如,博主我的电脑上就是i686-pc-linux-gnu.下表是一些比较常见的配置

    机器 类型 内核 操作系统
    alpha
    arm / armeb
    avr / avr32
    bfin
    cris
    hppa / hppa1.1 / hppa2.0 / hppa64
    ia64
    i386 / i486 / i586 / i686
    m68k
    mips / mipsel / mips64 / mips64el
    nios / nios2
    powerpc / powerpc64
    sparc / sparcv8 / sparcv9 / sparc64
    s390 / s390x
    sh / sh3 / sh4 / sheb / sh3eb / sh4eb / sh64
    vax
    x86_64
    gentoo
    pc
    softfloat [1]
    unknown
    elf [2]
    freebsd6.2
    linux
    mingw32 / mingw64
    uclinux [3]
    gnu [4]
    gnueabi [5]
    uclibc [6]
    uclibceabi

    来说说这其中几个比较有趣的:

      类型那部分几乎可以随便设置,
      当操作系统指定为elf时,你就可以不用操作系统,而是直接把编译出的代码放到硬件上运行。
      uclinux编译出的FLAT二进制文件,能在MMU不可用的Linux上运行
      操作系统中指定gnu表明系统库为libc
  • 言归正传,装我们的交叉编译器
  • 我们的第一步当然是
    emerge -av crossdev

    这个命令会安装所有交叉编译相关的包。在博主的电脑上,就需要安装以下包
    emerge -pv crossdev

    These are the packages that would be merged, in order:

    Calculating dependencies… done!
    [ebuild N ] dev-util/unifdef-1.20 65 kB
    [ebuild N ] sys-devel/crossdev-0.9.18-r10 0 kB

    Total: 2 packages (2 new), Size of downloads: 65 kB

    注意,crossdev只是一个工具,我们的最终目的是使用crossdev编译一个交叉工具链出来,有必要先看看帮助,直接运行crossdev命令

    # crossdev
    Usage: crossdev [options] --target TARGET
    Options:
    --b, --binutils ver Specify version of binutils to use
    --g, --gcc ver Specify version of gcc to use
    --k, --kernel ver Specify version of kernel headers to use
    --l, --libc ver Specify version of libc to use
    -S, --stable Use latest stable versions as default
    -C, --clean target Uninstall specified target
    -P, --portage opts Options to pass to emerge (see emerge(1))
    --with[out]-headers Build C library headers before C compiler?
    Stage Options:
    -s0, --stage0 Build just binutils
    -s1, --stage1 Also build a C compiler (no libc/C++)
    -s2, --stage2 Also build kernel headers
    -s3, --stage3 Also build the C library (no C++)
    -s4, --stage4 Also build a C++ compiler [default]
    Extra Fun (must be run after above stages):
    --ex-only Skip the stage steps above
    --ex-gcc Build extra gcc targets (gcj/ada/etc...)
    --ex-gdb Build a cross gdb
    --ex-insight Build a cross insight
    Target (-t) takes a tuple ARCH-VENDOR-OS-LIBC; see 'crossdev -t help'

    上面可以看到,我们能用crossdev指定binutils gcc kernel和libc的版本,还有不同的编译stage来指定不同规模的工具链。甚至在Extra Fun中包含了gdb,扩展的gcc等支持,insight是gdb的图形化接口,博主没有用过,所以不知道。
    再来看看crossdev支持的系统元组们

    # crossdev -t help
    Supported Architectures:
    - alpha - arm / armeb
    - hppa (parisc) - ia64
    - i386 / i486 / i586 / i686 (x86) - m68k
    - mips / mipsel / mips64 / mips64el
    - powerpc (ppc) / powerpc64 (ppc64)
    - sparc / sparc64 - s390 / s390x
    - sh / sh[1-5] / sh64 - x86_64 (amd64)
    Supported C Libraries:
    - glibc (gnu)
    - klibc [prob wont work]
    - newlib [bare metal/no operating system]
    - uclibc [not all arches are ported]
    Special Targets:
    - avr http://www.nongnu.org/avr-libc/
    - bfin http://blackfin.uclinux.org/
    - h8300 http://h8300-hms.sourceforge.net/
    - mingw32 http://www.mingw.org/
    - msp430 http://mspgcc.sourceforge.net/
    - nios2 http://www.altera.com/products/ip/processors/nios2/ni2-index.html
    - xc16x http://www.infineon.com/
    - ee / iop / dvp (ps2) [Playstation 2 targets]
    - ppu / spu (cell) [Cell/Playstation 3 targets]
    Softfloat toolchains:
    Include 'softfloat' in the 'vendor' field
    e.g. armeb-softfloat-linux-uclibc powerpc-booya_softfloat-linux-gnu

    不懂的话您就看看上面关于系统元组的介绍,具体我就不解释了,好了,现在看是安装。开动拉。。。。。因为博主要安装mips64el-unknown-linux-gnu的编译器,就直接运行了

    # crossdev --target mips64el-st-linux-gnu
    -------------------------------------------------------------------------------------------------------------------------------------------------------------
    * Host Portage ARCH: x86
    * Target Portage ARCH: mips
    * Target System: mips64el-st-linux-gnu
    * Stage: 4 (C/C++ compiler)

    * binutils: binutils-[latest]
    * gcc: gcc-[latest]
    * headers: linux-headers-[latest]
    * libc: glibc-[latest]

    * PORTDIR_OVERLAY: /usr/local/portage/layman/gentoo-china
    * PORT_LOGDIR: /var/log/portage
    * PKGDIR: /usr/portage/packages/cross/mips64el-st-linux-gnu
    * PORTAGE_TMPDIR: /var/tmp/cross/mips64el-st-linux-gnu
    _ – ~ – _ – ~ – _ – ~ – _ – ~ – _ – ~ – _ – ~ – _ – ~ – _ – ~ – _ – ~ – _ – ~ – _ – ~ – _ – ~ – _ – ~ -
    * Forcing the latest versions of {binutils,gcc}-config/gnuconfig … [ ok ]
    * Log: /var/log/portage/cross-mips64el-st-linux-gnu-binutils.log
    * Emerging cross-binutils …
    这是个非常漫长的过程。。。。。。。。。因为是mips64el的,遇到了glibc checkfail的问题。这个问题正在解决中,以后再汇报。
    下面假设你安装的是arm的
    #crossdev -t arm-unknown-linux-gnu

    最后,再说说
    mips64el-unknown-linux-gnu 和mips64el-st-linux-gnu。其实没有区别,你可以简单的理解为是谁制作了这个工具链,比如st就代表这个工具链是ST作的,比如,我曾经使用的一个mips64el-st-linux-gnu就是曾经从意法半导体的网站上下载的,不过现在好像链接已经没有了。而mips64el-unknown-linux-gnu是上面crossdev自己编译出来的,在gentoo的overlay中,使用的就是unknown,所以就沿用了unknown

    你可以参考下面几个链接
    http://www.gentoo.org/proj/en/base/embedded/handbook

    http://psas.pdx.edu/GentooCrossCompilerHowto/

    相关文章:

    此条目发表在 Linux系统 分类目录,贴了 , , , , , , , , , , , , , , , , , , , , 标签。将固定链接加入收藏夹。

    Gentoo中的交叉编译利器–crossdev》有 9 条评论

    1. rix 说:

      编程技术类博客似乎不是很受欢迎,做技术的圈子好像也比较小

      • erlv 说:

        @rix, 圈子是比较小,呵呵。主要是想这个博客能记录我的一些个人学习生活和工作。 如果能同时方便其他同道中人就更好。呵呵,具体的博客主题会形式多样些。欢迎多来看看。
        你的博客也挺专业,都写汇编,要向你多学习学习 :)

    2. 王辉 说:

      嵌入式这个行业门槛很高,我大学的那会学了点,现在基本都忘了,我当时学了点ARM7。感觉都是底层,要用很多汇编和C。

      搞技术就得耐得住寂寞,势利了可真不搞不出来真格的。

      • erlv 说:

        @王辉, 同意,卧薪尝胆。现在越来越觉得学技术就是修行,要想道行深,就得耐得住寂寞,不弃不馁。对于我这种俗人,就走一步算一步。养家糊口是第一位的:).
        我刚刚听新闻,巴黎那边好像09年最后一天连酒都不让买,所有玻璃制品也不能出售。呵呵,比我们牛多了。

    3. risent 说:

      原来Gentoo下打造工具链有这么方便的工具阿,手动时候的版本匹配让人抓狂

    4. Pingback 引用通告: 《编译点滴》半年记 « 编译点滴

    发表评论

    电子邮件地址不会被公开。 必填项已被标记为 *

    *

    您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>