当前位置:首页 » 编程软件 » powerpc交叉编译

powerpc交叉编译

发布时间: 2023-03-05 08:35:43

A. 如何在 Intel x86 服务器上构建 IBM Powerlinux 应用程序 第2页

环境和配置
测试环境有一个 IBM Flex System® 组成,该系统有多个 IBM Flex System x240 计算节点和两个基于 IBM POWER7 处理器的节点(一个 Flex System p260 和一个 Flex System p460)。出于本项目的目的,我使用一个 Flex system x240 计算节点来交叉编译 Apache httpd 和 Postgresql。构建二进制程序后,我将它们转移到 Flex System p460 计算节点。图 7 显示了 IBM Flex System 测试环境的布局图。
图 7. IBM Flex System 测试环境

以下是我的系统配置、操作系统级别和其他与系统设置相关的信息。
Flex System x240 计算节点
用于交叉编译二进制程序的 Intel 节点仅需要足够的处理能力和内存,以便能够构建 Power 二进制程序。配置如下:
基于内核的虚拟机 (KVM) 管理程序 Red Hat 6.5
32 个处理器
64 GB 内存
IBM Storwize® V7000 存取区域网络 (SAN) 连接磁盘
KVM Guest 系统
Red Hat Enterprise Linux 6.5
4 个处理器
16 GB 内存
一个 virtio 磁盘:100 GB
一个配置为 br0 的虚拟网络接口卡 (NIC)
所有其他 KVM Guest 系统都已关闭,以消除破坏环境的任何可能性。
Flex System p440 计算节点
Flex System p440 计算节点包含多个逻辑分区 (LPAR),其中一个配置为测试服务器。PowerLinux 服务器配置如下:
IBM PowerVM® 来宾
Red Hat Enterprise Linux 6.5
8 个处理器(专用)
32 GB 内存
Storwize V7000 SAN 连接磁盘 (50 GB)
通过虚拟 I/O 服务器 (VIOS) 共享的以太网适配器
LPAR 配置
最小内存:256 MB
目标内存:32 GB
最大内存:64 GB
最少处理器数:8
目标处理器数:8
最大处理器数:32
处理模式:专用
专用内存
虚拟以太网适配器(通过 VIOS 建立)
适配器 ID:2
VLAN ID:1
需要此适配器来激活虚拟服务器:已选择
以下是我运行的其他一些命令:
# ppc64_cpu --frequency
min: 3.56 GHz (cpu 28)
max: 3.56 GHz (cpu 4)
avg: 3.56 GHz
# ppc64_cpu --cores-present
Number of cores present = 8
# sysctl.conf
kernel.sem = 250 32000 32 12288
使用 toolchain 构建应用程序
通常,构建开源发行版的过程是一个迭代过程。如果您很幸运的话,该过程可能已构建完成。不幸的是,因为大多数开源发行版都构建于 x86 服务器之上,所以在尝试为不同架构(比如 IBM Power 架构)构建它们时可能遇到问题。
如果在 Power 上构建开源包时遇到问题,只需在互联网上搜索类似情形,查看这些已报告的问题是否与您的经历密切相关。如果是相关的,那么在大多数情况下,您可以找到如何解决该问题的建议。
对我而言,尽管为配置脚本选择正确参数后,postgresql 很好地构建完成了,但 apache httpd 没那么幸运。接下来的几节将介绍为 Power 架构构建 apache httpd 所需的修复程序。
交叉编译器经验
编写本文时,我使用的交叉编译器版本是一个仅供 IBM 内部使用的版本,它专为修复我在测试期间遇到的一个错误而构建。读者可以下载 AT 7.0-5 版,它是最新的交叉编译器(在发表本文时),拥有接下来的几段中描述的错误的修复程序。
在我尝试交叉编译 apr-1.5.1 源代码发行版时,我看到了以下编译器消息。
"sorry - this program has been built without plugin support"

按照我在互联网上搜索可能的帮助和解决方案的建议,我找到多个链接提到编译器需要使用 “plugin enabled” 选项来构建。我向 toolchain 支持小组报告了此问题,toolchain 维护人员很快就回复了我,为我提供了一个使用 plugin enabled 选项构建的修改版本。请注意,toolchain 的交叉编译器和原生编译器版本都需要使用 plugin enabled 选项构建。我能够在获得拥有该修复程序的 toolchain 版本后继续工作。
这是我使用 PowerLinux toolchain 的第一次经历。
交叉编译 httpd 2.4.3
要交叉编译 Apache httpd,需要使用另外 3 个包。它们是:apr、apr-util 和 pcre。找到下载最新包的位置后,开始使用 toolchain 交叉编译器在 x86 服务器上构建它们。
我构建 apr-1.5.1 时遇到的问题是构建 gen_test_char.o 模块。请参阅 ASF Bugzilla – 错误 51257 了解有关的更多细节。我修改了 Makefile.in 文件(如下所示)并运行 buildconf 脚本,以便将更改包含在配置脚本中。
对 Makefile.in 的修改如下所示:
[root@stgisv240 apr-1.5.1]# diff -u Makefile.in ../../apr-1.5.1/Makefile.in
--- Makefile.in 2014-03-17 10:10:26.000000000 -0500
+++ ../../apr-1.5.1/Makefile.in 2014-07-03 13:36:11.125013781 -0500
@@ -46,7 +46,6 @@

CLEAN_TARGETS = apr-config.out apr.exp exports.c export_vars.c .make.dirs build/apr_rules.out tools/gen_test_char@EXEEXT@ - tools/gen_test_char.o tools/gen_test_char.lo \
include/private/apr_escape_test_char.h
DISTCLEAN_TARGETS = config.cache config.log config.status include/apr.h include/arch/unix/apr_private.h @@ -132,10 +131,9 @@
make_tools_dir:
$(APR_MKDIR) tools
-OBJECTS_gen_test_char = tools/gen_test_char.lo $(LOCAL_LIBS)
-tools/gen_test_char.lo: make_tools_dir
-tools/gen_test_char@EXEEXT@:$(OBJECTS_gen_test_char)
- $(LINK_PROG) $(OBJECTS_gen_test_char) $(ALL_LIBS)
+tools/gen_test_char@EXEEXT@: make_tools_dir
+tools/gen_test_char@EXEEXT@: tools/gen_test_char.c
+ $(BUILD_CC) $(CFLAGS_FOR_BUILD) $< -o $@
include/private/apr_escape_test_char.h: tools/gen_test_char@EXEEXT@
$(APR_MKDIR) include/private
修改 Makefile.in 文件后,我运行 buildconf 来创建了一个新配置脚本。下一段将介绍用于配置脚本的参数和变量。顺便说一下,我是根据其他尝试在其他平台(比如 ARM)上交叉编译 Apache httpd 及其组件的开发人员的建议,为配置脚本选择配置参数的。
以下是我在 x86 服务器上运行 apr-1.5.1 组件的配置脚本时,使用的参数和环境变量。
# Config script using Power Linux toolchain on x86
BUILD_CC=gcc
CC_FOR_BUILD=gcc
CC=powerpc64-linux-gcc
CPP=powerpc64-linux-cpp
AS=powerpc64-linux-as
AR=powerpc64-linux-ar
RANLIB=powerpc64-linux-gcc-ranlib
CXX=powerpc64-linux-c++
LD=powerpc64-linux-ld
STRIP=powerpc64-linux-strip
export CC CPP AS ASCPP AR RANLIB CXXCPP CXX LD STRIP CFLAGS LDFLAGS CC_FOR_BUILD
./configure --prefix=/tmp/usr/local/apr --host=powerpc64-linux ac_cv_file__dev_zero=no
ac_cv_func_setpgrp_void=no apr_cv_tcp_nodelay_with_cork=no ac_cv_sizeof_struct_iovec=1
BUILD_CC=gcc make install
我在 Power 服务器上了略加修改的相同发行版。请注意,用于 Power 服务器的 PowerLinux toolchain 使用了具有类似命名的可执行程序,比如从原生 cpp 和 binutils 包安装的 cpp 和 ld。修改脚本中的 CPP 和 LD 变量,如下所示。确保 Power toolchain 的路径首先传入您的 PATH 环境中。
以下是我在 Power 服务器上运行 apr-1.5.1 的配置脚本时使用的参数和环境变量。
# Config script using PowerLinux toolchain on Power
BUILD_CC=gcc
CC_FOR_BUILD=gcc
CC=powerpc64-linux-gcc
CPP=cpp # Note the difference
AS=powerpc64-linux-as
AR=powerpc64-linux-ar
RANLIB=powerpc64-linux-gcc-ranlib
CXX=powerpc64-linux-c++
LD=ld # Note the difference
STRIP=powerpc64-linux-strip
#CFLAGS="-mcpu=440fp -mtune=440fp --sysroot $SYSROOT"
#LDFLAGS=-L$SYSROOT/lib
export CC CPP AS ASCPP AR RANLIB CXXCPP CXX LD STRIP CFLAGS LDFLAGS CC_FOR_BUILD
./configure --prefix=/home/usr/local/apr ac_cv_file__dev_zero=no
ac_cv_func_setpgrp_void=no apr_cv_tcp_nodelay_with_cork=no ac_cv_sizeof_struct_iovec=1
ac_cv_struct_rlimit=yes
BUILD_CC=gcc make install
以下是我在 x86 服务器上运行 apr-util-1.5.3 组件的配置脚本时使用的参数和环境变量。
# Configure script for apr-util-1.5.3 on x86
BUILD_CC=gcc
CC_FOR_BUILD=gcc
CC=powerpc64-linux-gcc
CPP=powerpc64-linux-cpp
AS=powerpc64-linux-as
AR=powerpc64-linux-ar
RANLIB=powerpc64-linux-gcc-ranlib
CXX=powerpc64-linux-c++
LD=powerpc64-linux-ld
STRIP=powerpc64-linux-strip
export CC CPP AS ASCPP AR RANLIB CXXCPP CXX LD STRIP CFLAGS LDFLAGS CC_FOR_BUILD
./configure --prefix=/tmp/usr/local/apr --host=powerpc64-linux --with-
apr=/tmp/usr/local/apr ac_cv_file__dev_zero=no ac_cv_func_setpgrp_void=no
apr_cv_tcp_nodelay_with_cork=no ac_cv_sizeof_struct_iovec=1
以下是我在 Power 服务器上运行 apr-util-1.5.3 组件的配置脚本时使用的参数和环境变量。
# Configure script for apr-util-1.5.3 on Power
BUILD_CC=gcc
CC_FOR_BUILD=gcc
CC=powerpc64-linux-gcc
CPP=cpp
AS=powerpc64-linux-as
AR=powerpc64-linux-ar
RANLIB=powerpc64-linux-gcc-ranlib
CXX=powerpc64-linux-c++
LD=ld
STRIP=powerpc64-linux-strip
export CC CPP AS ASCPP AR RANLIB CXXCPP CXX LD STRIP CFLAGS LDFLAGS CC_FOR_BUILD
./configure --prefix=/home/usr/local/apr --host=powerpc64-linux --with-
apr=/tmp/usr/local/apr ac_cv_file__dev_zero=no ac_cv_func_setpgrp_void=no
apr_cv_tcp_nodelay_with_cork=no ac_cv_sizeof_struct_iovec=1
以下是我在 x86 服务器上运行 httpd 组件的配置脚本时使用的参数和环境变量。
# Configure script for httpd 2.4.3 on x86
CC_FOR_BUILD=gcc
CC=powerpc64-linux-gcc
CPP=powerpc64-linux-cpp
AS=powerpc64-linux-as
AR=powerpc64-linux-ar
RANLIB=powerpc64-linux-gcc-ranlib
CXX=powerpc64-linux-c++
LD=powerpc64-linux-ld
STRIP=powerpc64-linux-strip
export CC CPP AS ASCPP AR RANLIB CXXCPP CXX LD STRIP CFLAGS LDFLAGS CC_FOR_BUILD
./configure --prefix=/tmp/usr/local --host=ppc64 ap_cv_void_ptr_lt_long=no --with-
pcre=/tmp/usr/local/bin/pcre-config --with-apr=/tmp/usr/local/apr --with-mpm=worker--
with-apr-util=/tmp/usr/local/apr/bin/apu-1-config
以下是我在 Power 服务器上运行 httpd 组件的配置脚本时使用的参数和环境变量。
# Configure script for httpd 2.4.3 on Power
CC_FOR_BUILD=gcc
CC=powerpc64-linux-gcc
CPP=cpp
AS=powerpc64-linux-as
#ASCPP=powerpc-apm-linux-gnu-as
AR=powerpc64-linux-ar
RANLIB=powerpc64-linux-gcc-ranlib
#CXXCPP=powerpc-apm-linux-gnu-cpp
CXX=powerpc64-linux-c++
LD=/opt/at7.0-5-rc1/bin/ld
STRIP=powerpc64-linux-strip
#CFLAGS="-mcpu=440fp -mtune=440fp --sysroot $SYSROOT"
#LDFLAGS=-L$SYSROOT/lib
export CC CPP AS ASCPP AR RANLIB CXXCPP CXX LD STRIP CFLAGS LDFLAGS CC_FOR_BUILD
./configure --prefix=/home/usr/local --host=ppc64 ap_cv_void_ptr_lt_long=no--with-
pcre=/home/usr/local/bin/pcre-config --with-apr=/home/usr/local/apr --with-mpm=worker--
with-apr-util=/home/usr/local/apr/bin/apu-1-config
交叉编译 PostgreSQL 9.4.3
不同于之前构建 httpd 所需的源代码发行版,我在交叉编译 PostgreSQL 时未遇到问题。PostgreSQL 是使用以下配置脚本来构建的。
以下是我在 x86 服务器上运行 PostgresSQL 的配置脚本时使用的参数和环境变量。
# Configure script for postgresql-9.3.4 on x86
CC=powerpc64-linux-gcc
CPP=powerpc64-linux-cpp
AS=powerpc64-linux-as
AR=powerpc64-linux-ar
RANLIB=powerpc64-linux-gcc-ranlib
CXX=powerpc64-linux-c++
D=powerpc64-linux-ld
STRIP=powerpc64-linux-strip
export CC CPP AS ASCPP AR RANLIB CXXCPP CXX LD STRIP CFLAGS LDFLAGS CC_FOR_BUILD
./configure --prefix=/tmp/usr/local --host=powerpc64-linux --without-readline --without-zlib
与 Apache 配置脚本一样,您可以注意到针对 Power 服务器 toolchain 使用了具有类似命名的可执行程序,比如从原生 cpp和 binutils 包安装的 cpp 和 ld。修改脚本中的 CPP 和 LD 变量,如下所示。确保 toolchain 的路径首先传入您的 PATH 环境中。
以下是我在 Power 服务器上运行 PostgresSQL 的配置脚本时使用的参数和环境变量。
# Configure script for postgresql-9.3.4 on Power
CC=powerpc64-linux-gcc
CPP=cpp
AS=powerpc64-linux-as
AR=powerpc64-linux-ar
RANLIB=powerpc64-linux-gcc-ranlib
CXX=powerpc64-linux-c++
LD=powerpc64-linux-ld
STRIP=powerpc64-linux-strip
export CC CPP AS ASCPP AR RANLIB CXXCPP CXX LD STRIP CFLAGS LDFLAGS CC_FOR_BUILD
./configure --prefix=/home/usr/local --host=powerpc64-linux --without-readline --without-zlib
结束语
toolchain 交叉编译器的实际价值在于,开发人员可在他们熟悉的开发平台上(在大多数情况下是 x86)编译和构建 Power Architecture 应用程序。从我们的用例中可以看到,toolchain 可生成像原生编译的应用程序一样高效地执行的二进制可执行程序和库。而且,交叉编译的库与原生编译的应用程序兼容。最后但同样重要的是,交叉编译的应用程序可在本地调试以及使用 gdb 调试器远程调试。
PowerLinux toolchain 与在 x86 平台上使用原生 Linux toolchain 没什么不同。希望本文能让读者很好地了解 PowerLinux toolchain 的特性和功能。

B. 如何为嵌入式开发建立交叉编译环境

下面我们将以建立针对arm的交叉编译开发环境为例来解说整个过程,其他的体系结构与这个相类似,只要作一些对应的改动。我的开发环境是,宿主机 i386-redhat-7.2,目标机 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,编译时将会报如下的错误
../../gcc-2.95.3/gcc/libgcc2.c:41: stdlib.h: No such file or directory
../../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
如果没有定义 -D__gthr_posix_h,编译时会报如下的错误
In file included from gthr-default.h:1,
from ../../gcc-2.95.3/gcc/gthr.h:98,
from ../../gcc-2.95.3/gcc/libgcc2.c:3034:
../../gcc-2.95.3/gcc/gthr-posix.h:37: pthread.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
还有一种与-Dinhibit同等效果的方法,那就是在你配置configure时多加一个参数-with-newlib,这个选项不会迫使我们必须使用newlib。我们编译了bootstrap-gcc后,仍然可以选择任何c库。
接着就是配置boostrap gcc, 后面要用bootstrap gcc 来编译 glibc 库。
$cd ..; cd build-boot-gcc
$../gcc-2.95.3/configure --target=$TARGET --prefix=$PREFIX \
>--without-headers --enable-languages=c --disable-threads
这条命令中的 -target、--prefix 和配置 binutils 的含义是相同的,--without-headers 就是指不需要头文件,因为是交叉编译工具,不需要本机上的头文件。-enable-languages=c是指我们的 boot-gcc 只支持 c 语言。--disable-threads 是去掉 thread 功能,这个功能需要 glibc 的支持。
接着我们编译并安装 boot-gcc
$make all-gcc
$make install-gcc
我们来看看 $PREFIX/bin 里面多了哪些东西
$ls $PREFIX/bin
你会发现多了 arm-linux-gcc 、arm-linux-unprotoize、cpp 和 gcov 几个文件。
Gcc-gnu 的 C 语言编译器
Unprotoize-将 ANSI C 的源码转化为 K&R C 的形式,去掉函数原型中的参数类型。
Cpp-gnu的 C 的预编译器
Gcov-gcc 的辅助测试工具,可以用它来分析和优程序。
使用 gcc3.2 以及 gcc3.2 以上版本时,配置 boot-gcc 不能使用 --without-headers 选项,而需要使用 glibc 的头文件。
回页首
建立 c 库(glibc)
首先解压 glibc-2.2.3.tar.gz 和 glibc-linuxthreads-2.2.3.tar.gz 源代码
$cd $PRJROOT/build-tools
$tar -xvzf glibc-2.2.3.tar.gz
$tar -xzvf glibc-linuxthreads-2.2.3.tar.gz --directory=glibc-2.2.3
然后进入 build-glibc 目录配置 glibc
$cd build-glibc
$CC=arm-linux-gcc ../glibc-2.2.3/configure --host=$TARGET --prefix="/usr"
--enable-add-ons --with-headers=$TARGET_PREFIX/include
CC=arm-linux-gcc 是把 CC 变量设成你刚编译完的boostrap gcc,用它来编译你的glibc。--enable-add-ons是告诉glibc用 linuxthreads 包,在上面我们已经将它放入了 glibc 源码目录中,这个选项等价于 -enable-add-ons=linuxthreads。--with-headers 告诉 glibc 我们的linux 内核头文件的目录位置。
配置完后就可以编译和安装 glibc
$make
$make install_root=$TARGET_PREFIX prefix="" install
然后你还要修改 libc.so 文件

GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a)
改为
GROUP ( libc.so.6 libc_nonshared.a)
这样连接程序 ld 就会在 libc.so 所在的目录查找它需要的库,因为你的机子的/lib目录可能已经装了一个相同名字的库,一个为编译可以在你的宿主机上运行的程序的库,而不是用于交叉编译的。
回页首
建立全套编译器(full gcc)
在建立boot-gcc 的时候,我们只支持了C。到这里,我们就要建立全套编译器,来支持C和C++。
$cd $PRJROOT/build-tools/build-gcc
$../gcc-2.95.3/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c,c++
--enable-languages=c,c++ 告诉 full gcc 支持 c 和 c++ 语言。
然后编译和安装你的 full gcc
$make all
$make install
我们再来看看 $PREFIX/bin 里面多了哪些东西
$ls $PREFIX/bin
你会发现多了 arm-linux-g++ 、arm-linux-protoize 和 arm-linux-c++ 几个文件。
G++-gnu的 c++ 编译器。
Protoize-与Unprotoize相反,将K&R C的源码转化为ANSI C的形式,函数原型中加入参数类型。
C++-gnu 的 c++ 编译器。
到这里你的交叉编译工具就算做完了,简单验证一下你的交叉编译工具。
用它来编译一个很简单的程序 helloworld.c
#include <stdio.h>
int main(void)
{
printf("hello world\n");
return 0;
}
$arm-linux-gcc helloworld.c -o helloworld
$file helloworld
helloworld: ELF 32-bit LSB executable, ARM, version 1,
dynamically linked (uses shared libs), not stripped
上面的输出说明你编译了一个能在 arm 体系结构下运行的 helloworld,证明你的编译工具做成功了。
转载仅供参考,版权属于原作者

热点内容
java返回this 发布:2025-10-20 08:28:16 浏览:743
制作脚本网站 发布:2025-10-20 08:17:34 浏览:1007
python中的init方法 发布:2025-10-20 08:17:33 浏览:713
图案密码什么意思 发布:2025-10-20 08:16:56 浏览:875
怎么清理微信视频缓存 发布:2025-10-20 08:12:37 浏览:774
c语言编译器怎么看执行过程 发布:2025-10-20 08:00:32 浏览:1122
邮箱如何填写发信服务器 发布:2025-10-20 07:45:27 浏览:347
shell脚本入门案例 发布:2025-10-20 07:44:45 浏览:225
怎么上传照片浏览上传 发布:2025-10-20 07:44:03 浏览:911
python股票数据获取 发布:2025-10-20 07:39:44 浏览:871