gcc编译器常用选项的含义

gcc是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C++、Object C、Jave等多种语言编写的程序。gcc又可以作为交叉编译工具,它能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件。

gcc名称:
GNU project C andC++ Compiler
GNU CompilerCollection


gcc的编译流程有四个步骤:
• 预处理(Pre-Processing)
    gcc  -E  test.c  -o  test.i    //.i文件
• 编译(Compiling)
    gcc  -S  test.i  -o   test.s   //.s文件
• 汇编(Assembling)
    gcc  -c  test.s  -o  test.o    //.o文件
• 链接(Linking)
    gcc  test.o  -o  test    //bin文件

如果是c++ 直接将gcc改为g++即可。


项目实践中最常用的编译选项是:
gcc  -c  test.c           //.o文件,汇编
gcc  -o  test  test.c  //bin可执行文件
gcc  test.c                //test.out可执行文件。这里省略了目标文件,gcc会默认生成可执行的文件,名为:编译文件.out


gcc基本使用格式:
$ gcc [选项] 要编译的文件 [选项] [目标文件]

常用选项及含义:

gcc有超过100个的可用选项,主要包括总体选项、告警和出错选项、优化选项和体系结构相关选项。以下只对部分常用的选项进行解释:

-c 只是编译不链接(仅把源代码编译为目标代码),生成目标文件“.o”。
-E 只进行预编译,不做其他处理。当这个选项被使用时, 预处理器的输出被送到标准输出而不是储存在文件里。
-S 只是编译不汇编,生成汇编代码。(在为C代码产生了汇编语言文件后停止编译。)gcc产生的汇编语言文件的缺省扩展名是.s 。
-o file 把输出文件输出到file里(即:为将产生的可执行文件用指定的文件名。)

-O 对源代码进行基本优化(主要进行跳转和延迟退栈两种优化)。这些优化在大多数情况下都会使程序执行的更快。
-O2 产生尽可能小和尽可能快的代码。 如-O2,-O3,-On(n常为0--3);
-O2 除了完成-O1的优化之外,还进行一些额外的调整工作,如指令调整等。
-O3 则包括循环展开和其他一些与处理特性相关的优化工作。
选项将使编译的速度比使用 -O 时慢,但通常产生的代码执行速度会更快。如:

$ gcc test.c -O3
$ gcc -O3 test.c
$ gcc -o tt test.c -O2
$ gcc -O2 -o tt test.c

-g 在可执行程序中包含标准调试信息(产生能被GNU调试器使用的调试信息以便调试你的程序。)
-pg 在编译好的程序里加入额外的代码。运行程序时, 产生gprof用的剖析信息以显示你的程序的耗时情况。
-v 打印出编译器内部编译各过程的命令行信息和编译器的版本
-I 指定头文件目录。可以用相对路径,比如头文件在当前目录,可以用-I.来指定。 注意:这里是大写的i
-L 指定库文件目录。可以用相对路径,比如库文件在当前目录,可以用-L.来指定。
-l 指定程序要链接的库,-l参数紧接着就是库名。在 这里解释过把库文件名的头lib和尾.so去掉就是库名。 注意:这里是小写的L
-include 用来包含头文件。一般情况下包含头文件都在源码里用#include 实现,故-include参数很少用。

-static 链接静态库
-llibrary 连接名为 library 的库文件
-Wall 打印出gcc提供的警告信息
-w     关闭所有警告信息
-v      列出所有编译步骤

关于-I,-L和-l的几点补充解释:

    /usr/include目录一般是不用指定的,gcc知道去那里找,但是如果头文件不在/usr/icnclude目录的时候,需要用-I参数告诉gcc,比如头文件放在/myinclude目录里,那编译时加上-I/myinclude,如果不加你会得到一个"xxxx.h: No such file or directory"的错误。如果你指定了-I参数,gcc会先查找这个目录,然后才查找默认路径(/usr/include)。
    比如我们自已要用到一个第三方提供的库名字叫libtest.so,那么我们只要把libtest.so拷贝到 /usr/lib里,编译时加上-ltest参数,我们就能用上libtest.so库了(当然要用libtest.so库里的函数,我们还需要与 libtest.so配套的头文件)。放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了,但如果库文件没放在这三个目录里,而是放在其他目录里,这时我们只用-l参数的话,链接还是会出错,出错信息大概是:“/usr/bin/ld: cannot find -lxxx”,也就是链接程序ld在那3个目录里找不到libxxx.so,这时另外一个参数-L就派上用场了,比如常用的X11的库,它放在/usr/X11R6/lib目录下,我们编译时就要用-L/usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。再比如我们把libtest.so放在/aaa/bbb/ccc目录下,那链接参数就是-L/aaa/bbb/ccc -ltest。
    另外,大部分libxxxx.so只是一个链接,以RH9为例,比如libm.so它链接到/lib/libm.so.x,/lib/libm.so.6 又链接到/lib/libm-2.3.2.so,如果没有这样的链接,还是会出错,因为ld只会找libxxxx.so,所以如果你要用到xxxx库,而只有libxxxx.so.x或者libxxxx-x.x.x.so,做一个链接就可以了ln -s libxxxx-x.x.x.so libxxxx.so。手工写链接参数是很麻烦的,很多库开发包提供了生成链接参数的程序,名字一般叫xxxx-config,具体介绍可以点这里(http://blog.csdn.net/zhuxiaoyang2000/article/details/5575194)。



参考:

http://blog.csdn.net/rain208/article/details/4060384

http://blog.csdn.net/zhuxiaoyang2000/article/details/5575194


你可能感兴趣的:(Linux学习)