|
本文最后更新于4月15日
-----------
SYSROOT工具链相比普通的LFS/CLFS工具链有很多优势。这点在Youbest的文章里面已经有叙述。
随着GCC 4.3的出现,构造SYSROOT工具链的原有方法已经行不通了。经过本人反复测试,在x86_64 -> x86_64上总结出如下的工具链构造方法。本文主要参考最新的CLFS-SYSROOT BOOK,请对照阅读。
1. 准备工作
请参考根据CLFS-SYSROOT的标准做法,进行分区、添加用户、设置环境等工作。由于本文的宿主是x86_64,因此需要多加几个变量:
export CLFS_TARGET32="i686-pc-linux-gnu"
export BUILD32="-m32"
export BUILD64="-m64"
此外,我的测试环境有些另类。为了拥有一个基本上干净的目标分区,我把cross-tools目录直接建在宿主根目录下,同时在$CLFS目录(目标分区)下创建一个符号连接指向它。这样,所有的交叉工具链(依赖于宿主的)都不会存在于目标分区。
为了安装GCC 4.3我们额外下载3个东东:
GMP 4.2.2 http://ftp.sunet.se/pub/gnu/gmp/gmp-4.2.2.tar.bz2
MPFR 2.3.1 http://www.mpfr.org/mpfr-current/mpfr-2.3.1.tar.bz2
FLEX 2.5.32 http://optusnet.dl.sourceforge.n ... flex-2.5.35.tar.bz2
2. binutils 2.18
本来根据CLFS-SYSROOT,这一步之前需要安装目录结构、设置用户密码等。不过,我们这里忽略它,仅在必要的时候才安装需要的目录。实践证明这样做是完全可行的,因为在工具链创建成功之前我们甚至不想往目标分区放任何东西。只不过有些东西如头文件和库文件等不得不放在那里,否则就构建不出我们的交叉工具链了。
patch -Np1 -i ../binutils-2.18-genscripts_multilib-1.patch
patch -Np1 -i ../binutils-2.18-posix-1.patch
mkdir -v ../binutils-build
cd ../binutils-build
AR=ar AS=as ../binutils-2.18/configure --prefix=$CLFS/cross-tools \
--host=$CLFS_HOST --target=$CLFS_TARGET --with-sysroot=$CLFS \
--disable-nls --enable-shared --with-64-bit-bfd
以上没什么好说的,照抄的而已。
make && make install
我懒得一步步make configure-host && make && make install,直接一步make install了事。事实上效果是完全一样的。make configure-host会把所有的目录都创建好并运行相应的configure脚本生成Makefile文件。这对调试Makefile和configure相关问题非常有用。不过,binutils实在也没什么可调试的。但直接make install 也不行,要先make好才能install。
3. GMP & MPFR
两个库的安装方式都很简单:
./configure --prefix=$CLFS/cross-tools --disable-shared
make install
添加--disable-shared是因为我们不需要它们的动态库。只要静态库就足够安装了。
4. FLEX
这个更简单:
./configure --prefix=$CLFS/cross-tools
make install
5. 头文件
首先是Linux头文件,我用Linux-2.6.24.4
install -dv $CLFS/usr/include
make mrproper
make ARCH=x86_64 headers_check
make ARCH=x86_64 INSTALL_HDR_PATH=dest headers_install
cp -rv dest/include/* $CLFS/usr/include
然后是Glibc头文件。顺便说一下,如果你用GCC 4.2.3这一步是可以忽略的,只要在配置参数上加上一个--with-newlib就可以。但是经过反复尝试在GCC 4.3里这样做是不行的。
cp configure{,.orig}
sed -e 's/3.4\*/3.[0-9]\*/g' configure.orig >configure
mkdir -v ../glibc-build
cd ../glibc-build
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache
echo "libc_cv_x86_64_tls=yes" >> config.cache
echo "install_root=${CLFS}" > configparms
CC=gcc ../glibc-2.7/configure --prefix=/usr \
--host=${CLFS_TARGET} --build=${CLFS_HOST} \
--with-headers=${CLFS}/usr/include --cache-file=config.cache
make install-headers
cp -v bits/stdio_lim.h ${CLFS}/usr/include/bits
touch ${CLFS}/usr/include/gnu/stubs.h
cp -v ../glibc-2.7/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h \
${CLFS}/usr/include/bits
以上基本是照抄,然后稍微改动一下得到的。
6. GCC 4.3-20080410 c语言静态库
在目前的阶段,GCC无法产生动态库,这是因为动态库需要启动代码,而启动代码由Libc提供,现阶段Libc还尚不存在。因此现在要编译GCC,只能选择生成静态库。
之前的版本这里有一个补丁,根据1987a网友的提示这步是不需要的,可以省略。
(可以省略)cp libgcc/Makefile.in{,.orig}
(可以省略)sed -e '/libgcc\.a libgcov\.a\s*$/s/$/ libgcc_eh.a/' libgcc/Makefile.in.orig > libgcc/Makefile.in
mkdir ../gcc-build
cd ../gcc-build
AR=ar CC_FOR_TARGET="$CLFS_TARGET-gcc" ../gcc-4.3-20080410/configure --prefix=$CLFS/cross-tools --host=$CLFS_HOST --target=$CLFS_TARGET --with-sysroot=$CLFS --disable-nls --enable-long-long --enable-languages=c --with-gmp=$CLFS/cross-tools --with-mpfr=$CLFS/cross-tools --disable-shared --disable-threads
这里要注意的是--with-gmp 和--with-mpfr参数是为了让GCC构建系统能够找到之前编译的GMP和MPFR这两个包。其余参数都可以从CLFS-SYSROOT BOOK找到。同时,AR=ar这个环境变量如果不设置,构建系统会试图寻找并不存在的x86_64-cross-linux-gnu-ar。而CC_FOR_TARGET的设置后面会提到。
构造部分非常特别,是我实验多次才找到的。
make all-gcc && make install-gcc
首先说一句,和我在别处的风格不一样,这里如果只有make install-gcc那是跑不了的。因为make install-gcc不默认执行make all-gcc。其次,这一步看上去和之前的版本一模一样,但有本质的区别。因为从GCC 4.3开始,make all-gcc就真的只会生成gcc及相关的可执行文件,至于相关的库它一点都不管了。所以我们还需要额外的步骤来生成相关的库文件。
不过有一个问题,就是随后生成库文件的步骤中,构建系统应当采用新创建的$CLFS_TARGET-gcc而不是宿主的gcc来编译。所以我们需要在配置的时候设置好CC_FOR_TARGET变量。之前曾采取过
(不建议使用)ln -sv ${CLFS_TARGET}-gcc $CLFS/cross-tools/bin/cc
的方式来绕过这个问题,不过如果你用了正确的参数,就不再需要这个步骤。
现在我们来构建GCC库文件
make all-target-libgcc && make install-target-libgcc
之前的版本我们需要一个补丁,但这个补丁其实已经包含在Glibc包中(1987a的提醒),所以这些步骤都不需要了
(不需要)cp $CLFS_TARGET/libgcc/libgcc_eh.a $CLFS/cross-tools/lib/gcc/$CLFS_TARGET/4.3.1
(不需要)cp $CLFS_TARGET/32/libgcc/libgcc_eh.a $CLFS/cross-tools/lib/gcc/$CLFS_TARGET/4.3.1/32
(不需要)${CLFS_TARGET}-ranlib $CLFS/cross-tools/lib/gcc/$CLFS_TARGET/4.3.1/libgcc_eh.a
(不需要)${CLFS_TARGET}-ranlib $CLFS/cross-tools/lib/gcc/$CLFS_TARGET/4.3.1/32/libgcc_eh.a
7. Glibc 32bit
现在我们需要构造一个32位的Glibc。先打两个补丁
patch -Np1 -i ../glibc-2.7-libgcc_eh-1.patch
patch -Np1 -i ../glibc-2.7-localedef_segfault-1.patch
GCC 4.3系列把某些头文件放在了另一个目录,致使Glibc找不到。为此我们需要一个补丁:
cp configure{,.orig}
sed -e "/ccheaders=/s/\`\(\$CC.*include\)\`/\"& -isystem \`\1-fixed\`\"/" configure.orig > configure
随后是标准步骤:
mkdir -v ../glibc-build
cd ../glibc-build
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache
echo "install_root=${CLFS}" > configparms
echo "CFLAGS += -march=i686" >> configparms
BUILD_CC="gcc" CC="${CLFS_TARGET}-gcc ${BUILD32}" \
AR="${CLFS_TARGET}-ar" RANLIB="${CLFS_TARGET}-ranlib" \
../glibc-2.7/configure --prefix=/usr \
--libexecdir=/usr/lib/glibc --host=${CLFS_TARGET32} --build=${CLFS_HOST} \
--disable-profile --enable-add-ons --with-tls --enable-kernel=2.6.0 \
--with-__thread --with-binutils=/cross-tools/bin \
--with-headers=${CLFS}/usr/include --cache-file=config.cache
make && make install
工具链的组件基本上都不可以直接make install。
8. Glibc 64bit
标准操作是要删除源代码,然后重新打补丁,重新构建。但是因为补丁是一样的,我们就没有必要删除重来了。只需要在glibc-build下
rm -rf *
然后即可开始标准步骤:
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache
echo "install_root=${CLFS}" > configparms
echo "slibdir=/lib64" >> configparms
BUILD_CC="gcc" CC="${CLFS_TARGET}-gcc ${BUILD64}" \
AR="${CLFS_TARGET}-ar" RANLIB="${CLFS_TARGET}-ranlib" \
../glibc-2.7/configure --prefix=/usr --libdir=/usr/lib64 \
--libexecdir=/usr/lib64/glibc --host=${CLFS_TARGET} --build=${CLFS_HOST} \
--disable-profile --enable-add-ons --with-tls --enable-kernel=2.6.0 \
--with-__thread --with-binutils=${CLFS}/cross-tools/bin \
--with-headers=${CLFS}/usr/include --cache-file=config.cache
make && make install
9. 终极Gcc
在GCC 4.3-20080410 中的libstdc++部分有一个bug必须修复,请参见附件。
patch -Np1 -i ../gcc-4.3-20080410-libstdc++-v3.patch.txt
mkdir -v ../gcc-build
cd ../gcc-build
AR=ar CXX_FOR_TARGET="$CLFS_TARGET-g++" CC_FOR_TARGET="$CLFS_TARGET-gcc" ../gcc-4.3-20080410/configure --prefix=${CLFS}/cross-tools \
--host=${CLFS_HOST} --target=${CLFS_TARGET} \
--with-sysroot=${CLFS} --disable-nls --enable-shared \
--enable-languages=c,c++ --enable-__cxa_atexit \
--enable-c99 --enable-long-long --enable-threads=posix \
--with-gmp=$CLFS/cross-tools --with-mpfr=$CLFS/cross-tools
这里我们再次使用了CC_FOR_TARGET和CXX_FOR_TARGET来防止库构建过程引用错误的编译器。构造过程可谓是一波三折,共需三个阶段
a. 编译并安装编译器
make all-gcc && make install-gcc
在这个阶段,为什么我们还不能大大方方地make呢?原因还是因为在构建GCC库的时候,GCC 4.3需要引用刚编译的C++编译器。这个编译器在make install-gcc的时候才能安装上。
之前我使用过这条命令
(不建议使用)ln -sv $CLFS_TARGET-g++ $CLFS/cross-tools/bin/c++
来防止错误的编译器引用。现在已经不需要了。
b.编译并安装libgcc
make all-target-libgcc && make install-target-libgcc
在后面某个阶段我们需要新安装的而不是老的libgcc(因为之前的libgcc是静态库,而这次编译用的是动态链接)。如果绕过make all-gcc直接运行这个,那么因为target-libgcc使用之前静态链接的gcc编译,随后步骤会发生一些错误。
c.最终步骤
make && make install
完成安装。
不出意外的话,经过千辛万苦,我们的SYSROOT工具链应该就完成了! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|