编译工具链一般最简化的为binutils+gcc+glibc+kernel-header组合的环境。
GCC就是编译器,他的输出每次安装只能有针对一个架构的指令输出。如果要多个架构输出,那就要装多个GCC,所以编译工具链里面会有一个GCC。
交叉编译就是跨架构编译,编译出来的程序不能在本机执行(当然有例外情况)。所以这个时候就需要交叉编译工具链。
工具链光有GCC是不行的,还需要一个binutils的二进制连接器,以及一个最基本的目标架构的C库,C库还需要一个目标架构的内核源代码才能完全工作(当然不是必须的,但编译有的时候需要)
又因为GCC、binutils不能实现单软件同时多架构输出,所以需要单独另装,又加上C库和内核头文件需要目标架构的东西而不能用本机本地架构的数据。
所以一个交叉编译工具链就是针对目标架构准备的单独安装单独使用的binutils+gcc+glibc+kernel-header的集合了。
PS:这个kernel-header并不一定就是Linux,他还可以是别的系统核心开发库,比如FreeBSD。
㈡ 什么是交叉编译
交叉编译是指在不同类型的计算机体系结构或操作系统平台上进行编译和生成代码的过程。
以下是详细的解释:
交叉编译的基本原理
交叉编译是一种特殊的编译方式,它允许开发者在一台计算机上生成适用于另一台计算机的代码。在这个过程中,源代码通常是在一个平台上编写,然后通过交叉编译器进行编译,生成目标平台可执行的代码。交叉编译的主要优势在于能够在资源有限或特定环境下开发软件,特别是在嵌入式系统、移动设备等场景下,使得开发更加灵活高效。
交叉编译的应用场景
在现实中,交叉编译有着广泛的应用。例如,开发者可能会使用桌面计算机的Linux系统来编译运行在嵌入式Linux系统上的软件。这种场景是因为嵌入式设备的硬件资源有限,直接在其上进行编译可能会遇到性能瓶颈。通过交叉编译,开发者可以利用更强大的桌面计算机来处理复杂的编译任务,生成适用于嵌入式设备的代码。这不仅缩短了开发周期,还提高了开发效率。
交叉编译的过程和工具
交叉编译的具体过程依赖于使用的工具链和平台。它涉及一系列的编译器、链接器和库文件等,这些工具需要根据目标平台的特点进行优化和适配。例如,针对ARM架构的交叉编译工具链就包括了专为ARM处理器优化的编译器和链接器。开发者通过安装和配置这些工具链,可以在宿主机上实现目标平台的代码生成。在这一过程中,需要对不同平台间的兼容性和差异进行深入的了解和优化。而现代的软件开发环境中,已经有众多成熟的交叉编译工具和平台支持多种语言的交叉编译需求。
总结来说,交叉编译是一种在不同平台间进行代码生成的技术,它通过特定的工具链实现源代码到目标平台可执行代码的转换,广泛应用于嵌入式系统、移动设备等场景的开发中。
㈢ 建立交叉编译环境需要配置哪些服务
基于Linux操作系统的应用开发环境一般是由目标系统硬件(开发板)和宿主PC机所构成。目标硬件开发板用于运行操作系统和系统应用软件。
这种情况下,在 ARM 平台上进行本机编译就不太可能了,这是因为一般的编译工具链(compilation tool chain)需要很大的存储空间,并需要很强的 CPU 运算能力。为了解决这个问题,交叉编译工具就应运而生了。
比如,我们在 Windows 平台上,可使用 Visual C++开发环境,编写程序并编译成可执行程序。这种方式下,我们使用 PC 平台上的 Windows 工具开发针对 Windows 本身的可执行程序,这种编译过程称为 native compilation,中文可理解为本机编译。
然而,在进行嵌入式系统的开发时,则不能直接编译。运行程序的目标平台通常具有有限的存储空间和运算能力,比如常见的 ARM 平台,其一般的静态存储空间大概是 16 到 32 MB,而 CPU 的主频大概在 100MHz 到 500MHz 之间。
㈣ 如何用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,即不需再做什 么就能生成最终的目标机系统。
㈤ Linux嵌入式交叉编译工具链问题 浅谈
交叉编译工具链是一个由编译器、连接器和解释器组成的综合开发环境,交叉编译工具链主要由binutils、gcc和glibc 3个部分组成。有时出于减小libc库大小的考虑,也可以用别的c库来代替glibc,例如uClibc、dietlibc和newlib。交叉编译工具链主要包括针对目标系统的编译器gcc、目标系统的二进制工具binutils、目标系统的标准c库glibc和目标系统的Linux内核头文件。第一个步骤就是确定目标平台。每个目标平台都有一个明确的格式,这些信息用于在构建过程中识别要使用的不同工具的正确版本。因此,当在一个特定目标机下运行GCC时,GCC便在目录路径中查找包含该目标规范的应用程序路径。GNU的目标规范格式为CPU-PLATFORM-OS。例如,建立基于ARM平台的交叉工具链,目标平台名为arm-linux-gnu。
分步编译和安装交叉编译工具链所需要的库和源代码,最终生成交叉编译工具链。
通过Crosstool脚本工具来实现一次编译生成交叉编译工具链。
直接通过网上(ftp.arm.kernel.org.uk)下载已经制作好的交叉编译工具链。
方法1相对比较困难,适合想深入学习构建交叉工具链的读者。如果只是想使用交叉工具链,建议使用方法2或方法3构建交叉工具链。方法3的优点不用多说,当然是简单省事,但与此同时该方法有一定的弊端就是局限性太大,因为毕竟是别人构建好的,也就是固定的没有灵活性,所以构建所用的库以及编译器的版本也许并不适合你要编译的程序,同时也许会在使用时出现许多莫名的错误,建议你慎用此方法。
方法1:分步构建交叉编译工具链
下载所需的源代码包
建立工作目录
建立环境变量
编译、安装Binutils
获取内核头文件
编译gcc的辅助编译器
编译生成glibc库
编译生成完整的gcc
由于在问答中的篇幅,我不能细述具体的步骤,兴趣的同学请自行阅读开源共创协议的《Linux from scratch》,网址是:linuxfromscratch dot org
。
Crosstool是一组脚本工具集,可构建和测试不同版本的gcc和glibc,用于那些支持glibc的体系结构。它也是一个开源项目,下载地址是kegel dot com/crosstool。用Crosstool构建交叉工具链要比上述的分步编译容易得多,并且也方便许多,对于仅仅为了工作需要构建交叉编译工具链的你,建议使用此方法。
运行which makeinfo,如果不能找见该命令,在解压texinfo-4.11.tar.bz2,进入texinfo-4.11目录,执行./configure&&make&&make install完成makeinfo工具的安装
下载所需资源文件linux-2.4.20.tar.gz、binutils-2.19.tar.bz2、gcc-3.3.6.tar.gz、glibc- 2.3.2.tar.gz、glibc-linuxthreads-2.3.2.tar.gz和gdb-6.5.tar.bz2。然后将这些工具包文件放在新建的$HOME/downloads目录下,最后在$HOME/目录下解压crosstool-0.43.tar.gz,命
令如下:
#cd$HOME/
#tar–xvzfcrosstool-0.43.tar.gz
建立脚本文件
接着需要建立自己的编译脚本,起名为arm.sh,为了简化编写arm.sh,寻找一个最接近的脚本文件demo-arm.sh作为模板,然后将该脚本的内容复制到arm.sh,修改arm.sh脚本,具体操作如下:
# cd crosstool-0.43
# cp demo-arm.sh arm.sh
# vi arm.sh
修改后的arm.sh脚本内容如下:
#!/bin/sh
set-ex
TARBALLS_DIR=$HOME/downloads#定义工具链源码所存放位置。
RESULT_TOP=$HOME/arm-bin#定义工具链的安装目录
exportTARBALLS_DIRRESULT_TOP
GCC_LANGUAGES="c,c++"#定义支持C,C++语言
exportGCC_LANGUAGES
#创建/opt/crosstool目录
mkdir-p$RESULT_TOP
#编译工具链,该过程需要数小时完成。
eval'catarm.datgcc-3.3.6-glibc-2.3.2.dat'shall.sh--notest
echoDone.
在arm.sh脚本文件中需要注意arm-xscale.dat和gcc-3.3.6-glibc-2.3.2.dat两个文件,这两个文件是作为Crosstool的编译的配置文件。其中arm.dat文件内容如下,主要用于定义配置文件、定义生成编译工具链的名称以及定义编译选项等。
KERNELCONFIG='pwd'/arm.config#内核的配置
TARGET=arm-linux#编译生成的工具链名称
TARGET_CFLAGS="-O"#编译选项
gcc-3.3.6-glibc-2.3.2.dat文件内容如下,该文件主要定义编译过程中所需要的库以及它定义的版本,如果在编译过程中发现有些库不存在时,Crosstool会自动在相关网站上下载,该工具在这点上相对比较智能,也非常有用。
BINUTILS_DIR=binutils-2.19
GCC_DIR=gcc-3.3.6
GLIBC_DIR=glibc-2.3.2
LINUX_DIR=linux-2.6.10-8(根据实际情况填写)
GDB_DIR=gdb-6.5
执行脚本
将Crosstool的脚本文件和配置文件准备好之后,开始执行arm.sh脚本来编译交叉编译工具。具体执行命令如下:
#cdcrosstool-0.43
#./arm.sh
经过数小时的漫长编译之后,会在/opt/crosstool目录下生成新的交叉编译工具,其中包括以下内容:
arm-linux-addr2linearm-linux-g++arm-linux-ldarm-linux-size
arm-linux-ararm-linux-gccarm-linux-nmarm-linux-strings
arm-linux-asarm-linux-gcc-3.3.6arm-linux-objarm-linux-strip
arm-linux-c++arm-linux-gccbugarm-linux-objmpfix-embedded-paths
arm-linux-c++filtarm-linux-gcovarm-linux-ranlib
arm-linux-cpparm-linux-gprofarm-linux-readelf
然后将生成的编译工具链路径添加到环境变量PATH上去,添加的方法是在系统/etc/ bashrc文件的最后添加下面一行,在bashrc文件中添加环境变量
export PATH=/home/jiabing/gcc-3.3.6-glibc-2.3.2/arm-linux-bin/bin:$PATH
至此,arm-linux下的交叉编译工具链已经完成,现在就可以使用arm-linux-gcc来生成试验箱上的程序了!
㈥ Linux下的交叉编译环境设置
采用交叉编译的主要原因在于,多数嵌入式目标系统不能提供足够的资源供编译过程使用,因而只好将编译工程转移到高性能的主机中进行。
linux下的交叉编译环境重要包括以下几个部分:
1.对目标系统的编译器gcc
2.对目标系统的二进制工具binutils
3.目标系统的标准c库glibc
4.目标系统的linux内核头文件
交叉编译环境的建立步骤
一、下载源代码 下载包括binutils、gcc、glibc及linux内核的源代码(需要注意的是,glibc和内核源代码的版本必须与目标机上实际使用的版本保持一致),并设定shell变量PREFIX指定可执行程序的安装路径。
二、编译binutils 首先运行configure文件,并使用--prefix=$PREFIX参数指定安装路径,使用--target=arm-linux参数指定目标机类型,然后执行make install。
三、配置linux内核头文件
首先执行make mrproper进行清理工作,然后执行make config ARCH=arm(或make menuconfig/xconfig ARCH=arm)进行配置(注意,一定要在命令行中使用ARCH=arm指定cpu架构,因为缺省架构为主机的cpu架构),这一步需要根据目标机的实际情况进行详细的配置,笔者进行的实验中目标机为HP的ipaq-hp3630 PDA,因而设置system type为SA11X0,SA11X0 Implementations中选择Compaq iPAQ H3600/H3700。
配置完成之后,需要将内核头文件拷贝到安装目录: cp -dR include/asm-arm $PREFIX/arm-linux/include/asm cp -dR include/linux $PREFIX/arm-linux/include/linux
四、第一次编译gcc
首先运行configure文件,使用--prefix=$PREFIX参数指定安装路径,使用--target=arm-linux参数指定目标机类型,并使用--disable-threads、--disable-shared、--enable-languages=c参数,然后执行make install。这一步将生成一个最简的gcc。由于编译整个gcc是需要目标机的glibc库的,它现在还不存在,因此需要首先生成一个最简的gcc,它只需要具备编译目标机glibc库的能力即可。
五、交叉编译glibc
这一步骤生成的代码是针对目标机cpu的,因此它属于一个交叉编译过程。该过程要用到linux内核头文件,默认路径为$PREFIX/arm-linux/sys-linux,因而需要在$PREFIX/arm-linux中建立一个名为sys-linux的软连接,使其内核头文件所在的include目录;或者,也可以在接下来要执行的configure命令中使用--with-headers参数指定linux内核头文件的实际路径。
configure的运行参数设置如下(因为是交叉编译,所以要将编译器变量CC设为arm-linux-gcc): CC=arm-linux-gcc ./configure --prefix=$PREFIX/arm-linux --host=arm-linux --enable-add-ons 最后,按以上配置执行configure和make install,glibc的交叉编译过程就算完成了,这里需要指出的是,glibc的安装路径设置为$PREFIXARCH=arm/arm-linux,如果此处设置不当,第二次编译gcc时可能找不到glibc的头文件和库。
六、第二次编译gcc
运行configure,参数设置为--prefix=$PREFIX --target=arm-linux --enable-languages=c,c++。
运行make install。
到此为止整个交叉编译环境就完全生成了。
几点注意事项
第一点、在第一次编译gcc的时候可能会出现找不到stdio.h的错误,解决办法是修改gcc/config/arm/t-linux文件,在TARGET_LIBGCC2_CFLAGS变量的设定中增加-Dinhibit_libc和-D__gthr_posix_h。