详解GCC的下载和安装.doc_第1页
详解GCC的下载和安装.doc_第2页
详解GCC的下载和安装.doc_第3页
详解GCC的下载和安装.doc_第4页
详解GCC的下载和安装.doc_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

详解GCC的下载和安装 2008-10-28 16:22 海纳百川 CSDN 我要评论(3) GCC是Linux平台下最常用的编译程序,它是Linux平台编译器的事实标准。同时,在Linux平台下的嵌入式开发领域,GCC也是用得最普遍的一种编译器。本文将告诉读者如何下载并按照GCC。下载 在GCC网站上(/)或者通过网上搜索可以查找到下载资源。目前GCC的最新版本为 3.4.0。可供下载的文件一般有两种形式:gcc-3.4.0.tar.gz和gcc-3.4.0.tar.bz2,只是压缩格式不一样,内容完全一致,下载其中一种即可。 解压缩 根据压缩格式,选择下面相应的一种方式解包(以下的“%”表示命令行提示符):% tar xzvf gcc-3.4.0.tar.gz 或者 % bzcat gcc-3.4.0.tar.bz2 | tar xvf - 新生成的gcc-3.4.0这个目录被称为源目录,用$srcdir表示它。以后在出现$srcdir的地方,应该用真实的路径来替换它。用pwd命令可以查看当前路径。 在$srcdir/INSTALL目录下有详细的GCC安装说明,可用浏览器打开index.html阅读。建立目标目录 目标目录(用$objdir表示)是用来存放编译结果的地方。GCC建议编译后的文件不要放在源目录$srcdir中(虽然这样做也可以),最好单独存放在另外一个目录中,而且不能是$srcdir的子目录。 例如,可以这样建立一个叫 gcc-build 的目标目录(与源目录$srcdir是同级目录):% mkdir gcc-build % cd gcc-build以下的操作主要是在目标目录 $objdir 下进行。配置配置的目的是决定将GCC编译器安装到什么地方($destdir),支持什么语言以及指定其它一些选项等。其中,$destdir不能与$objdir或$srcdir目录相同。$srcdir下的configure来完成的。其命令格式为(记得用你的真实路径替换$destdir)配置是通过执行% $srcdir/configure -prefix=$destdir 其它选项例如,如果想将GCC 3.4.0安装到/usr/local/gcc-3.4.0目录下,则$destdir就表示这个路径。在我的机器上,我是这样配置的:% ./gcc-3.4.0/configure -prefix=/usr/local/gcc-3.4.0 -enable-threads=posix -disable-checking -enable-long-long -host=i386-redhat-linux -with-system-zlib -enable-languages=c,c+,java将GCC安装在/usr/local/gcc-3.4.0目录下,支持C/C+和JAVA语言,其它选项参见GCC提供的帮助说明。编译% make这是一个漫长的过程。在我的机器上(P4-1.6),这个过程用了50多分钟。安装执行下面的命令将编译好的库文件等拷贝到$destdir目录中(根据你设定的路径,可能需要管理员的权限):% make install至此,GCC 3.4.0安装过程就完成了。其它设置GCC 3.4.0的所有文件,包括命令文件(如gcc、g+)、库文件等都在$destdir目录下分别存放,如命令文件放在bin目录下、库文件在 lib下、头文件在include下等。由于命令文件和库文件所在的目录还没有包含在相应的搜索路径内,所以必须要作适当的设置之后编译器才能顺利地找到并使用它们。gcc、g+、gcj的设置要想使用GCC $destdir/bin放在环境变量PATH中。我不用这种方式,而是用符号连接的方式实现,这样做的好处是我仍然可以使用系统上原来的旧版本的GCC编译器。3.4.0的gcc等命令,简单的方法就是把它的路径首先,查看原来的gcc所在的路径:% which gcc在我的系统上,上述命令显示:/usr/bin/gcc。因此,原来的gcc命令在/usr/bin目录下。我们可以把GCC 3.4.0中的gcc、g+、gcj等命令在/usr/bin目录下分别做一个符号连接:% cd /usr/bin% ln -s $destdir/bin/gcc gcc34% ln -s $destdir/bin/g+ g+34% ln -s $destdir/bin/gcj gcj34这样,就可以分别使用gcc34、g+34、gcj34来调用GCC 3.4.0的gcc、g+、gcj完成对C、C+、JAVA程序的编译了。同时,仍然能够使用旧版本的GCC编译器中的gcc、g+等命令。库路径的设置将$destdir/lib路径添加到环境变量LD_LIBRARY_PATH中,最好添加到系统的配置文件中,这样就不必要每次都设置这个环境变量了。例如,如果GCC 3.4.0安装在/usr/local/gcc-3.4.0目录下,在RH Linux下可以直接在命令行上执行或者在文件/etc/profile中添加下面一句:$LD_LIBRARY_PATH测试用新的编译命令(gcc34、g+34等)编译你以前的C、C+程序,检验新安装的GCC编译器是否能正常工作。根据需要,可以删除或者保留$srcdir和$objdir目录。 GCC使用入门(一)(1) 2006-09-26 16:52 宇文 51CTO.com 我要评论(1) 本文将向读者介绍在Linux平台下应用程序的编译过程,以及编译程序GCC在编译应用程序的过程的具体用法,同时详细说明了GCC的常用选项、模式和警告选项。【51CTO.com独家特稿】一、GCC简介通常所说的GCC是GUN Compiler Collection的简称,除了编译程序之外,它还含其他相关工具,所以它能把易于人类使用的高级语言编写的源代码构建成计算机能够直接执行的二进制代码。GCC是Linux平台下最常用的编译程序,它是Linux平台编译器的事实标准。同时,在Linux平台下的嵌入式开发领域,GCC也是用得最普遍的一种编译器。GCC之所以被广泛采用,是因为它能支持各种不同的目标体系结构。例如,它既支持基于宿主的开发(简单讲就是要为某平台编译程序,就在该平台上编译),也支持交叉编译(即在A平台上编译的程序是供平台B使用的)。目前,GCC支持的体系结构有四十余种,常见的有X86系列、Arm、PowerPC等。同时,GCC还能运行在不同的操作系统上,如Linux、Solaris、Windows等。详解GCC的下载和安装Linux编程起步 GCC基本用法除了上面讲的之外,GCC除了支持C语言外,还支持多种其他语言,例如C+、Ada、Java、Objective-C、FORTRAN、Pascal等。本系列文章中,我们不仅介绍GCC的基本功能,还涉及到一些诸如优化之类的高级功能。另外,我们还考察GCC的一些映像操作工具,如size和objcopy等,这将在后续的文章中加以介绍。二、程序的编译过程对于GUN编译器来说,程序的编译要经历预处理、编译、汇编、连接四个阶段,如下图所示:从功能上分,预处理、编译、汇编是三个不同的阶段,但GCC的实际操作上,它可以把这三个步骤合并为一个步骤来执行。下面我们以C语言为例来谈一下不同阶段的输入和输出情况。在预处理阶段,输入的是C语言的源文件,通常为*.c。它们通常带有.h之类头文件的包含文件。这个阶段主要处理源文件中的#ifdef、 #include和#define命令。该阶段会生成一个中间文件*.i,但实际工作中通常不用专门生成这种文件,因为基本上用不到;若非要生成这种文件不可,可以利用下面的示例命令:gcc -E test.c -o test.i在编译阶段,输入的是中间文件*.i,编译后生成汇编语言文件*.s 。这个阶段对应的GCC命令如下所示:GCC -S test.i -o test.s 在汇编阶段,将输入的汇编文件*.s转换成机器语言*.o。这个阶段对应的GCC命令如下所示:GCC -c test.s -o test.o 最后,在连接阶段将输入的机器代码文件*.s(与其它的机器代码文件和库文件)汇集成一个可执行的二进制代码文件。这一步骤,可以利用下面的示例命令完成:GCC test.o -o test 上面介绍了GCC编译过程的四个阶段以及相应的命令。下面我们进一步介绍常用的GCC的模式。三、GCC常用模式这里介绍GCC追常用的两种模式:编译模式和编译连接模式。下面以一个例子来说明各种模式的使用方法。为简单起见,假设我们全部的源代码都在一个文件test.c中,要想把这个源文件直接编译成可执行程序,可以使用以下命令:$ GCC -o test这里test.c是源文件,生成的可执行代码存放在一个名为test 的文件中(该文件是机器代码并且可执行)。-o 是生成可执行文件的输出选项。如果我们只想让源文件生成目标文件(给文件虽然也是机器代码但不可执行),可以使用标记-c ,详细命令如下所示:$ GCC -c test.c默认情况下,生成的目标文件被命名为test.o,但我们也可以为输出文件指定名称,如下所示:$ GCC -c test.c -o 上面这条命令将编译后的目标文件命名为mytest.o,而不是默认的test.o。迄今为止,我们谈论的程序仅涉及到一个源文件;现实中,一个程序的源代码通常包含在多个源文件之中,这该怎么办?没关系,即使这样,用GCC处理起来也并不复杂,见下例:$ GCC -o test first.c second.c third.c该命令将同时编译三个源文件,即first.c、second.c和 third.c,然后将它们连接成一个可执行程序,名为test。 GCC使用入门(一)(2) 2006-09-26 16:52 宇文 51CTO.com 我要评论(1) 本文将向读者介绍在Linux平台下应用程序的编译过程,以及编译程序GCC在编译应用程序的过程的具体用法,同时详细说明了GCC的常用选项、模式和警告选项。需要注意的是,要生成可执行程序时,一个程序无论有有一个源文件还是多个源文件,所有被编译和连接的源文件中必须有且仅有一个main函数,因为main函数是该程序的入口点(换句话说,当系统调用该程序时,首先将控制权授予程序的main函数)。但如果仅仅是把源文件编译成目标文件的时候,因为不会进行连接,所以main函数不是必需的。四、常用选项许多情况下,头文件和源文件会单独存放在不同的目录中。例如,假设存放源文件的子目录名为./src,而包含文件则放在层次的其他目录下,如./inc。当我们在./src 目录下进行编译工作时,如何告诉GCC到哪里找头文件呢?方法如下所示:$ gcc test.c I./inc -o test上面的命令告诉GCC包含文件存放在./inc 目录下,在当前目录的上一级。如果在编译时需要的包含文件存放在多个目录下,可以使用多个-I 来指定各个目录:$ gcc test.c I./inc I././inc2 -o test这里指出了另一个包含子目录inc2,较之前目录它还要在再上两级才能找到。另外,我们还可以在编译命令行中定义符号常量。为此,我们可以简单的在命令行中使用-D选项即可,如下例所示:$ gcc -DTEST_CONFIGURATION test.c -o test上面的命令与在源文件中加入下列命令是等效的:#define TEST_CONFIGURATION在编译命令行中定义符号常量的好处是,不必修改源文件就能改变由符号常量控制的行为。五、警告功能当GCC在编译过程中检查出错误的话,它就会中止编译;但检测到警告时却能继续编译生成可执行程序,因为警告只是针对程序结构的诊断信息,它不能说明程序一定有错误,而是存在风险,或者可能存在错误。虽然GCC提供了非常丰富的警告,但前提是你已经启用了它们,否则它不会报告这些检测到的警告。在众多的警告选项之中,最常用的就是-Wall选项。该选项能发现程序中一系列的常见错误警告,该选项用法举例如下:$ gcc -Wall test.c -o test该选项相当于同时使用了下列所有的选项:unused-function:遇到仅声明过但尚未定义的静态函数时发出警告。unused-label:遇到声明过但不使用的标号的警告。unused-parameter:从未用过的函数参数的警告。unused-variable:在本地声明但从未用过的变量的警告。unused-value:仅计算但从未用过的值得警告。Format:检查对printf和scanf等函数的调用,确认各个参数类型和格式串中的一致。implicit-int:警告没有规定类型的声明。implicit-function-:在函数在未经声明就使用时给予警告。char-subscripts:警告把char类型作为数组下标。这是常见错误,程序员经常忘记在某些机器上char有符号。missing-braces:聚合初始化两边缺少大括号。Parentheses:在某些情况下如果忽略了括号,编译器就发出警告。return-type:如果函数定义了返回类型,而默认类型是int型,编译器就发出警告。同时警告那些不带返回值的 return语句,如果他们所属的函数并非void类型。sequence-point:出现可疑的代码元素时,发出报警。Switch:如果某条switch语句的参数属于枚举类型,但是没有对应的case语句使用枚举元素,编译器就发出警告(在switch语句中使用default分支能够防止这个警告)。超出枚举范围的case语句同样会导致这个警告。strict-aliasing:对变量别名进行最严格的检查。unknown-pragmas:使用了不允许的#pragma。Uninitialized:在初始化之前就使用自动变量。需要注意的是,各警告选项既然能使之生效,当然也能使之关闭。比如假设我们想要使用-Wall来启用个选项,同时又要关闭unused警告,利益通过下面的命令来达到目的:$ gcc -Wall -Wno-unused test.c -o test下面是使用-Wall选项的时候没有生效的一些警告项:cast-align:一旦某个指针类型强制转换时,会导致目标所需的地址对齐边界扩展,编译器就发出警告。例如,某些机器上只能在2或4字节边界上访问整数,如果在这种机型上把char *强制转换成int *类型, 编译器就发出警告。sign-compare:将有符号类型和无符号类型数据进行比较时发出警告。missing-prototypes :如果没有预先声明函数原形就定义了全局函数,编译器就发出警告。即使函数定义自身提供了函数原形也会产生这个警告。这样做的目的是检查没有在头文件中声明的全局函数。Packed:当结构体带有packed属性但实际并没有出现紧缩式给出警告。Padded:如果结构体通过充填进行对齐则给出警告。unreachable-code:如果发现从未执行的代码时给出警告。Inline:如果某函数不能内嵌(inline),无论是声明为inline或者是指定了-finline-functions 选项,编译器都将发出警告。 disabled-optimization:当需要太长时间或过多资源而导致不能完成某项优化时给出警告。上面是使用-Wall选项时没有生效,但又比较常用的一些警告选项。本文中要介绍的最后一个常用警告选项是-Werror。使用该选项后,GCC发现可疑之处时不会简单的发出警告就算完事,而是将警告作为一个错误而中断编译过程。该选项在希望得到高质量代码时非常有用。 六、小结本文介绍了GCC的基本编译过程和编译模式,并详细阐述了GCC的一些常用选项以及警告功能。这些是在利用GCC进行应用编程时最基本也最常用的一些内容,我们会在后续文章中继续介绍GCC的调试和优化技术。 Linux编程起步 GCC基本用法 2008-10-28 17:39 孤独的blog 百度空间 我要评论(0) 初学时最好从命令行入手,这样可以熟悉从编写程序、编译、调试和执行的整个过程。编写程序可以用vi或其它编辑器编写。编译则使用GCC命令。要往下学习首先就得熟悉GCC命令的用法。初学时最好从命令行入手,这样可以熟悉从编写程序、编译、调试和执行的整个过程。编写程序可以用vi或其它编辑器编写。编译则使用GCC命令。要往下学习首先就得熟悉GCC命令的用法。GCC命令提供了非常多的命令选项,但并不是所有都要熟悉,初学时掌握几个常用的就可以了,到后面再慢慢学习其它选项,免得因选项太多而打击了学习的信心。一. 常用编译命令选项假设源程序文件名为test.c。1. 无选项编译链接用法:#gcc test.c作用:将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。2. 选项 -o用法:#gcc test.c -o test作用:将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。3. 选项 -E用法:#gcc -E test.c -o test.i作用:将test.c预处理输出test.i文件。4. 选项 -S用法:#gcc -S test.i作用:将预处理输出文件test.i汇编成test.s文件。5. 选项 -c用法:#gcc -c test.s作用:将汇编输出文件test.s编译输出test.o文件。6. 无选项链接用法:#gcc test.o -o test作用:将编译输出文件test.o链接成最终可执行文件test。7. 选项-O用法:#gcc -O1 test.c -o test作用:使用编译优化级别1编译程序。级别为13,级别越大优化效果越好,但编译时间越长。二. 多源文件的编译方法如果有多个源文件,基本上有两种编译方法:假设有两个源文件为test.c和testfun.c1. 多个文件一起编译用法:#gcc testfun.c test.c -o test作用:将testfun.c和test.c分别编译后链接成test可执行文件。2. 分别编译各个源文件,之后对编译后输出的目标文件链接。用法:#gcc -c testfun.c /将testfun.c编译成testfun.o#gcc -c test.c /将test.c编译成test.o#gcc -o testfun.o test.o -o test /将testfun.o和test.o链接成test以上两种方法相比较,第一中方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译。Gcchowto出自Ubuntu中文目录隐藏 1 准备工作 2 编译简单的 C 程序 3 捕捉错误 4 编译多个源文件 5 简单的 Makefile 文件 6 链接外部库 7 编译C+与Fortran 8 其他参考 本文翻译自 An Introduction to GCC 的部分章节(有改动)。 编辑 准备工作 注意:本文可能会让你失望,如果你有下列疑问的话:为什么要在终端输命令啊? GCC 是什么东西,怎么在菜单中找不到? GCC 不能有像 VC 那样的窗口吗? 那么你真正想要了解的可能是 anjuta,kdevelop,geany,code blocks,eclipse,netbeans 等 IDE 集成开发环境。即使在这种情况下,由于 GCC 是以上 IDE 的后台的编译器,本文仍值得你稍作了解。 如果你还没装编译环境或自己不确定装没装,不妨先执行 sudo apt-get install build-essential如果你需要编译 Fortran 程序,那么还需要安装 gfortran(或 g77) sudo apt-get install gfortran编辑 编译简单的 C 程序 C 语言经典的入门例子是 Hello World,下面是一示例代码: #include int main(void) printf(Hello, world!n); return 0;我们假定该代码存为文件hello.c。要用 gcc 编译该文件,使用下面的命令: $ gcc -g -Wall hello.c -o hello该命令将文件hello.c中的代码编译为机器码并存储在可执行文件 hello中。机器码的文件名是通过 -o 选项指定的。该选项通常作为命令行中的最后一个参数。如果被省略,输出文件默认为 a.out。 注意到如果当前目录中与可执行文件重名的文件已经存在,它将被覆盖。 选项 -Wall 开启编译器几乎所有常用的警告强烈建议你始终使用该选项。编译器有很多其他的警告选项,但 -Wall 是最常用的。默认情况下GCC 不会产生任何警告信息。当编写 C 或 C+ 程序时编译器警告非常有助于检测程序存在的问题。 注意如果有用到math.h库等非gcc默认调用的标准库,请使用-lm参数 本例中,编译器使用了 -Wall 选项而没产生任何警告,因为示例程序是完全合法的。 选项 -g 表示在生成的目标文件中带调试信息,调试信息可以在程序异常中止产生core后,帮助分析错误产生的源头,包括产生错误的文件名和行号等非常多有用的信息。 要运行该程序,输入可执行文件的路径如下: $ ./helloHello, world!这将可执行文件载入内存,并使 CPU 开始执行其包含的指令。 路径 ./ 指代当前目录,因此 ./hello 载入并执行当前目录下的可执行文件 hello。 点击此处下载本节的操作视频 编辑 捕捉错误 如上所述,当用 C 或 C+ 编程时,编译器警告是非常重要的助手。为了说明这一点,下面的例子包含一个微妙的错误:为一个整数值错误地指定了一浮点数控制符%f。 #include int main (void) printf (Two plus two is%fn, 4); return 0;一眼看去该错误并不明显,但是它可被编译器捕捉到,只要启用了警告选项 -Wall。 编译上面的程序bad.c,将得到如下的消息: $ gcc -Wall -o bad bad.cmain.c: 在函数main中:main.c:5: 警告: 格式%f需要类型double,但实参 2 的类型为int这表明文件 bad.c第 6 行中的格式字符串用法不正确。GCC 的消息总是具有下面的格式 文件名:行号:消息。编译器对错误与警告区别对待,前者将阻止编译,后者表明可能存在的问题但并不阻止程序编译。 本例中,对整数值来说,正确的格式控制符应该是 %d。 如果不启用 -Wall,程序表面看起来编译正常,但是会产生不正确的结果: $ gcc bad.c -o bad$ ./badTwo plus two is 0.000000显而易见,开发程序时不检查警告是非常危险的。如果有函数使用不当,将可能导致程序崩溃或产生错误的结果。开启编译器警告选项 -Wall 可捕捉 C 编程时的多数常见错误。 编辑 编译多个源文件 一个源程序可以分成几个文件。这样便于编辑与理解,尤其是程序非常大的时候。这也使各部分独立编译成为可能。 下面的例子中我们将程序 Hello World 分割成 3 个文件:hello.c,hello_fn.c和头文件hello.h。这是主程序hello.c: #include hello.hint main(void) hello (world); return 0;在先前例子的hello.c中,我们调用的是库函数 printf,本例中我们用一个定义在文件hello_fn.c中的函数 hello 取代它。 主程序中包含有头文件hello.h,该头文件包含函数 hello 的声明。我们不需要在hello.c文件中包含系统头文件stdio.h来声明函数 printf,因为hello.c没有直接调用 printf。 文件hello.h中的声明只用了一行就指定了函数 hello 的原型。 void hello (const char * name);函数 hello 的定义在文件hello_fn.c中: #include #include hello.hvoid hello (const char * name) printf (Hello,%s!n, name);语句 #include FILE.h 与 #include 有所不同:前者在搜索系统头文件目录之前将先在当前目录中搜索文件FILE.h,后者只搜索系统头文件而不查看当前目录。 要用gcc编译以上源文件,使用下面的命令: $ gcc -Wall hello.c hello_fn.c -o newhello本例中,我们使用选项 -o 为可执行文件指定了一个不同的名字 newhello。注意到头文件hello.h并未在命令行中指定。源文件中的的 #include hello.h 指示符使得编译器自动将其包含到合适的位置。 要运行本程序,输入可执行文件的路径名: $ ./newhelloHello, world!源程序各部分被编译为单一的可执行文件,它与我们先前的例子产生的结果相同。 点击此处下载本节的操作视频 编辑 简单的 Makefile 文件 为便于不熟悉 make 的读者理解,本节提供一个简单的用法示例。Make 凭借本身的优势,可在所有的 Unix 系统中被找到。要了解关于Gnu make 的更多信息,请参考 Richard M. Stallman 和 Roland McGrath 编写的 GNU Make 手册。 Make 从 makefile(默认是当前目录下的名为Makefile的文件)中读取项目的描述。makefile指定了一系列目标(比如可执行文件)和依赖(比如对象文件和源文件)的编译规则,其格式如下: 目标: 依赖命令对每一个目标,make 检查其对应的依赖文件修改时间来确定该目标是否需要利用对应的命令重新建立。注意到,makefile 中命令行必须以单个的 TAB 字符进行缩进,不能是空格。 GNU Make 包含许多默认的规则(参考隐含规则)来简化 makefile 的构建。比如说,它们指定.o文件可以通过编译.c文件得到,可执行文件可以通过将.o链接到一起获得。隐含规则通过被叫做make变量的东西所指定,比如 CC(C 语言编译器)和 CFLAGS(C程序的编译选项);在makefile文件中它们通过独占一行的 变量=值 的形式被设置。对 C+ ,其等价的变量是CXX和CXXFLAGS,而变量CPPFLAGS则是编译预处理选项。 现在我们为上一节的项目写一个简单的 makefile 文件: CC=gccCFLAGS=-Wallhello: hello.o hello_fn.oclean:rm -f hello hello.o hello_fn.o该文件可以这样来读:使用 C 语言编译器 gcc,和编译选项-Wall,从对象文件hello.o和hello_fn.o生成目标可执行文件 hello(文件hello.o和hello_fn.o通过隐含规则分别由hello.c和hello_fn.c生成)。目标clean没有依赖文件,它只是简单地移除所有编译生成的文件。rm命令的选项 -f(force) 抑制文件不存在时产生的错误消息。 另外,需要注意的是,如果包含main函数的cpp文件为A.cpp, makefile中最好把可执行文件名也写成 A。 要使用该 makefile 文件,输入 make。不加参数调用make时,makefile文件中的第一个目标被建立,从而生成可执行文件hello: $ makegcc -Wall -c -o hello.o hello.cgcc -Wall -c -o hello_fn.o hello_fn.cgcc hello.o hello_fn.o -o hello$ ./helloHello, world!一个源文件被修改要重新生成可执行文件,简单地再次输入 make 即可。通过检查目标文件和依赖文件的时间戳,程序 make 可识别哪些文件已经修改并依据对应的规则更新其对应的目标文件: $ vim hello.c (打开编辑器修改一下文件)$ makegcc -Wall -c -o hello.o hello.cgcc hello.o hello_fn.o -o hello$ ./helloHello, world!最后,我们移除 make 生成的文件,输入 make clean: $ make cleanrm -f hello hello.o hello_fn.o一个专业的 makefile文件通常包含用于安装(make install)和测试(make check)等额外的目标。 本文中涉及到的例子都足够简单以至于可以完全不需要makefile,但是对任何大些的程序都使用 make 是很有必要的。 编辑 链接外部库 库是预编译的目标文件(object files)的集合,它们可被链接进程序。静态库以后缀为.a的特殊的存档文件(archive file)存储。 标准系统库可在目录 /usr/lib 与 /lib 中找到。比如,在类 Unix 系统中 C 语言的数学库一般存储为文件 /usr/lib/libm.a。该库中函数的原型声明在头文件 /usr/include/math.h 中。C 标准库本身存储为 /usr/lib/libc.a,它包含 ANSI/ISO C 标准指定的函数,比如printf。对每一个 C 程序来说,libc.a 都默认被链接。 下面的是一个调用数学库 libm.a 中 sin 函数的的例子,创建文件calc.c: #include #include int main (void) double x = 2.0; double y = sin (x); printf (The value of sin(2.0) is%fn, y); return 0;尝试单独从该文件生成一个可执行文件将导致一个链接阶段的错误: $ gcc -Wall calc.c -o calc/tmp/ccbR6Ojm.o: In function main:/tmp/ccbR6Ojm.o(.text+0x19): undefined reference to sin函数 sin,未在本程序中定义也不在默认库libc.a中;除非被指定,编译器也不会链接libm.a。 为使编译器能将 sin 链接进主程序calc.c,我们需要提供数学库libm.a。一个容易想到但比较麻烦的做法是在命令行中显式地指定它: $ gcc -Wall calc.c /usr/lib/libm.a -o calc函数库libm.a包含所有数学函数的目标文件,比如sin,cos,exp,log及sqrt。链接器将搜索所有文件来找到包含 sin 的目标文件。 一旦包含 sin 的目标文件被找到,主程序就能被链接,一个完整的可执行文件就可生成了: $ ./calcThe value of sin(2.0) is 0.909297可执行文件包含主程序的机器码以及函数库libm.a中 sin 对应的机器码。 为避免在命令行中指定长长的路径,编译器为链接函数库提供了快捷的选项-l。例如,下面的命令 $ gcc -Wall calc.c -lm -o calc与我们上面指定库全路径/usr/lib/libm.a的命令等价。 一般来说,选项 -lNAME使链接器尝试链接系统库目录中的函数库文件 libNAME.a。一个大型的程序通常要使用很多 -l 选项来指定要链接的数学库,图形库,网络库等。 编辑 编译C+与FortranGCC 是 GNU 编译器集合(GNU Compiler Collection)的首字母缩写词。GNU 编译器集合包含 C,C+,Objective-C,Fortran,Java 和 Ada 的前端以及这些语言对应的库(libstdc+,libgcj,)。 前面我们只涉及到 C 语言,那么如何用 gcc 编译其他语言呢?本节将简单介绍 C+ 和 Fortran 编译的例子。 首先我们尝试编译简单的 C+ 的经典程序 Hello world: #include int main(int argc,char *argv) std:cout hello, world std:endl; return 0;将文件保存为hello.cpp,用 gcc 编译,结果如下: $ gcc -Wall hello.cpp -o hello/tmp/cch6oUy9.o: In function _static_initialization_and_destruction_0(int, int):hello.cpp:(.text+0x23): undefined reference to std:ios_base:Init:Init()/tmp/cch6oUy9.o: In function _tcf_0:hello.cpp:(.text+0x6c): undefined reference to std:ios_base:Init:Init()/tmp/cch6oUy9.o: In function main:hello.cpp:(.text+0x8e): undefined reference to std:couthello.cpp:(.text+0x93): undefined reference to std:basic_ostreamchar, std:char_traits & std:operator std:char_traits (std:basic_ostreamchar, std:char_traits &, char const*)/tmp/cch6oUy9.o:(.eh_frame+0x11): undefined reference to _gxx_personality_v0collect2: ld returned 1 exit status出错了!而且错误还很多,很难看懂,这可怎么办呢?在解释之前,我们先试试下面的命令: $ gcc -Wall hello.cpp -o hello -lstdc+噫,加上-lstdc+选项后,编译竟然通过了,而且没有任何警告。运行程序,结果如下: $ ./hello hello, world通过上节,我们可以知道,-lstdc+ 选项用来通知链接器链接静态库 libstdc+.a。而从字面上可以看出,libstdc+.a 是C+ 的标准库,这样一来,上面的问题我们就不难理解了编译 C+ 程序,需要链接 C+ 的函数库 libstdc+.a。 编译 C 的时候我们不需要指定 C 的函数库,为什么 C+ 要指定呢?这是由于早期 gcc 是指 GNU 的 C 语言编译器(GNU C Compiler),随着 C+,Fortran 等语言的加入,gcc的含义才变化成了 GNU 编译器集合(GNU Compiler Collection)。C作为 gcc 的原生语言,故编译时不需额外的选项。 不过幸运的是,GCC 包含专门为 C+ 、Fortran 等语言的编译器前端。于是,上面的例子,我们可以直接用如下命令编译: $ g+ -Wall hello.cpp -o helloGCC 的 C+ 前端是 g+,而 Fortran 的情况则有点复杂:在 gcc-4.0 版本之前,Fortran 前端是 g77,而gcc-4.0之后的版本对应的 Fortran 前端则改为 gfortran。下面我们先写一个简单的 Fortran 示例程序: C Fortran 示例程序 PROGRAM HELLOWORLD WRITE(*,10) 10 FORMAT(hello, world) END PROGRAM HELLOWORLD将文件保存hello.f,用 GCC 的 Fortran 前端编译运行该文件 $ gfortran -Wall hello.f -o hello$ ./hellohello, world我们已经知道,直接用 gcc 来编译 C+ 时,需要链接 C+ 标准库,那么用 gcc 编译 Fortran时,命令该怎么写呢? $ gcc -Wall hello.f -o helloworld -lgfortran -lgfortranbegin注意:上面这条命令与 gfortran 前端是等价的(g77 与此稍有不同)。其中库文件 libgfortranbegin.a (通过命令行选项 -lgfortranbegin 被调用) 包含运行和终止一个 Fortran 程序所必须的开始和退出代码。库文件 libgfortran.a 包含 Fortran 底层的输入输出等所需要的运行函数。 对于 g77 来说,下面两条命令是等价的(注意到 g77 对应的 gcc 是 4.0 之前的版本): $ g77 -Wall hello.f -o hello$ gcc-3.4 -Wall hello.f -o hello -lfrtbegin -lg2c命令行中的两个库文件分别包含 Fortran 的开始和退出代码以及 Fortran 底层的运行函数。 gcc的使用命令是什么 在使用Gcc编译器的时候,我们必须给出一系列必要的调用参数和文件名称。Gcc编译器的调用参数大约有100多个,其中多数参数我们可能根本就用不到,这里只介绍其中最基本、最常用的参数。 Gcc最基本的用法是gcc options filenames 其中options就是编译器所需要的参数,filenames给出相关的文件名称。 -c,只编译,不连接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。 -o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。 -g,产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。 -O,对程序进行优化编译、连接,采用这个选项,整个源代码会在编译、连接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、连接的速度就相应地要慢一些。 -O2,比-O更好的优化编译、连接,当然整个编译、连接过程会更慢。 -Idirname,将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。C程序中的头文件包含两种情况 A)#include B)#include “myinc.h” 其中,A类使用尖括号(),B类使用双引号(“ ”)。对于A类,预处理程序cpp在系统预设包含文件目录(如/usr/include)中搜寻相应的文件,而B类,预处理程序在目标文件的文件夹内搜索相应文件。 GCC执行过程示例 示例代码 a.c: #include int main() printf(hellon); 预编译过程: 这个过程处理宏定义和include,并做语法检查。 可以看

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论