⑴ 如何安装 glibc-2.15.tar
编译步骤:
下载glibc-2.15.tar.gz和补丁包glibc-ports-2.15.tar.gz
解压
$mv glibc-ports-2.15 glibc-2.15/ports
$mkdir glibc-build-2.15 &&cd glibc-build-2.15
$ ../glibc-2.15/configure \
--prefix=/usr/local/glibc_mips \
CC=mipsel-linux-gcc \
--host=mipsel-linux \
--build=i686-pc-linux-gnu \
--enable-add-on=nptl \
libc_cv_forced_unwind=yes \
libc_cv_c_cleanup=yes \
libc_cv_mips_tls=yes \
libc_cv_gnu99_inline=yes
ok,没问题
$make &&make install
大功告成
##########################################################################
下面是我编译时的过程和遇到的问题及解决:
##########################################################################
$tar xvf glibc-2.16.0.tar.bz2
$cd glibc-2.16.0
$./configure --prefix=/usr/local/glibc //先不加其他选项,除了安装路径,一切默认,网上一般配置arm的选项如下 --prefix=$HOME/usr/arm --with-headers=$HOME/usr/arm/glibc/arm-linux-glibc/include --with-libs=$HOME/usr/arm/glibc/arm-linux-glibc/lib
报错:
configure: error: you must configure in a separate build directory
很奇怪的问题,必须配置一个构建目录,刚开始以为是安装目录为创建
$mkdir /usr/local/glibc
问题仍然存在,网络之
$mkdir ../glibc-build && cd ../glibc-build
$../glibc-2.16.0/configure --prefix=/usr/local/glibc
出现新的问题:
configure: WARNING:
*** These auxiliary programs are missing or incompatible versions: msgfmt
*** some features will be disabled.
*** Check the INSTALL file for required versions.
checking LD_LIBRARY_PATH variable... contains current directory
configure: error:
*** LD_LIBRARY_PATH shouldn't contain the current directory when
*** building glibc. Please change the environment variable
*** and run configure again.
第一个警告不用管它,第二个LD_LIBRARY_PATY也会有错?我的这个路径用了多少天了。仔细看提示,不应包含当前路径。打开~/.bash_profile
$cat ~/.bash_profile
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export LD_LIBRARY_PATH
这也没当前路径啊。还是网络吧。
一个兄弟的解释是这样“LD_LIBRARY_PATH不能以终结符作为开始和最后一个字符,不能有2个终结符连在一起,我的LD_LIBRARY_PATH为 :/usr/local/firefox:/usr/local/firefox,只要在前面加上一个路径,不让:出现在第一个字符就可以了 ”
原来如此,第一个字符不能是":",修改~/.bash_profile
export LD_LIBRARY_PATH=/usr/local/lib export LD_LIBRARY_PATH
$../glibc-2.16.0/configure --prefix=/usr/local/glibc
ls一下,发现,当前目录生成了Makefile等一堆东西
$make && make install
没问题
下一步开始交叉编译
$mkdir ../glibc-build-mips && cd ../glibc-build-mips
$ ../glibc-2.16.0/configure --prefix=/usr/local/glibc_mips CC=mipsel-linux-gcc --host=mips
出现新的问题:
configure: running configure fragment for add-on libidn
configure: running configure fragment for add-on nptl
*** The GNU C library is currently not available for this platform.
*** So far nobody cared to port it and if there is no volunteer it
*** might never happen. So, if you have interest to see glibc on
*** this platform visit
*** http://www.gnu.org/software/libc/porting.html
*** and join the group of porters
看起来像是需要path,下载glibc-ports-2.16.tar.gz,放在源码包目录,解压
$ ../glibc-2.16.0/configure \
--prefix=/usr/local/glibc_mips \
CC=mipsel-linux-gcc \
CXX=mipsel-linux-g++ \
--host=mips \
--enable-add-ons=/home/hb/code/glibc/glibc-ports-2.16.0/sysdeps/mips
仍然报错:
configure: error: fragment must set $libc_add_on_canonical
改为:
$ ../glibc-2.16.0/configure \
--prefix=/usr/local/glibc_mips \
CC=mipsel-linux-gcc \
CXX=mipsel-linux-g++ \
--host=mips \
--enable-add-ons
报错:
configure: error: The mipsel is not supported.
这样不行,谷歌半天,总算知道补丁怎么用的了。把补丁目录拷到glibc目录下,改名为ports
$mv glibc-ports-2.16.0/ glibc-2.16.0/ports
$../glibc-2.16.0/configure \
--prefix=/usr/local/glibc_mips \
CC=mipsel-linux-gcc \
CXX=mipsel-linux-g++ \
--host=mipsel-linux \
--build=i686-pc-linux-gnu \
--enable-add-on
继续报错:
configure: error:
*** These critical programs are missing or too old: ld as
*** Check the INSTALL file for required versions.
这个问题可折腾死我了。弄了好半天,就是不行,最后google发现,原来是ld和as版本不对,不是太高就是太低。
configure中找到$AS --version
发现版本是这么匹配的2.1*.*
$mipsel-linux-ld
GNU ld (GNU Binutils) 2.18.50.20080908
原来是这样,在configure版本号那一行修改,最后的括号前面加入
|2.18.50.×
as那一行也同样修改
然后
$make
开始编译,看起来不错
好半天后,编译也报错了
In file included from ../include/uchar.h:1,
from mbrtoc16.c:23:
../wcsmbs/uchar.h:47:5: error: #error "<uchar.h> requires ISO C11 mode"
In file included from ../include/uchar.h:1,
from mbrtoc16.c:23:
../wcsmbs/uchar.h:52: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'char16_t'
../wcsmbs/uchar.h:53: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'char32_t'
../wcsmbs/uchar.h:61: error: expected ')' before '*' token
../wcsmbs/uchar.h:66: error: expected declaration specifiers or '...' before 'char16_t'
../wcsmbs/uchar.h:73: error: expected ')' before '*' token
../wcsmbs/uchar.h:78: error: expected declaration specifiers or '...' before 'char32_t'
mbrtoc16.c:37: error: expected ')' before '*' token
make[2]: *** [/home/hb/code/glibc/glibc-build-mips/wcsmbs/mbrtoc16.o] 错误 1
make[2]:正在离开目录 `/home/hb/code/glibc/glibc-2.16.0/wcsmbs'
make[1]: *** [wcsmbs/subdir_lib] 错误 2
make[1]:正在离开目录 `/home/hb/code/glibc/glibc-2.16.0'
make: *** [all] 错误 2
看看这个头文件咋回事
$ vim ../glibc-2.16.0/wcsmbs/uchar.h
#if defined __GNUC__ && !defined __USE_ISOCXX11
/* Define the 16-bit and 32-bit character types. Use the information
provided by the compiler. */
# if !defined __CHAR16_TYPE__ || !defined __CHAR32_TYPE__
# if defined __STDC_VERSION__ && __STDC_VERSION__ < 201000L
# error "<uchar.h> requires ISO C11 mode"
# else
# error "definitions of __CHAR16_TYPE__ and/or __CHAR32_TYPE__ missing"
# endif
# endif
明白了,原来是需要c11支持,mipsel-linux-gcc -v一下,我的支持c99.原来如此。暂时没招了,我还做不到修改c11的支持,只剩两个办法,不用这个glibc版本或者重新编译一个支持c11的交叉编译器。编译器需要做的比较多,暂时先换个低点的版本吧。
下载galibc-2.15版本
重复上面步骤,解压tar包
解压ports包
$mv glibc-ports-2.15 glibc-2.15/ports
$mkdir glibc-build-2.15 &&cd glibc-build-2.15
$ ../glibc-2.15/configure \
--prefix=/usr/local/glibc_mips \
CC=mipsel-linux-gcc \
--host=mipsel-linux \
--build=i686-pc-linux-gnu \
--enable-add-on=nptl \
libc_cv_forced_unwind=yes \
libc_cv_c_cleanup=yes \
libc_cv_mips_tls=yes \
libc_cv_gnu99_inline=yes
ok,没问题
$make &&make install
库已经编好了,但是不能直接使用,必须再用新的库重编一遍编译器才行。
上一篇
⑵ 求Linux下的libdl库源码。
你可以从GNU网站下载glibc的源码,libdl库源于glibc源码的dlfcn目录,其中包含dlopen、dlsym等函数的实现。
⑶ 在哪里可以找到C语言标准库的实现源代码
Linux下的glic库的源码链接:
http://ftp.gnu.org/gnu/glibc/,你可以下载最新版本的glibc-2.24.tar.gz这个压缩文件,在Windows系统下直接用WinRAR解压即可,如果在Linux系统下用命令行解压的话,命令如下:tar -xzvf glibc-2.24.tar.gz。
⑷ 如何建立Linux下的ARM交叉编译环境
这个过程如下
1. 下载源文件、补丁和建立编译的目录
2. 建立内核头文件
3. 建立二进制工具(binutils)
4. 建立初始编译器(bootstrap gcc)
5. 建立c库(glibc)
6. 建立全套编译器(full gcc)
下载源文件、补丁和建立编译的目录
1. 选定软件版本号
选择软件版本号时,先看看glibc源代码中的INSTALL文件。那里列举了该版本的glibc编译时所需的binutils 和gcc的版本号。例如在 glibc-2.2.3/INSTALL 文件中推荐 gcc 用 2.95以上,binutils 用 2.10.1 以上版本。
我选的各个软件的版本是:
linux-2.4.21+rmk2
binutils-2.10.1
gcc-2.95.3
glibc-2.2.3
glibc-linuxthreads-2.2.3
如果你选的glibc的版本号低于2.2,你还要下载一个叫glibc-crypt的文件,例如glibc-crypt-2.1.tar.gz。 Linux 内核你可以从www.kernel.org 或它的镜像下载。
Binutils、gcc和glibc你可以从FSF的FTP站点ftp://ftp.gun.org/gnu/ 或它的镜像去下载。在编译glibc时,要用到 Linux 内核中的 include 目录的内核头文件。如果你发现有变量没有定义而导致编译失败,你就改变你的内核版本号。例如我开始用linux-2.4.25+vrs2,编译glibc-2.2.3 时报 BUS_ISA 没定义,后来发现在 2.4.23 开始它的名字被改为 CTL_BUS_ISA。如果你没有完全的把握保证你改的内核改完全了,就不要动内核,而是把你的 Linux 内核的版本号降低或升高,来适应 glibc。
Gcc 的版本号,推荐用 gcc-2.95 以上的。太老的版本编译可能会出问题。Gcc-2.95.3 是一个比较稳定的版本,也是内核开发人员推荐用的一个 gcc 版本。
如果你发现无法编译过去,有可能是你选用的软件中有的加入了一些新的特性而其他所选软件不支持的原因,就相应降低该软件的版本号。例如我开始用 gcc-3.3.2,发现编译不过,报 as、ld 等版本太老,我就把 gcc 降为 2.95.3。太新的版本大多没经过大量的测试,建议不要选用。
2. 建立工作目录
首先,我们建立几个用来工作的目录:
在你的用户目录,我用的是用户liang,因此用户目录为 /home/liang,先建立一个项目目录embedded。
$pwd
/home/liang
$mkdir embedded
再在这个项目目录 embedded 下建立三个目录 build-tools、kernel 和 tools。
build-tools-用来存放你下载的 binutils、gcc 和 glibc 的源代码和用来编译这些源代码的目录。
kernel-用来存放你的内核源代码和内核补丁。
tools-用来存放编译好的交叉编译工具和库文件。
$cd embedded
$mkdir build-tools kernel tools
执行完后目录结构如下:
$ls embedded
build-tools kernel tools
3. 输出和环境变量
我们输出如下的环境变量方便我们编译。
$export PRJROOT=/home/liang/embedded
$export TARGET=arm-linux
$export PREFIX=$PRJROOT/tools
$export TARGET_PREFIX=$PREFIX/$TARGET
$export PATH=$PREFIX/bin:$PATH
如果你不惯用环境变量的,你可以直接用绝对或相对路径。我如果不用环境变量,一般都用绝对路径,相对路径有时会失败。环境变量也可以定义在.bashrc文件中,这样当你logout或换了控制台时,就不用老是export这些变量了。
体系结构和你的TAEGET变量的对应如下表
你可以在通过glibc下的config.sub脚本来知道,你的TARGET变量是否被支持,例如:
$./config.sub arm-linux
arm-unknown-linux-gnu
在我的环境中,config.sub 在 glibc-2.2.3/scripts 目录下。
网上还有一些 HOWTO 可以参考,ARM 体系结构的《The GNU Toolchain for ARM Target HOWTO》,PowerPC 体系结构的《Linux for PowerPC Embedded Systems HOWTO》等。对TARGET的选取可能有帮助。
4. 建立编译目录
为了把源码和编译时生成的文件分开,一般的编译工作不在的源码目录中,要另建一个目录来专门用于编译。用以下的命令来建立编译你下载的binutils、gcc和glibc的源代码的目录。
$cd $PRJROOT/build-tools
$mkdir build-binutils build-boot-gcc build-gcc build-glibc gcc-patch
build-binutils-编译binutils的目录
build-boot-gcc-编译gcc 启动部分的目录
build-glibc-编译glibc的目录
build-gcc-编译gcc 全部的目录
gcc-patch-放gcc的补丁的目录
gcc-2.95.3 的补丁有 gcc-2.95.3-2.patch、gcc-2.95.3-no-fixinc.patch 和gcc-2.95.3-returntype-fix.patch,可以从 http://www.linuxfromscratch.org/ 下载到这些补丁。
再将你下载的 binutils-2.10.1、gcc-2.95.3、glibc-2.2.3 和 glibc-linuxthreads-2.2.3 的源代码放入 build-tools 目录中
看一下你的 build-tools 目录,有以下内容:
$ls
binutils-2.10.1.tar.bz2 build-gcc gcc-patch
build-binutls build-glibc glibc-2.2.3.tar.gz
build-boot-gcc gcc-2.95.3.tar.gz glibc-linuxthreads-2.2.3.tar.gz
建立内核头文件
把你从 www.kernel.org 下载的内核源代码放入 $PRJROOT /kernel 目录
进入你的 kernel 目录:
$cd $PRJROOT /kernel
解开内核源代码
$tar -xzvf linux-2.4.21.tar.gz
或
$tar -xjvf linux-2.4.21.tar.bz2
小于 2.4.19 的内核版本解开会生成一个 linux 目录,没带版本号,就将其改名。
$mv linux linux-2.4.x
给 Linux 内核打上你的补丁
$cd linux-2.4.21
$patch -p1 < ../patch-2.4.21-rmk2
编译内核生成头文件
$make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
你也可以用 config 和 xconfig 来代替 menuconfig,但这样用可能会没有设置某些配置文件选项和没有生成下面编译所需的头文件。推荐大家用 make menuconfig,这也是内核开发人员用的最多的配置方法。配置完退出并保存,检查一下的内核目录中的 include/linux/version.h 和 include/linux/autoconf.h 文件是不是生成了,这是编译 glibc 是要用到的,version.h 和 autoconf.h 文件的存在,也说明了你生成了正确的头文件。
还要建立几个正确的链接
$cd include
$ln -s asm-arm asm
$cd asm
$ln -s arch-epxa arch
$ln -s proc-armv proc
接下来为你的交叉编译环境建立你的内核头文件的链接
$mkdir -p $TARGET_PREFIX/include
$ln -s $PRJROOT/kernel/linux-2.4.21/include/linux $TARGET_PREFIX/include/linux
$in -s $PRJROOT/kernel/linux-2.4.21/include/asm-arm $TARGET_PREFIX/include/asm
也可以把 Linux 内核头文件拷贝过来用
$mkdir -p $TARGET_PREFIX/include
$cp -r $PRJROOT/kernel/linux-2.4.21/include/linux $TARGET_PREFIX/include
$cp -r $PRJROOT/kernel/linux-2.4.21/include/asm-arm $TARGET_PREFIX/include
建立二进制工具(binutils)
binutils是一些二进制工具的集合,其中包含了我们常用到的as和ld。
首先,我们解压我们下载的binutils源文件。
$cd $PRJROOT/build-tools
$tar -xvjf binutils-2.10.1.tar.bz2
然后进入build-binutils目录配置和编译binutils。
$cd build-binutils
$../binutils-2.10.1/configure --target=$TARGET --prefix=$PREFIX
--target 选项是指出我们生成的是 arm-linux 的工具,--prefix 是指出我们可执行文件安装的位置。
会出现很多 check,最后产生 Makefile 文件。
有了 Makefile 后,我们来编译并安装 binutils,命令很简单。
$make
$make install
看一下我们 $PREFIX/bin 下的生成的文件
$ls $PREFIX/bin
arm-linux-addr2line arm-linux-gasp arm-linux-objmp arm-linux-strings
arm-linux-ar arm-linux-ld arm-linux-ranlib arm-linux-strip
arm-linux-as arm-linux-nm arm-linux-readelf
arm-linux-c++filt arm-linux-obj arm-linux-size
我们来解释一下上面生成的可执行文件都是用来干什么的
add2line - 将你要找的地址转成文件和行号,它要使用 debug 信息。
Ar-产生、修改和解开一个存档文件
As-gnu 的汇编器
C++filt-C++ 和 java 中有一种重载函数,所用的重载函数最后会被编译转化成汇编的标号,c++filt 就是实现这种反向的转化,根据标号得到函数名。
Gasp-gnu 汇编器预编译器。
Ld-gnu 的连接器
Nm-列出目标文件的符号和对应的地址
Obj-将某种格式的目标文件转化成另外格式的目标文件
Objmp-显示目标文件的信息
Ranlib-为一个存档文件产生一个索引,并将这个索引存入存档文件中
Readelf-显示 elf 格式的目标文件的信息
Size-显示目标文件各个节的大小和目标文件的大小
Strings-打印出目标文件中可以打印的字符串,有个默认的长度,为4
Strip-剥掉目标文件的所有的符号信息
建立初始编译器(bootstrap gcc)
首先进入 build-tools 目录,将下载 gcc 源代码解压
$cd $PRJROOT/build-tools
$tar -xvzf gcc-2.95.3.tar.gz
然后进入 gcc-2.95.3 目录给 gcc 打上补丁
$cd gcc-2.95.3
$patch -p1< ../gcc-patch/gcc-2.95.3.-2.patch
$patch -p1< ../gcc-patch/gcc-2.95.3.-no-fixinc.patch
$patch -p1< ../gcc-patch/gcc-2.95.3-returntype-fix.patch
echo timestamp > gcc/cstamp-h.in
在我们编译并安装 gcc 前,我们先要改一个文件 $PRJROOT/gcc/config/arm/t-linux,把
TARGET_LIBGCC2-CFLAGS = -fomit-frame-pointer -fPIC
这一行改为
TARGET_LIBGCC2-CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h
你如果没定义 -Dinhibit,编译时将会报如下的错误
http://www.cnblogs.com/gcc-2.95.3/gcc/libgcc2.c:41: stdlib.h: No such file or directory
http://www.cnblogs.com/gcc-2.95.3/gcc/libgcc2.c:42: unistd.h: No such file or directory
make[3]: *** [libgcc2.a] Error 1
make[2]: *** [stmp-multilib-sub] Error 2
make[1]: *** [stmp-multilib] Error 1
make: *** [all-gcc] Error 2
⑸ 如何查看C语言,内库的源代码
1、首先标准只是规定了这些函数的接口和具体的运行效率的要求,这些函数具体是怎么写得要看各个编译器的实现和平台。
2、例如使用的编译器是visual studio,微软提供了一部分C运行时(CRT)的源码,里面会有memcpy,strcpy之类的函数的实现,在visual studio 2005下的路径是C:\Program Files\Microsoft Visual Studio 8\VC\crt\src。
⑹ 谁能提供C语言stdio库函数源代码
http://mirrors.kernel.org/gnu/glibc/glibc-2.7.tar.gz
下载Linux的C语言标准库,它包含stdio.h等等
⑺ cygwin 中如何安装arm-linux-gcc交叉编译器
交叉编译工具链作为嵌入式Linux开发的基础,直接影响到嵌入式开发的项目进度和完成质量。由于目前大多数开发人员使用Windows作为嵌入式开发的宿主机,在Windows中通过安装VMware等虚拟机软件来进行嵌入式Linux开发,这样对宿主机的性能要求极高。Cygwin直接作为Windows下的软件完全能满足嵌入式Linux的开发工作,对硬件的要求低及方便快捷的特点成为嵌入式开发的最佳选择。
目前网络上Cygwin下直接可用的交叉编译器寥寥无几且版本都比较低,不能满足开源软件对编译器版本依赖性的要求(如低版本工具链编译U-Boot出现软浮点问题等);Crosstool等交叉工具链制作工具也是更新跟不上自由软件版本的进度;同时系统介绍Cygwin下制作交叉编译器方面的资料很少。针对上述情况,基于最新版gcc等自由软件构建Cygwin下的交叉编译器显得尤为迫切和重要。
构建前准备工作
首先Cygwin下必须保证基本工具比如make}gcc等来构建bootstrap-gcc编译器,这可以在安装Cygwin时选择安装。参照gcc等安装说明文档来在Cygwin下查看是否已经安装,如输入gcc --v等。
源码下载
gcc-4.5.0的编译需mpc的支持,而mpc又依赖gmp和mpfr库。从各个项目官方网站上下载的最新的源码:
binutils-2.20. l .tar.bz2
gmp-S.O. l .tar.bz2
mpc-0.8.2.tar.gz
mpfr-3.O.O.tar.bz2
gcc-4.S.O.tar.bz2
linux-2.6.34.tar.bz2
glibc-2.11.2.tar.bz2
glibc-ports-2. l l .tar.bz2
gdb-7. l.tar.bz2
设置环境变量
HOST:工具链要运行的目标机器;BUILD:用来建立工具链的机器;TARGET工具链编译产生的二进制代码可以运行的机器。
BUILD=i686-pc-cygwin
HOST=i686-pc-cygwin TARGET=arm-linux
SYSROOT指定根目录,$PREFIX指定安装目录。目标系统的头文件、库文件、运行时对象都将被限定在其中,这在交叉编译中有时很重要,可以防止使用宿主机的头文件和库文件。本文首选$SYSROOT为安装目录,$PREFIX主要作为glibc库安装目录。
SYSROOT=/cross-root
PREFIX=/cross-root/arm-linux
由于GCC-4.5.0需要mpfr,gmp,mpc的支持,而这三个库又不需要交叉编译,仅仅是在编译交叉编译链时使用,所以放在一个临时的目录。
TEMP_PREFIX=/build-temp
控制某些程序的本地化的环境变量:
LC ALL=POSIX
设置环境变量:
PATH=$SYSROOT/bin:儿in:/usr/bin
设置编译时的线程数f31减少编译时间:
PROCS=2
定义各个软件版本:
BINUTILS V=2.20.1
GCC V=4.5.0
GMP V=5.0.1
MPFR V=3.0.0
MPC V二0.8.2
LINUX V二2.6.34
GLIBC V=2.11.2
GLIBC-PORTS V=2.11
GDB V=7.1
构建过程详解
鉴于手工编译费时费力,统一把构建过程写到Makefile脚本文件中,把其同源码包放在同一目录下,执行make或顺次执行每个命令即可进行无人值守的编译安装交叉工具
链。以下主要以Makefile执行过程为主线进行讲解。
执行“make”命令实现全速运行
可在Cygwin的Shell环境下执行“make>make.log 2>&1”命令把编译过程及出现的错误都输出到make.log中,便于查找:
all:prerequest install-deps install-cross-stage-one install-
cross-stage-two
预处理操作
"make prerequest',命令实现单步执行的第一步,实现输出变量、建立目录及解压源码包等操作。0'set十h”关闭bash的Hash功能,使要运行程序的时候,shell将总是搜索PATH里的目录[4]。这样新工具一旦编译好,shell就可以在$(SYSROOT)/bin目录里找到: prerequest:
set +h&&mkdir -p $(SYSROOT)/bin&&
mkdir -p $(PREFIX)/include&&
mkdir -p $(TEMP一REFIX)&&
export PATH LCes ALL&&
tar -xvf gmp-$(GMP_V).tar.bz2&&
tar -xvf mpfr-$(MPFR_V).tar.bz2&&
tar -xvf mpc-$(MPC_V).tar.gz&&
tar -xvf binutils-$(BINUTILS_V).tar.bz2&&
tar -xvf gcc-$(GCC_V).tar.bz2&&
tar -xvf linux-$(LINUX_V).tar.bz2&&
tar -xvf glibc-$(GLIBC_V).tar.bz2&&
tar -xvf glibc-ports-$(GLIBC-PORTS_V).tar.bz2&&
my glibc-ports-$(GLIBC-PORTS_V)
glibc-$(GLIBC_V)/ports&&
tar -xvf gdb-$(GDB V).tar.bz2
非交叉编译安装gcc支持包mpc
00make install-deps”命令实现单步执行的第二步,实现mpc本地编译,mpc依赖于gmp和mpfr
install-deps:gmp mpfr mpc
gmp:gmp-$(GMP_V)
mkdir -p build/gmp&&cd build/gmp&&
../../gmp-*/configure
--disable-shared --prefix=$(TEMP_PREFIX)&&
$(MAKE)一$(PROCS)&&$(MAKE) install
mpfr:mpfr-$(MPFR_V)
mkdir -p b-uild/mpfr&&cd build/mpfr&&
../..//mpfr-*/configure
LDF'LAGS="-Wl,-search_paths_first”--disable-shared
--with-gmp=$(TEMP_PREFIX)
--prefix=$(TEMP_PREFIX)&&
$(MAKE)一$(PROCS) all&&$(MAKE) install
mpc: mpc-$(MPC_V) gmp mpfr
mkdir -p build/mpc&&cd build/mpc&&
../../mpc-*/configure
--with-mpfr=$(TEMP PREFIX)
--with-gmp=$(TEMP_PREFIX)
--prefix=$(TEMP_PREFIX)&&
$(MAKE)一$(PROCS)&&$(MAKE) install
交叉编译第一阶段
"make install-cross-stage-one',命令实现单步执行的第三步,编译安装binutils,bootstrap-gcc和获取Linux内核头文件:
install-cross-stage-one:cross-binutils cross-gcc get-kernel-headers
编译安装binutils
cross-binutils: binutils-$(BINUTILS_ V)
mkdir -p build/binutils&&cd build/binutils&&
../..//binutils-*/configure --prefix=$(SYSROOT)
--target=$(TARGET)--disable-nls&&
$(MAKE)j$(PROCS)&&$(MAKE) install
编译安装bootstrap-gcc。使用一disable-shared参数的意思是不编译和安装libgcc_ eh.a文件。glibc软件包依赖这个库,因为它使用其内部的一lgcc_eh来创建系统[6]。这种依赖
性,可通过建立一个指向libgcc.a符号链接得到满足,因为该文件最终将含有通常在libgcc- eh.a中的对象(也可通过补丁文件实现)。
cross-gcc:gcc-$(GCC_V)
mkdir -p build/gcc&&cd build/gcc&&
二//gcc-*/configure
--target=$(TARGET)--prefix=$(SYSROOT)
--disable-nls --disable-shared --disable-multilib
--disable-decimal-float--disable-threads
--disable-libmudflap --disable-libssp
--disable-libgomp --enable-languages=c
--with-gmp=$(TEMP_PREFIX)
--with-mpfr=$(TEMP_PREFIX)
--with-mpc=$(TEMP_PREFIX)&&
$(MAKE) -j$(PROCS)&&$(MAICE) install&&
In -vs libgcc.a'arm-linux-gcc -print-libgcc-file-name I
sed's/libgcc/& eh/'}
获取Linux内核头文件:
get-kernel-headersainux-$(LINUX_V)
cd linux-$(LINUX_V)&&
$(MAICE) mrproper&&$(MAKE) headers check&&
$(MAKE) ARCH=arm&&
INSTALLes HDR_ PATH=dest headers_ install&&
find dest/include
(-name .install一。-name ..installNaNd)-delete&&
cp -rv desdinclude/* $(PREFIX)/include
交叉编译第二阶段
编译安装glibc、重新编译安装binutils、完整编译安装gcc和编译安装gdb o "make install-cross-stage-two',命令实现单步执行的第四步: install-cross-stage-two:cross-glibc cross-rebinutils cross-g++ cross-gdb
编译安装glibca glib。的安装路径特意选为$(PREFIX),与gcc更好找到动态链接库也有关系,选在$(SYSROOT)提示找不到crti.o; glibc已经不再支持i386; glibc对ARM等的处理器的支持主要通过glibc-ports包来实现;正确认识大小写敏感(Case Sensitive)和大小写不敏感(CaseInsensitive)系统,大小写敏感问题主要影响到glibc,是交叉编译glibc成功的关键:Cygwin帮助手册中可知Cygwin是默认大小写不敏感的n},但是UNIX系统是大小写敏感的,这也是Cygwin和UNIX类系统的一个区别。通过作者自行参考制作的glibc-2.11.2-cygwin.patch补T使glibc变为Case-Insensitive,此补丁主要是对大小写敏感问题改名来实现。
交叉编译过程中安装的链接器,在安装完Glibc以前都无法使用。也就是说这个配置的forced unwind支持测试会失败,因为它依赖运行中的链接器。设置libc_ cvforced unwind=yes这个选项是为了通知configure支持force-unwind,而不需要进行测试。libc cv_c_cleanup=yes类似的,在configure脚本中使用libc_cv_c cleanup=yes,以便配置成跳过测试而支持C语言清理处理。
cross-glibc:glibc-$(GLIBC_V)
cd glibc-$(GLIBC_V)&&
patch -Np 1 –i...//glibc-2.11.2-cygwin.patch&&
cd..&&mkdir -p build/glibc&&
cd build/glibc&&
echo"libc cv_forcedes unwind=yes">config.cache&&
echo "libc cv_c_cleanup=yes">>config.cache&&
echo "libc cv_arm_tls=yes">>config.cache&&
../../glibc-*/configure --host=$(TARGET)
--build=$(../OneScheme/glibc-2.11.2/scripts/config.guess)
--prefix=$(PREFIX)--disable-profile
--enable-add-ons --enable-kernel=2.6.22.5
--with-headers=$(PREFIX)/include
--cache-file=config.cache&&
$(MAKE)&&$(MAKE) install
重新编译安装binutils。编译之前要调整工具链,使其
指向新生成的动态连接器。
调整工具链:
SPECS=
'dirname $(arm-linux-gcc -print-libgcc-file-name)'/specs
arm-linux-gcc -mpspecs
sed -e 's@/lib(64)\?/ld@$(PREFTX)&@g' -e ,}/}}*cPP}$/{n;s,$,-isystem $(PREFIX)/include,}"
>$SPECS
echo "New specs file is: $SPECS"
unset SPECS
测试调整后工具链:
echo 'main(川’>mmy.c
arm-linux-gcc
-B/cross-root/arm-linux/lib mmy.c
readelf -1 a.out I grep’:/cross-roobarm-linux'
调整正确的输出结果:
[Requesting program interpreter: /tools/lib/ld-linux.so.2j
一切正确后删除测试程序:
rm -v mmy.c a.out
重新编译binutils。指定--host,--build及--target,否则配置不成功,其config.guess识别能力不如gcc做的好。
cross-rebinutils: binutils-$(BINUTILS_V)
mkdir -p build/rebinutils&&
cd build/rebinutils&&CC="$(TARGET)-gcc
-B/cross-roodarm-linux/lib/"&&AR=$(TARGET)-ar&&
RANLIB=$(TARGET)-ranlib&&../..//binutils-*/configure
--host=$(HOST)--build=$(BUILD)--target=$(TARGET)
--prefix=$(SYSROOT)--disable-nls
--with-lib-path=$(PREFIX)/lib&&
$(MAKE)--$(PROCS)&&$(MAKE) install
高于4.3版的gcc把这个编译当作一个重置的编译器,并且禁止在被一prefix指定的位置搜索startfiles。因为这次不是重置的编译器,并且$(SYSROOT)目录中的startfiles对于创
建一个链接到$$(SYSROOT)目录库的工作编译器很重要,所以我们使用下面的补丁,它可以部分还原gcc的老功能tai . patch -Npl –i../gcc-4.5.0-startfiles_fix-l.patch
在正常条件下,运行gcc的fixincludes脚本,是为了修复可能损坏的头文件。它会把宿主系统中已修复的头文件安装到gcc专属头文件目录里,通过执行下面的命令,可以抑
制fixincludes脚本的运行[9](此时目录为/gcc-4.5.0)。
cp -v gcc/Makefile.in{,.orig}
sed 's@\./fixinc\.sh@-c true@'
gcc/Makefile.in.orig > gcc/Makefile.in
下面更改gcc的默认动态链接器的位置,使用已安装在/cross-root/ann-linux目录下的链接器,这样确保在gcc真实的编译过程中使用新的动态链接器。即在编译过程中创建的所有
二进制文件,都会链接到新的glibc文件
for file in
$(find gcc/config -name linux64.h-o -name linux.h –o -name sysv4.h)
do cp -uv $file{,.orig}
sed -a 's@/lib(64)?(32)?/Id@/cross-root/arm-linux&@g’-e's@/usr@/cross-rootlarm-linux@g' $file.orig>$file echo‘
#undef STANDARD INCLUDE DIR
#define STANDARD_ INCLUDE DIR "/cross-root/arm-linux/include"
#define STANDARD STARTFILE PREFIX 1 "/cross-root/arm-linux/lib"
#define STANDARD_ STARTFILE_ PREFIX_ 2””’>>$file
touch $file.orig done
完整编译安装gcc。最好通过指定--libexecdir更改libexecdir到atm-linux目录下。--with-local-prefix选项指定gcc本地包含文件的安装路径此处设为$$(PREFIX),安装后就会在内核头文件的路径下。路径前指定$(Pwd)则以当前路径为基点,不指定则默认以/home路径为基点,这点要注意。
cross-g++:gcc-$(GCC-)
mkdir -p build/g十+&&cd build/g++&&
CC="$(TARGET)-gcc AR=$(TARGET)-ar&&
-B/cross-roodarm-linux/lib/"&&
RANLIB=$(TARGET)-ranlib&&
..//gcc-*/configure
--host=$(HOST)--build=$(BUILD)--target=$(TARGET)
--prefix=$(SYSROOT)--with-local-prefix=$(PREFIX)
--enable-clocale=gnu --enable-shared
--enable-threads=posix --enable -cxa_atexit
--enable-languages=c,c++--enable-c99
--enable-long-long --disable-libstdcxx-pch
--disable-libunwind-exceptions
--with-gmp=$(TEMP_PREFIX)
--with-mpfr=$(TEMP_PREFIX)
--with-mpc=$(TEMP_PREFIX)&&
$(MAKE) LD_IBRARY_ATH=
$(pwd)/$(../../gcc-4.5.0/config.guess)/libgcc&&
$(MAKE) install
编译安装gdb,至此完成整个工具链的制作。
cross-gdb: gdb-$(GDB V)
mkdir -p build/gdb&&cd build/gdb&&
../../gdb-*/configure --prefix=$(SYSROOT)
--target=$(TARGET)--disable-werror&&
$(MAKE)-j$(PROCS)&&$(MAKE) install
“make clean”命令清除编译生成的文件和创建解压的文件夹
.PHONY:clean
dean:
rm -fr $(TEMP_PREFIX) build
binutils-$(BINUTIL,S_V) gcc-$(GCC_V)
glibc-$(NEWL.IB_V) gdb-$(GDB_V)
gmp-$(GMP_V) mpc-$(MPC_V) mpfr-$(MPFR_V)
工具链测试
命令行中输入以下内容:
echo 'main(){}’>mmy.c
arm-linux-gcc -o mmy.exe mmy.c
file mmy.exe
运行正常的结果:
mmy.exe: ELF 32-bit LSB executable, ARM, version 1,for GNU/Linux 2.6.22, dynamically linked (uses shared libs),not stripped.