临渊羡鱼,不如退而结网。
分类: LINUX
2014-02-11 01:20:35
决心投入嵌入式开发的世界,那么首先要构建一个开发环境。日常使用的是 Debian,工作内容是 ARM 平台的 Linux 内核开发。如果要依赖 Windows 才能进行,
感觉实在很窝囊。在连续几天的加班熬夜之后,终于建立起了 Linux 本地的工作环境。选择的过程很纠结,最初希望能用 Emdebian 提供的包,但是因为依赖关系不成功。
不过发现 Debian 正在努力提供一整套做好的交叉编译工具链,让我们拭目以待吧。网上最多的是使用 arm-linux-gcc 预编译包,不过不适用我 X86_64 平台,
最终决定自己动手编译。网上相关内容很多,但找到一个好用的着实不易。现将构建过程简单记录如下: 使用工具及版本:
binutils-2.24
gcc-4.8.2
glibc-2.18
linux-3.14-rc1
一切从零开始,需要五个步骤:
编译安装 binutils
编译安装最小化的 gcc
安装内核头文件
编译安装 glibc
编译安装完整版的 gcc
准备工作:
1、定义环境变量,主要是为了后续工作的方便
export TRIPLET=arm-unknown-linux-gnueabi
export TOOLS=$HOME/work/tools
export SYSROOT=$HOME/work/sysroot
注意:TRIPLET 定义为 arm-unknown-linux-gnueabi 而非 arm-unknown-linux-gnu 是因为从某个gcc版本(4.7.X)开始后者为非法了。
2、安装构建 gcc 依赖的包
apt-get install libgmp-dev libmpc-dev libmpfr-dev flex bison byacc
提示缺少什么就安装吧。
3、取得源代码包,我是去官网(gnu.org 和 kernel.org)下载了最新发行版。
4、建立相应的目录树,下面是我最终的目录结构,开始时主要是先把work/build下面的建好。work/sysroot 和 work/tools 下面都是空的。
开始构建:
1、编译安装 binutils
binutils 是为目标平台配置的,要在这里指定sysroot,而且*重要的*是,后面配置其它工具时要保持一致性,否则会出错。
cd build_binutils
../binutils-2.24/configure --prefix=$TOOLS --target=$TRIPLET --with-sysroot=$SYSROOT
make
make install
2、第一遍编译安装 gcc,最小化的 gcc
这是因为编译 gcc,需要 libc,而编译 libc 又需要 gcc,这种相互依赖关系导致不得不两遍编译 gcc。配置参数是从参考文章那里抄来的,重要的是其中
--enable-languages=c (为编译 glibc ,只需支持 c),--without-headers (不需要 c 库),--disable-threads 等(为了不依赖其它库)。
配置和编译需要第1步构造的 binutils,用 PATH 指定。
cd build_gcc_stage1
PATH=$TOOLS/bin:$PATH ../gcc-4.8.2/configure --prefix=$TOOLS --enable-languages=c --without-headers --target=$TRIPLET \
--disable-libmudflap -disable-libatomic --disable-threads --disable-shared --enable-static --disable-decimal-float --disable-libgomp \
--disable-libitm --disable-libmudflap --disable-libquadmath --disable-libsanitizer --disable-libssp
PATH=$TOOLS/bin:$PATH make
PATH=$TOOLS/bin:$PATH make install
这步只要能生成 gcc 就成了。
3、安装内核头文件,因为编译 glibc 需要内核定义的系统调用 ABI
cd linux-3.14-rc1
make headers_install ARCH=arm INSTALL_HDR_PATH=$SYSROOT/usr/
4、编译安装 glibc
重要的配置选项,--prefix=/usr (为生成正确的最终目录结构),--with-headers (指定内核位置)。
cd build_glibc
PATH=$TOOLS/bin:$PATH ../glibc-2.18/configure --prefix=/usr --build=x86_64-unknown-linux-gnu --host=$TRIPLET --target=$TRIPLET \
--with-headers=$SYSROOT/usr/include --includedir=/usr/include
PATH=$TOOLS/bin:$PATH make
PATH=$TOOLS/bin:$PATH make install install_root=$SYSROOT
注意:安装时,install_root 必须指定,因为 --prefix 指定为 /usr,而我们想要安装到的位置是 $SYSROOT 而非系统 /usr 目录。
5、第二遍编译安装 gcc,完整版的 gcc
cd build_gcc_stage2
PATH=$TOOLS/bin:$PATH ../gcc-4.8.2/configure --prefix=$TOOLS --enable-languages=c,c++ --target=$TRIPLET --with-sysroot=$SYSROOT
PATH=$TOOLS/bin:$PATH make
PATH=$TOOLS/bin:$PATH make install
如果最终能够生成 gcc g++ 等,整个交叉编译工具链就构造完了。
我的 gcc 版本信息:
[~/work/tools/bin]$ ./arm-unknown-linux-gnueabi-gcc -v
Using built-in specs.
COLLECT_GCC=./arm-unknown-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/home/lei/work/tools/libexec/gcc/arm-unknown-linux-gnueabi/4.8.2/lto-wrapper
Target: arm-unknown-linux-gnueabi
Configured with: ../gcc-4.8.2/configure --prefix=/home/lei/work/tools --enable-languages=c,c++ --target=arm-unknown-linux-gnueabi \
--with-sysroot=/home/lei/work/sysroot
Thread model: posix
gcc version 4.8.2 (GCC)
[~/work/tools/bin]$
我使用 $TOOLS/bin/$TRIPLET-gcc 编译了一个 helloworld 和一个 pthread 小程序,拷贝到目标机上运行一下,可以正常运行,看来是没有问题了。
参考文章: