前些日子,为自己的ARM11开发版做了一套交叉编译工具,整理与此,以备后用!
交叉编译工具链是一套在宿主机上生成目标机目标代码的编译链接工具集。
由上可知:
1. 交叉编译工具链是一套编译链接工具。
2. 交叉编译工具链运行于宿主机.
3. 交叉编译工具链生成的是目标机的目标代码,而非宿主机的目标代码。
一套完整的编译工具不仅仅有编译链接工具,还需相应的C库支持。所以,
交叉编译工具链的制作主要由三个步骤构成:
1. 制作一套简单的交叉编译工具。
利用本地工具(gcc, binutils 等), 生成一套简单的交叉编译工具,此工
具只能编译纯净(不涉及C库)的C源码。
2. 制作一套用于目标机的C库。
借用第一步生成的编译工具(gcc)与本地工具(binutils 等),生成与目标
机匹配的C库。
3. 制作一套完整的交叉编译工具。
借用本地工具(gcc, binutils 等),结合步骤2生成的C库。生成一套完整的
交叉编译工具链。
在以上三个步骤开始前,还有一步准备工作:环境搭建--相关目录的创建,源码准备,
相关本地工具的安装等。
本地环境:
Linux 3.0.0-16-generic #29-Ubuntu SMP Tue Feb 14 12:49:42 UTC 2012 i686 i686 i386 GNU/Linux
目录结构:
TOP_DIR--|-BUILD_DIR 制作Toolchain的工作目录
|-UTILS_DIR Host端相关工具的安装目录
|-SOURCE_DIR 源码目录
|-SYSROOT_DIR 根目录
源码版本:
binutils-2.22
gcc-4.7.0
glibc-2.15
glibc-ports-2.15
linux-3.2.12
gmp-5.0.4
mpfr-3.1.0
mpc-0.9
m4-1.4.16
autoconf-2.68
gettext-0.18.1.1
gawk-4.0.1
ncurses-5.9
texinfo-4.13
一.环境搭建
//定制变量
BUILD_PLAT="$(gcc -dumpmachine)"
TARGET_PLAT="arm-efeng-linux-gnueabi"
TOP_DIR="${HOME}/arm_toolchain_build"
BUILD_DIR="${TOP_DIR}/build"
UTILS_DIR="${TOP_DIR}/utils"
SOURCE_DIR="${TOP_DIR}/source"
SYSROOT_DIR="${TOP_DIR}/sysroot"
//创建目录
mkdir -p ${BUILD_DIR} ${UTILS_DIR} ${SOURCE_DIR} ${SYSROOT_DIR}
//安装工具
把所有相关的源码都解压到SOURCE_DIR目录下。
把除gcc, glibc, glibc-ports, linux 之外的所需工具编译安装到UTILS_DIR
目录下。例如: binutils.
cd ${BUILD_DIR}
mkdir binutils-2.22
cd binutils-2.22
${SOURCE_DIR}/binutils-2.22/configure --prefix=${UTILS_DIR} || exit 1
make && make install
//导出环境
export PATH=${PATH}:${SYSROOT_DIR}/usr/bin
echo $PATH >> ${HOME}/.bashrc
export PATH=${UTILS_DIR}/bin:${PATH}
二. 第一次编译GCC.
cd ${BUILD_DIR}
//gcc 编译时会查找/usr/include目录,若目录不存在会报错并终止编译。
mkdir gcc-4.7.0_1 ${SYSROOT_DIR}/usr/include
cd gcc-4.7.0_1
CFLAGS='-Dinhibit_libc' \
${SOURCE_DIR}/${GCC_PKG}/configure \
--prefix=/usr \
--build=${BUILD_PLAT} \
--host=${BUILD_PLAT} \
--target=${TARGET_PLAT} \
--with-sysroot=${SYSROOT_DIR} \
--with-gmp=${UTILS_DIR} \
--with-mpfr=${UTILS_DIR} \
--with-mpc=${UTILS_DIR} \
--without-headers \
--disable-libgomp \
--disable-libmudflap \
--disable-libssp \
--disable-multilib \
--disable-libquadmath \
--disable-threads \
--disable-shared \
--enable-languages=c \
|| exit 1
make && make DESTDIR=${SYSROOT} install
三. 编译GLIBC
cd ${SOURCE_DIR}
//下面的两个补丁用于解决编译过程中的错误,补丁附在文章的最后,请手动在
//SOURCE_DIR下创建这两个文件,并把相应内容拷入。
patch -p0 < glibc-2.15-libgcc_eh.patch
patch -p0 < glibc-ports-2.15-__aeabi_read_tp.path
//把glibc-ports-2.15 拷贝到glibc-2.15目录下,并命名为ports.
mv ${SOURCE_DIR}/glibc-ports-2.15 ${SOURCE_DIR}/glibc-2.15/ports
//glibc 的编译需要linux头文件, 先安装头文件。
cd ${SOURCE_DIR}/linux-3.2.12
make ARCH=arm INSTALL_HDR_PATH=${SYSROOT_DIR}/usr headers_install
//创建glibc build 目录。
mkdir -p ${BUILD_DIR}/glibc-2.15
cd ${BUILD_DIR}/glibc-2.15
libc_cv_c_cleanup=yes \
libc_cv_forced_unwind=yes \
libc_cv_ctors_header=no \
CC="${TARGET_PLAT}-gcc" \
AR="${TARGET_PLAT}-ar" \
RANLIB="${TARGET_PLAT}-ranlib" \
${SOURCE_DIR}/${GLIBC_PKG}/configure \
--prefix=/usr \
--build=${BUILD_PLAT} \
--host=${TARGET_PLAT} \
--disable-profile \
--enable-add-ons \
--enable-kernel=3.2.12 \
--with-threads=posix \
--with-binutils=${SYSROOT_DIR}/usr/bin \
--with-headers=${SYSROOT_DIR}/usr/include \
|| exit 1
make && make DESTDIR=${SYSROOT_DIR} install
四. 第二次编译GCC.
mkdir -p ${BUILD_DIR}/gcc-4.7.0_2
cd ${BUILD_DIR}/gcc-4.7.0_2
target_cpu=arm1176zjf-s \
${SOURCE_DIR}/${GCC_PKG}/configure \
--prefix=/usr \
--build=${BUILD_PLAT} \
--host=${BUILD_PLAT} \
--target=${TARGET_PLAT} \
--with-sysroot=${SYSROOT_DIR} \
--with-gmp=${UTILS_DIR} \
--with-mpfr=${UTILS_DIR} \
--with-mpc=${UTILS_DIR} \
--enable-languages=c,c++ \
|| exit 1
make AS_FOR_TARGET=${TARGET_PLAT}-as LD_FOR_TARGET=${TARGET_PLAT}-ld \
&& make DESTDIR=${SYSROOT_DIR} install
附录:
glibc相关的两个补丁,“/////” 中的内容为补丁正文,。
glibc-2.15-libgcc_eh.patch
/////////////////////////////////////////////////////////////////////////////////////////
--- glibc-2.15/Makeconfig 2012-01-01 20:16:32.000000000 +0800
+++ glibc-2.15/Makeconfig.new 2012-04-13 10:17:26.148701847 +0800
@@ -563,12 +563,12 @@
libunwind = -lunwind
endif
ifneq ($(have-as-needed),yes)
- libgcc_eh := -lgcc_eh $(libunwind)
+ libgcc_eh := $(libunwind)
else
libgcc_eh := -Wl,--as-needed -lgcc_s$(libgcc_s_suffix) $(libunwind) -Wl,--no-as-needed
endif
gnulib := -lgcc $(libgcc_eh)
-static-gnulib := -lgcc -lgcc_eh $(libunwind)
+static-gnulib := -lgcc $(libunwind)
libc.so-gnulib := -lgcc
endif
ifeq ($(elf),yes)
/////////////////////////////////////////////////////////////////////////////////////////
glibc-ports-2.15-__aeabi_read_tp.patch
/////////////////////////////////////////////////////////////////////////////////////////
--- glibc-ports-2.15/sysdeps/arm/Makefile 2011-12-24 03:34:10.000000000 +0800
+++ glibc-ports-2.15/sysdeps/arm/Makefile.new 2012-04-13 10:31:24.076856942 +0800
@@ -7,3 +7,8 @@
ifeq ($(subdir),csu)
gen-as-const-headers += tlsdesc.sym
endif
+
+### To pull in __aeabi_read_tp, needed for tls
+ifeq ($(subdir),malloc)
+$(objpfx)libmemusage.so: $(common-objpfx)libc_nonshared.a
+endif
/////////////////////////////////////////////////////////////////////////////////////////
阅读(3484) | 评论(2) | 转发(1) |