在Ubuntu中编译、安装 gcc4.1.1 过程以及遇到的问题
首先简单介绍一下:GCC是GUN工具链中的编译开发工具,它可以把源程序编译成为可执行文件(gcc编译C语言程序;g++编译C++语言程 序;gcj编译Java语言程序……)。例如:使用gcc由C语言源代码文件生成可执行文件的过程要经历四个相互关联的步骤:预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和 链接(Linking)。
预处理阶段:gcc调用预处理程序cpp进行预处理,该阶段负责展开宏、插入头文件等。
编译阶段:gcc调用ccl,把预处理后的文件翻译成汇编。
汇编阶段:gcc调用as,把汇编程序编译成为目标文件。
链接阶段:gcc调用连接程序ld,把目标文件和库文件链接一起,形成可执行文件。
其实安装Linux操作系统后,系统会自带GCC编译器。因此安不安装更高版本的GCC无伤大局,不过了解一下其安装过程还是有一定的好处的。
1:熟悉Linux下的命令。
2:熟悉Linux下的文件布局及其主要功能。
3:在遇到问题时,考验一下自身解决问题的能力(其实主要就是上网搜索的能力啦O(∩_∩)O)。
4:当然是课程的需要啦。
说了这么多的前言,现在进入到今天的主题:安装GCC4.1.1的过程和在安装过程中所遇到的一些问题及其解决策略。
(我的Ubuntu是 9.10 版本)
第一步:下载
在GCC网站上(http://gcc.gnu.org/) 或者通过网上搜索可以查找到下载资源。目前GCC的最新版本为4.5.0。但我用的是gcc-4.1.1.tar.bz2 网上可供下载的文件一般有两种形式:gcc-4.1.1.tar.gz和gcc-4.1.1.tar.bz2,只是压缩格式不一样,内容完全一致,下载其中一种即可。
第二步:解压缩
根据压缩格式,进行解压(以下的“%”表示命令行提示符):
% tar -xjvf gcc-4.1.1.tar. bz2
新生成的gcc-4.1.1这个目录被称为源目录,用${srcdir}表示它。以后在出现${srcdir}的地方,应该用真实的路径来替换它。用pwd命令可以查看当前路径。
在${srcdir}/INSTALL目录下有详细的GCC安装说明,可用浏览器打开index.html阅读。
第三步:建立目标目录
目标目录(用${objdir}表示)是用来存放编译结果的地方。GCC建议编译后的文件不要放在源目录${srcdir}中(虽然这样做也可以),最好单独存放在另外一个目录中,而且不能是${srcdir}的子目录。
例如,可以这样建立一个叫 gcc4 的目标目录(与源目录${srcdir}是同级目录):
% mkdir gcc4
% cd gcc4
以下的操作主要是在目标目录 ${objdir} 下进行。
第四步:配置
配置的目的是决定将GCC编译器安装到什么地方(${destdir}),支持什么语言以及指定其它一些选项等。其中,${destdir}不能与${objdir}或${srcdir}目录相同。
${srcdir}下的configure来完成的。其命令格式为(记得用你的真实路径替换${destdir})??配置是通过执行
% ${srcdir}/configure --prefix=${destdir} [其它选项]
例如,如果想将GCC 4.1.1安装到/home/ssm/gcc4目录下,则${destdir}就表示这个路径。
在我的机器上,我是这样配置的:
% ../gcc4.1.1/configure --prefix=/home/ssm/gcc4 --enable-threads--disable-checking --enable--long-long --host=i386-Ubuntu-linux--with-system-zlib --enable-languages=c,c++,java
第五步:编译
% make
这是一个漫长的过程。在我的机器上(P4-1.6),这个过程用了50多分钟
然而从这里问题就出现了:
编译了一段时间后出错,其错误信息如下:
WARNING: `makeinfo' is missing on your system. You should only need it if
you modified a `.texi' or `.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy `make' (AIX,
DU, IRIX). You might want to install the `Texinfo' package or
the `GNU make' package. Grab either from any GNU archive site.
make[3]: *** [fastjar.info] 错误 1
make[3]:正在离开目录 `/home/ssm/gcc-obj/fastjar'
make[2]: *** [all] 错误 2
make[2]:正在离开目录 `/home/ssm/gcc-obj/fastjar'
make[1]: *** [all-fastjar] 错误 2
make[1]:正在离开目录 `/home/ssm/gcc-obj'
make: *** [all] 错误 2
解读错误与解决方法:
(主要原因是GCC的版本过高)
1:全英文的这部分说的是你的系统中缺少相应版本的makeinfo软件。
因为gcc4.1以上的版本需要makeinfo的版本为4.2或更高。
所以输入命令行:
makeinfo --version 想查看makeinfo的版本。结果得到了以下信息:
The program 'makeinfo' is currently not installed. You can install it bytyping:
sudo apt-get install texinfo
按照提示输入命令,问题得到解决。
2:本机使用的Texinfo是4.11版本,
出现此错误的原因也在于configure文件中texinfo对该版本不支持,可以在解压gcc4.1.1文件夹中的configure文件里找到
以下语句
# For an installed makeinfo, we require it to be from texinfo 4.2 or
# higher, else we use the "missing" dummy.
if ${MAKEINFO} --version \
| egrep 'texinfo[^0-9]*([1-3][0-9]|4\.[2-9]|[5-9])' >/dev/null 2>&1;then
:
else
MAKEINFO="$MISSING makeinfo"
fi
;;
其中4\.[2-9]|[5-9]表示的是支持4.2-4.9之间的几个版本,所以需要自己添加4\.[1-9][0-9]*,以支持4.11版本。即把'texinfo[^0-9]*([1-3][0-9]|4\.[2-9]|[5-9])'编辑成'texinfo[^0-9]*([1-3][0-9]|4\.[2-9]|4\.[1-9][0-9]*|[5-9])'后保存,编译通过。
本来以为这样就可以了,所以将gcc-obj中生成文件删除后,用以下两条命令重新编译。
% ../gcc4.1.1/configure --prefix=/home/ssm/gcc4 --enable-threads--disable-checking --enable--long-long --host=i386-Ubuntu-linux--with-system-zlib --enable-languages=c,c++,java
make
不过依旧有问题
错误信息如下:
../../gcc-4.1.1/gcc/java/jcf-io.c:43:18: error: zlib.h: 没有该文件或目录
../../gcc-4.1.1/gcc/java/jcf-io.c: In function ‘read_zip_member’:
../../gcc-4.1.1/gcc/java/jcf-io.c:193: error: ‘Z_NO_COMPRESSION’ undeclared(first use in this function)
../../gcc-4.1.1/gcc/java/jcf-io.c:193: error: (Each undeclared identifier isreported only once
../../gcc-4.1.1/gcc/java/jcf-io.c:193: error: for each function it appears in.)
../../gcc-4.1.1/gcc/java/jcf-io.c:206: error: ‘z_stream’ undeclared (first usein this function)
../../gcc-4.1.1/gcc/java/jcf-io.c:206: error: expected ‘;’ before ‘d_stream’
../../gcc-4.1.1/gcc/java/jcf-io.c:207: error: ‘d_stream’ undeclared (first usein this function)
../../gcc-4.1.1/gcc/java/jcf-io.c:207: error: ‘alloc_func’ undeclared (firstuse in this function)
../../gcc-4.1.1/gcc/java/jcf-io.c:207: error: expected ‘;’ before numericconstant
../../gcc-4.1.1/gcc/java/jcf-io.c:208: error: ‘free_func’ undeclared (first usein this function)
../../gcc-4.1.1/gcc/java/jcf-io.c:208: error: expected ‘;’ before numericconstant
../../gcc-4.1.1/gcc/java/jcf-io.c:209: error: ‘voidpf’ undeclared (first use inthis function)
../../gcc-4.1.1/gcc/java/jcf-io.c:209: error: expected ‘;’ before numericconstant
../../gcc-4.1.1/gcc/java/jcf-io.c:225: warning: implicit declaration offunction ‘inflateInit2’
../../gcc-4.1.1/gcc/java/jcf-io.c:225: error: ‘MAX_WBITS’ undeclared (first usein this function)
../../gcc-4.1.1/gcc/java/jcf-io.c:226: warning: implicit declaration offunction ‘inflate’
../../gcc-4.1.1/gcc/java/jcf-io.c:226: error: ‘Z_NO_FLUSH’ undeclared (firstuse in this function)
../../gcc-4.1.1/gcc/java/jcf-io.c:227: warning: implicit declaration offunction ‘inflateEnd’
make[2]: *** [java/jcf-io.o] 错误 1
make[2]:正在离开目录 `/home/ssm/gcc-obj/gcc'
make[1]: *** [all-gcc] 错误 2
make[1]:正在离开目录 `/home/ssm/gcc-obj'
make: *** [all] 错误 2
解读错误与解决方法:
(主要问题在于你输入的命令行当中包含了你的系统中不存在的相应软件)
注:上面的命令行中有这一部分 --with-system-zlib 我把这部分都删除了,才解决这个错误。
原因很简单是因为--with-system-zlib,当然要求你先装装好 zlib (zlib是一种提供数据压缩的函数库--自由软件),特别是 zlib 的开发包了,一般是zlib-devel,在你系统没有安装zlib的前提下,删除该条即可。
另一种解决办法就是:你先安装好zlib,然后再编译。
sudo apt-get install zlib
但是在我的机器上出现了如下问题:找不到zlib(所以我用上面那个方法解决的问题)
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
E: 无法找到软件包 zlib
在修正上面这些错误之后进行如下步骤:
第六步:安装
%make install
至此gcc4.1.1就安装好啦。
其它设置
GCC 4.1.1的所有文件,包括命令文件(如gcc、g++)、库文件等都在${destdir}目录下分别存放,如命令文件放在bin目录下、库文件在 lib下、头文件在include下等。由于命令文件和库文件所在的目录还没有包含在相应的搜索路径内,所以必须要作适当的设置之后编译器才能顺利地找到并使用它们。
gcc、g++、gcj的设置
要想使用GCC ${destdir}/bin放在环境变量PATH中。我不用这种方式,而是用符号连接的方式实现,这样做的好处是我仍然可以使用系统上原来的旧版本的GCC编译器。??4.1.1的gcc等命令,简单的方法就是把它的路径
首先,查看原来的gcc所在的路径:
% which gcc
在我的系统上,上述命令显示:/usr/bin/gcc。因此,原来的gcc命令在/usr/bin目录下。我们可以把GCC 4.1.1中的gcc、g++、gcj等命令在/usr/bin目录下分别做一个符号连接:
% cd /usr/bin
% ln -s ${destdir}/bin/gcc gcc4
% ln -s ${destdir}/bin/g++ g++4
% ln -s ${destdir}/bin/gcj gcj4
(若不是使用root用户登录,则需要在命令行前面加 sudo )
这样,就可以分别使用gcc4、g++4、gcj4来调用GCC 4.1.1的gcc、g++、gcj完成对C、C++、JAVA程序的编译了。同时,仍然能够使用旧版本的GCC编译器中的gcc、g++等命令。
库路径的设置
将${destdir}/lib路径添加到环境变量LD_LIBRARY_PATH中,最好添加到系统的配置文件中,这样就不必要每次都设置这个环境变量了。
例如,如果GCC 4.1.1安装在/home/ssm/gcc4目录下,在Ubuntu Linux下可以直接在命令行上执行或者在文件/etc/profile中添加下面一句:
$LD_LIBRARY_PATH
测试
1:看一下gcc4的版本:
gcc4 -v
如果编译成功则输出如下信息:
使用内建 specs。
目标:i386-Ubuntu_linux
目标为:../gcc4.1.1/configure --prefix=/home/ssm/gcc4 --enable-threads--disable-checking --enable--long-long --host=i386-Ubuntu-linux--enable-languages=c,c++,java
线程模型:posix
gcc版本 4.1.1
2:用新的编译命令(gcc4、g++4等)编译你以前的C、C++程序,检验新安装的GCC编译器是否能正常工作。
例如:gcc4 -o hello.c hello
……
根据需要,可以删除或者保留${srcdir}和${objdir}目录。
自此,在Linux的Ubuntu操作系统下编译、安装gcc4.1.1的全部过程与所遇问题的解决方案叙述完毕。