之前被同学问了一个开发版上编译程序依赖的问题,对这方面不是很熟悉,回去之后又重新查了挺久,总之这是个如何用gcc编译交叉工具链的问题.
一般官方会提供好可以使用的整套编译工具链,但是如果需要编译交叉编译用的gcc,需要知道三个概念:
Build Platform: This is the platform on which the compilation tools are executed.
Host Platform: This is the platform on which the code will eventually run.
Target Platform: If this is a compiler, this is the platform that the compiler will generate code for.Build Platform:简单来说就是编译gcc的系统
Host Platform: 执行gcc来编译生成跨平台程序的平台
Target Platform: 执行编译的程序的平台
总的来说gcc也是一个软件,也需要用编译工具编译生成,当然也是使用gcc编译的.(当然第一个gcc肯定不是.
那么进入正题开始编译,这次编译的target_arch是arm-none-linux-gnueabi.
这四个字段的意思是:
arch[-vendor]-os[-abi]
arch is for architecture: arm, mips, x86, i686…
vendor is tool chain supplier: apple,
os is for operating system: linux, none (bare metal)
abi is for application binary interface convention: eabi, gnueabi, gnueabihf
目标是得到交叉编译使用的gcc编译工具链以及对应的glibc库。
为了不扰乱现有的环境而不使用系统目录变量
export SRC_DIR=/root/cross/src
export BUILD_DIR=/root/cross/build
export INSTALL_DIR=/root/cross/arm
export SYSROOT_DIR=$INSTALL_DIR/sysroot
export BINUTIL_SRC=$SRC_DIR/binutils-2.28
export KERNEL_SRC=$SRC_DIR/linux-4.12.2
export GCC_SRC=$SRC_DIR/gcc-5.4.0
export GLIBC_SRC=$SRC_DIR/glibc-2.25
export TARGET_MACH=arm-none-linux-gnueabi
export BUILD_MACH=$(gcc -dumpmachine)
export LINUX_ARCH=arm
mkdir -p $SRC_DIR
cd $SRC_DIR
cd $BINUTILS_SRC
./configure --prefix=$INSTALL_DIR --build=$BUILD_MACH --target=$TARGET_MACH --with-sysroot=$SYSROOT_DIR --disable-werror
cd $BINUTIL_SRC
make -j4
make install
cd $KERNEL_SRC
make mrproper
make ARCH=$LINUX_ARCH INSTALL_HDR_PATH=$SYSROOT_DIR/usr headers_install
# eror Building GCC requires GMP 4.2+, MPFR 2.4.0+ and MPC 0.8.0+
# slove : yum install libmpc-devel
# -disable-libmudflap --disable-libssp来禁止编译时对glibc的检查
sed -i -e '/k prot/agcc_cv_libc_provides_ssp=yes' $GCC_SRC/gcc/configure
mkdir $BUILD_DIR/build-gcc
cd $BUILD_DIR/build-gcc
$GCC_SRC/configure --prefix=$INSTALL_DIR --build=$BUILD_MACH --host=$BUILD_MACH --target=$TARGET_MACH --without-headers --enable-boostrap --enable-languages='c' --disable-threads --enable-__cxa_atexit --disable-libmudflap --with-gnu-ld --with-gnu-as --disable-libssp --disable-libgomp --disable-nls --disable-shared
make -j$(nproc) all-gcc
make install-gcc
make -j$(nproc) all-target-libgcc
make install-target-libgcc
这里之前使用6.X和5.X版本的源码编译都失败了..最后用4.8版本通过 检查一下$INSTALL_DIR/bin目录下已经有了arm-none-linux-guneabi-{tool}一套东西.
mkdir $BUILD_DIR/build-libc
cd $BUILD_DIR/build-libc
echo 'libc_cv_forced_unwind=yes' > config.cache
echo 'libc_cv_c_cleanup=yes' >> config.cache
export PATH=$INSTALL_DIR/bin:$PATH
export CC=${TARGET_MACH}-gcc
export LD=${TARGET_MACH}-ld
export AS=${TARGET_MACH}-as
加入到系统路径里并指定默认编译指令为刚编译出来的那一套东西
./configure --prefix=/usr --build=$BUILD_MACH --host=$TARGET_MACH --with-headers=$SYSROOT_DIR/usr/include --config-cache --enable-kernel=2.6.32
make -k install-headers cross_compiling=yes install_root=$SYSROOTDIR
make -j$(nproc)
make install_root=$SYSROOT_DIR install
耗时超长一度以为自己编错了。。。
之后重置
unset CC
unset LD
unset AS
我们得到了glibc,需要对gcc重新进行编译
mkdir $BUILD_DIR/build-gcc2
cd $BUILD_DIR/build-gcc2
echo 'libc_cv_forced_unwind=yes' > config.cache
echo 'libc_cv_c_cleanup=yes' >> config.cache
GCC_SRC/configure --prefix=$INSTALL_DIR --build=$BUILD_MACH --target=$TARGET_MACH --with-sysroot=$SYSROOT_DIR --with-build-sysroot=$SYSROOT_DIR --enable-languages='c,c++' --with-gnu-as --with-gnu-ld --disable-multilib --disable-nls --enable-threads=posix --enable-long-longx
–with-build-sysroot来制定头文件的位置
make -j$(nproc) all-gcc
make install-gcc
mkdir $BUILD_DIR/build-gcc3
cd $BUILD_DIR/build-gcc3
echo 'libc_cv_forced_unwind=yes' > config.cache
echo 'libc_cv_c_cleanup=yes' >> config.cache
$GCC_SRC/configure --prefix=$INSTALL_DIR --build=$BUILD_MACH --target=$TARGET_MACH --with-sysroot=$SYSROOT_DIR --with-build-sysroot=$SYSROOT_DIR --enable-languages='c,c++' --with-gnu-as --with-gnu-ld --disable-multilib --disable-nls --enable-threads=posix --disable-libssp --enable-long-longx --with-shared
make -j$(nproc)
make install
到此编译完成,工具链在 INSTALLDIR/bin下,所需环境在 SYSROOT_DIR下。
至于如何检查编译是否成功可以使用qemu来测试。
具体看使用 qemu模拟arm开发板
幸亏当初没脑子一热去学嵌入式…