GNU Toolchain的构建
| 作者: | A.TNG |
|---|---|
| 邮箱: | tang.jiyu at gmail dot com |
| 时间: | 4/29/2008 |
| 参考: | http://www.gnu.org |
My Story
先介绍一下我的Story:两台PC,分别安装了CentOS 4.5,安装的 过程中都选择不安装任何开发工具,PC-1启动NFS服务,共享 Dir-1,并在其中安装GNU Toolchain;PC-2挂载Dir-1,设置 好对应环境变量,即可使用GNU Toolchain进行开发;往后, 有新的PC-3, PC-4等到来时,直接挂载Dir-1,设置好环境变量 即可使用GNU Toolchain进行开发。
准备工作
如同鸡生蛋、蛋孵鸡,我们若想自己构建整套GNU Toolchain, 必须有可以正常工作的GNU Toolchain。 在PC-1上,我们需要安装 下列软件包,来得到一个基础的编译环境:
cpp-4.1.1-52.el5.i386.rpm
glibc-headers-2.5-12.i386.rpm
glibc-devel-2.5-12.i386.rpm
libgomp-4.1.1-52.el5.i386.rpm
gcc-4.1.1-52.el5.i386.rpm
libstdc++-devel-4.1.1-52.el5.i386.rpm
gcc-c++-4.1.1-52.el5.i386.rpm
zlib-devel-1.2.3-3.i386.rpm
还有一些额外的软件包需要安装,编译完毕GCC时,进行测试时 会用到。
expect-5.43.0-5.1.i386.rpm
dejagnu-1.4.4-5.1.noarch.rpm
至此,PC-1已经是一台具备了基本开发环境的机器,可以作为 构建GNU Toolchain的火种了。
GNU Toolchain的族谱
构建GNU Toolchain之初,我简单的认为GCC能解决所有的问题, 有了GCC,我就可以开始开发之旅了。随着对GCC了解的深入, 我才发现了GCC身后庞大的家族,包括:
- GNU Make:编译和构建程序的自动化工具,Linux中常用 到的make命令。
- GNU Compiler Collection (GCC):一组编译器,支持多种 语言,包括:C, C++, Java, Objective-C, fortran。
- GNU Binutils:一组二进制工具,在编译完成后,链接 并生成二进制的工具。包括:ld, as等。
- GNU Lib C:标准的C库,软件开发的必需品。
- GNU Debugger (GDB):代码调试工具。
- GNU Build System (Autotools):一组自动化工具,在编译 的时候经常能用到,包括:autoconf、automake和libtool。
- GNU M4:宏预处理器,是最高级的文本宏处理系统之一。
编译和构建
上节提到的每种工具都需要下载源代码,并进行安装。曾经希望有 一些捷径,例如使用RPM包等,但是为了到达完全定制的效果,最终 只能选择下载源代码包,手动编译安装。
- 各工具的编译和安装大同小异,在PC-1上,configure/make/make install 三步曲,其中GCC的编译和安装最为复杂,耗时最长,具体可以参考 之前的文章 《Linux上编译和安装GCC》 。
- 在configure的时候,一定要设置 prefix 参数,都指定到 Dir-1目录下,特别是在编译glibc等库的时候,一旦make install 完成,就不要将安装好的库文件移动到其他路径了,不然会造成很多 关于路径的问题。
GNU Toolchain的配置和验证
配置
都安装好以后,并不能直接使用,配置也是个很重要的问题。首先, 介绍有用的命令,能帮助检查咱们的GNU Toolchain是不是在正常的 工作。
- gcc的-v参数。gcc命令有一个很有用的参数, -v ,他表示在 gcc编译源代码的过程中,动态输出相关的信息。信息中,不仅仅 包含源代码的error/warning,同时还包含gcc是在哪些路径下搜索 头文件,在哪里路径下链接哪些库文件。
- ldd。这是binutils下的一个工具,用来查看当前可执行文件中 用到了哪些共享库。
- readelf。这也是binutils下的工具,对二进制文件进行分析,可以 输出很多有用信息。
需要修改gcc的specs文件,specs文件是指示gcc如何工作的一个配置文件。 默认情况下,gcc的安装目录下是不包括specs的,gcc在编译的时候使用 其内建的specs文件,当有特殊需求时,例如,在当前情况下,我需要gcc 默认链接我自己编译的glibc库,因此需要对specs进行修改。
- 首先使用gcc的 -dumpspecs 参数来输出specs,并保存至 /Dir-1/gcc-4.2.3/lib/gcc/i686-pc-linux-gnu/4.2.3/specs
- 找到/lib/ld-linux.so.2,修改成/Dir-1/glibc-2.3.4/lib/ld-linux.so.2
需要设置的环境变量包括:
- C_INCLUDE_PATH=/Dir-1/glibc-2.3.4/include
- CPLUS_INCLUDE_PATH=/Dir-1/glibc-2.3.4/include
- LIBRARY_PATH=/Dir-1/glibc-2.3.4/lib
- LD_LIBRARY_PATH=/Dir-1/gcc-4.2.3/lib
这样才可以在编译的时候找到需要的头文件和库。同时,别忘了把 安装好的软件的bin目录设置到环境变量PATH中。
验证
可以编写一个超级简单的输出hello world的小程序。
C语言版:
#include
int main() {
printf("hello world.\n");
return 0;
}
保存为hello.c,用下列命令编译:
gcc hello.c -o hello -v
通过分析gcc的输出,查看gcc所搜索头文件的路径是否是你设置的环境 变量的路径;查看gcc链接的路径是否是你环境变量设置的路径,以及gcc 链接使用的库,都是你之前编译好的那些,如果使用到了系统的一些动态库, 你就要小心了,应该是什么地方设置出现错误了。
使用下列命令,查看动态链接库的路径是否正确:
ldd hello
输出:
libc.so.6 => /Dir-1/glibc-2.3.4/lib/libc.so.6 (0x00356000)
/Dir-1/glibc-2.3.4/lib/ld-linux.so.2 (0x00e79000)
表示链接到之前编译的glibc中。
对于C++,也可以使用类似的方法进行验证。


1 条评论:
经历+原创,支持!
看君一张贴,胜读十年书.呵呵
学习了..
期待更多的post~~
发表评论