版主
主题
回帖0
积分10609
阅读权限200
注册时间2008-11-22
最后登录1970-1-1
在线时间 小时
|
[介绍] ' C6 b0 o1 ^$ p6 D7 M
gcc and g++分别是gnu的c & c++编译器 gcc/g++在执行编译工作的时候,总共需要4步 " Z; q f2 P' H. c& C1 A
& {. [, Y2 |2 Y8 \, l
1.预处理,生成.i的文件[预处理器cpp]
+ y2 _$ Q; B& o* A/ B2.将预处理后的文件不转换成汇编语言,生成文件.s[编译器egcs] 6 h% x" t" y3 W
3.有汇编变为目标代码(机器代码)生成.o的文件[汇编器as]
* c, s/ H' J6 Z- N. k4.连接目标代码,生成可执行程序[链接器ld] ( X0 O8 X5 X+ r" S6 H
[参数详解]
& I, [7 q9 O" v-x language filename 2 M0 D- ~" N/ \ p3 S4 t& p8 o; V
设定文件所使用的语言,使后缀名无效,对以后的多个有效.也就是根据约定C语言的后 + Y+ x, O6 z# F# J0 @) u0 s
缀名称是.c的,而C++的后缀名是.C或者.cpp,如果你很个性,决定你的C代码文件的后缀 * W) o5 i/ Z# x& E3 D, J2 M+ u
名是.pig 哈哈,那你就要用这个参数,这个参数对他后面的文件名都起作用,除非到了
?. r3 | Q1 N( c/ G" O8 l$ P/ s下一个参数的使用。
; K7 }7 a7 M# s" _ 可以使用的参数吗有下面的这些
6 @9 v& N x3 M( o- @0 b1 Y9 J8 B- S j `c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `a ( [1 Y* V$ L/ v8 E$ e
ssembler-with-cpp'. , Q# Y' M, t9 N8 s( u7 i, n
看到英文,应该可以理解的。
0 C; | s) V& x. v2 B+ `3 G; z9 A 例子用法:
9 }5 `/ v- K: P1 K; i' f: N gcc -x c hello.pig
9 j6 e" D& X( `* `. y# D # V$ C) S" [: S8 C& l
-x none filename
$ Q9 t2 } ?+ [! L+ M" g* M 关掉上一个选项,也就是让gcc根据文件名后缀,自动识别文件类型 5 C& ^/ S3 v# E/ V
例子用法:
6 X! m, ~' y N( x! y4 A7 |' a gcc -x c hello.pig -x none hello2.c : z2 u5 @7 w1 }% J4 A- ?3 b7 |
( |2 h8 s/ W6 q/ n; \. a
-c 6 g, y8 `- W+ g" v" t
只激活预处理,编译,和汇编,也就是他只把程序做成obj文件
% o0 m) x2 Z! | Q 例子用法: 0 f& M6 D, P% [ E
gcc -c hello.c ( m, P/ w# d. r2 K' N# q
他将生成.o的obj文件
$ e$ J3 i4 |. u4 n* H/ R U' i-S - r; i2 d; S) ]9 f% W* T" ]
只激活预处理和编译,就是指把文件编译成为汇编代码。
, ?9 E. B7 d: B0 o, ?: Z! R 例子用法
5 `2 ?5 ^/ l3 x/ s* L gcc -S hello.c , u) D0 [. u( B7 H$ j
他将生成.s的汇编代码,你可以用文本编辑器察看
* a0 l" m/ M2 I! e- V) |7 m- z-E ; [; s0 i; }" `1 j6 P8 N$ K% ^" u
只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面. ' @2 W! o! C8 ^* j- C: \
例子用法: 8 @$ F' _% |4 Y9 c+ q' F4 w9 _
gcc -E hello.c > pianoapan.txt
, B& j0 s m3 z gcc -E hello.c | more / d3 p( H( i/ ?) W, G
慢慢看吧,一个hello word 也要与处理成800行的代码 5 E8 [! P9 t# u$ S5 ^
-o
* v: N& X2 r$ Q$ m 制定目标名称,缺省的时候,gcc 编译出来的文件是a.out,很难听,如果你和我有同感
5 t" x- d) z8 S+ n% ]4 Z* T,改掉它,哈哈
# v Z9 r+ B) A D: u0 b 例子用法
, w1 h* w# I, v gcc -o hello.exe hello.c (哦,windows用习惯了)
, [& e1 T! G; K gcc -o hello.asm -S hello.c
3 K+ L6 C0 U q# j8 d7 w-pipe 8 p; ~* V8 I% b5 c) D
使用管道代替编译中临时文件,在使用非gnu汇编工具的时候,可能有些问题
' Y. a3 I% ^" h8 v: c" [6 v6 W0 B2 d! |- { gcc -pipe -o hello.exe hello.c
7 U F- G; O6 {* f-ansi
. |4 D$ w6 G: r L; f. z2 F4 O+ C 关闭gnu c中与ansi c不兼容的特性,激活ansi c的专有特性(包括禁止一些asm inl
, V7 T' w7 H! D* t2 Wine typeof关键字,以及UNIX,vax等预处理宏, # d' l+ D6 Y1 B. L% z9 }; S
-fno-asm * ?0 I2 ?' I) e* ?9 [* B' r" O
此选项实现ansi选项的功能的一部分,它禁止将asm,inline和typeof用作关键字。 * u' e+ R* i1 e2 }5 K
( o7 g, g. E1 p% x0 q, g# p3 F
-fno-strict-prototype H" \9 B% T! E
只对g++起作用,使用这个选项,g++将对不带参数的函数,都认为是没有显式的对参数 . H4 B! F3 }' q& [: S
的个数和类型说明,而不是没有参数. 9 i$ ] P! \% L# v
而gcc无论是否使用这个参数,都将对没有带参数的函数,认为城没有显式说明的类型
' S+ @& k8 H, A6 G. G$ Y @1 a4 a3 r+ l
+ d" q2 f8 `1 ~- o3 Y. f* K& P-fthis-is-varialble ; _8 ~: Y' `$ Q# P
就是向传统c++看齐,可以使用this当一般变量使用. 3 S1 o \# W) B* y1 j: R
6 Q, l; I0 g+ Z% R! L4 y$ E
-fcond-mismatch $ F3 S2 u2 D) a
允许条件表达式的第二和第三参数类型不匹配,表达式的值将为void类型 $ a/ e$ N8 a/ z2 |: x% s3 j- U" h( ]
, T7 E1 A$ |2 M" P( z% u. F6 O-funsigned-char 5 E1 p! x" a, h& |, ]/ ?9 _
-fno-signed-char
6 K- x I+ E$ o. A-fsigned-char # i9 M. c M) Y( n9 r0 O
-fno-unsigned-char
$ h( t: I) T1 G. Q6 Z6 q& r 这四个参数是对char类型进行设置,决定将char类型设置成unsigned char(前两个参
; s5 b# F3 G1 k5 e- [8 m% o3 Q' ~ M数)或者 signed char(后两个参数) ) e1 ]% S( F/ }. [7 w$ t, ?
8 q5 H% j6 {0 n6 {2 k
-include file
: W8 x0 M3 U& s: U+ q+ S, T 包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以用它设 # o, s! W$ G+ K; T' R1 a$ g, e
定,功能就相当于在代码中使用#include<filename> + |& {+ |4 v$ W `0 _- i$ f3 U& h
例子用法:
7 N$ s; W& z9 D8 _6 W1 }7 _ gcc hello.c -include /root/pianopan.h 5 ] t& W: G( p+ c
" t& w z9 w9 z6 s2 o-imacros file
6 \( z% C1 L5 U$ C8 i2 }% a9 i. m 将file文件的宏,扩展到gcc/g++的输入文件,宏定义本身并不出现在输入文件中
3 o% j# W- J& q4 f4 Q
U7 Z8 B6 m8 t' G-Dmacro 0 h4 z1 ^8 t) A9 d0 J
相当于C语言中的#define macro . \* O5 F. w7 z% }, X; a
2 ]# w8 b/ q: t* `5 z; v-Dmacro=defn 6 ?) |# R% K$ F$ L
相当于C语言中的#define macro=defn
- j0 C* m9 o% g! N f) U% {
! L6 J" W; N! a! R+ m" l, G: t-Umacro
`. {/ W- P4 q! u6 b | 相当于C语言中的#undef macro + c- A( w! b4 L. l' a& M# H
-undef
8 Y2 L$ J( ~/ L6 F, t' L5 Q$ l o 取消对任何非标准宏的定义
6 P4 |$ k; H9 A : I6 Y0 s l4 B% r
-Idir ) ^$ T( g7 O$ I5 `( M; q# @$ G7 d9 \
在你是用#include"file"的时候,gcc/g++会先在当前目录查找你所制定的头文件,如 % [( y; f$ y# E/ O1 W: ^
果没有找到,他回到缺省的头文件目录找,如果使用-I制定了目录,他 0 m1 t; i8 }% U* z0 J4 T( N
回先在你所制定的目录查找,然后再按常规的顺序去找. / r3 H+ b) S1 L7 g. l% [
对于#include<file>,gcc/g++会到-I制定的目录查找,查找不到,然后将到系统的缺 ( t0 C4 x* G" Y# X7 y. `7 P" |2 I
省的头文件目录查找 * h0 o* V1 a0 O2 H8 ^7 E V, C+ U
$ E0 {8 t5 @. @1 y$ i- C
-I-
8 [1 G* Q2 L! }1 F& o. G' k 就是取消前一个参数的功能,所以一般在-Idir之后使用 / \# L3 K7 N' M2 L0 ]- P
/ K8 `" n) ~$ d, Q-idirafter dir u3 R) }9 s# ?7 ~; A- N
在-I的目录里面查找失败,讲到这个目录里面查找. 7 z5 {9 x0 [8 h
+ a$ Q& J% Q1 g; I: R, m-iprefix prefix " U8 _, j1 ?* F3 |( ~& S. R
-iwithprefix dir
; N- ?7 k' p1 ?' U 一般一起使用,当-I的目录查找失败,会到prefix+dir下查找
$ t& x: V4 a3 Z$ Q
9 d# g' H$ u ` \; U-nostdinc
; F0 E. n% B: T: U1 a4 I 使编译器不再系统缺省的头文件目录里面找头文件,一般和-I联合使用,明确限定头
, P; W& D" c; b* L- @9 l文件的位置 8 r4 M7 g- Z3 R1 W, j$ n4 ]) q
9 X* k7 p0 m6 u5 W4 d" x4 z+ }
-nostdin C++
& V t& I- E/ `' Z, d% F 规定不在g++指定的标准路经中搜索,但仍在其他路径中搜索,.此选项在创libg++库 0 g7 j: d0 q% F' z- y
使用
% s5 S9 b4 z F8 ~$ j8 D
0 @; x3 C* W/ W. P! n/ c-C
) a: a: H+ r5 G2 h 在预处理的时候,不删除注释信息,一般和-E使用,有时候分析程序,用这个很方便的 8 g6 A% Z F. C/ E# ~! E
7 H! O: w" v- h1 W; j 2 A* [& i( f/ x, I M: }
-M ( {: V* u4 `5 a& s1 w, E2 t* P2 o
生成文件关联的信息。包含目标文件所依赖的所有源代码你可以用gcc -M hello.c
! R% A( k+ y, s: k% R- ]来测试一下,很简单。
# o: A# @+ _! R % c( `+ i9 V# }" M3 A3 V
-MM
" n Q8 ^$ S4 R4 s 和上面的那个一样,但是它将忽略由#include<file>造成的依赖关系。 9 U; V$ U* d8 r; I
/ X8 z4 V- x8 R$ [* z" q
-MD
3 S3 d. D. n2 n 和-M相同,但是输出将导入到.d的文件里面 # f* }# H4 \9 F% N
2 ^) F& u! O, U. C' a-MMD 6 a, l& u' Y: A' l
和-MM相同,但是输出将导入到.d的文件里面
' Q4 T# Q/ W0 H& L* A6 s6 L
y+ Z+ P' z! z/ p-Wa,option
7 q% V0 w- B! `1 M% A 此选项传递option给汇编程序;如果option中间有逗号,就将option分成多个选项,然
+ _$ o3 q9 h$ G# u; H后传递给会汇编程序 : c( G! X% b2 f! |
8 q- n" [! Z9 ?-Wl.option - x" u5 Z1 Z- d9 F! v
此选项传递option给连接程序;如果option中间有逗号,就将option分成多个选项,然 ; M3 G5 Y* ^5 b( v3 B# w" z1 e. C
后传递给会连接程序.
5 O Y: u/ W# I* ?6 p2 z) D; y 9 ]9 R5 ^, F: B a6 H' c# y( R# M
-llibrary ( m) |1 t1 Y3 k7 V: Q# C
制定编译的时候使用的库
/ O& p, z4 W, m0 E. X 例子用法
( E3 m3 z, F6 H7 m! A gcc -lcurses hello.c 1 E. R8 L$ E% g' }4 P
使用ncurses库编译程序 : d" O4 _, u( x0 ]
. K0 c; y/ c& | l- `-Ldir
, e& p. r' D% W" ]) q5 y 制定编译的时候,搜索库的路径。比如你自己的库,可以用它制定目录,不然
# G2 `1 C: z" ?2 V 编译器将只在标准库的目录找。这个dir就是目录的名称。
) C) T6 E/ R4 m" n4 L
! h x5 f# c+ ]3 N' _-O0
! B2 D# b, O' s1 U+ C9 ?; D-O1
- c& B9 }, r0 j: E8 Q, W-O2 ! {* `3 Z# T. @- J2 e n
-O3 + \+ d, D$ W7 d& k. C$ i% p
编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高 - r9 d/ T9 e! C1 p: R7 q
& N4 C3 M5 Y: z% j( T-g 1 K0 p! k0 x- t2 b3 @
只是编译器,在编译的时候,产生调试信息。 , m! d G u# m- `2 @
- o x. H. }) J
-gstabs
: Y6 w1 ^3 f U. ^ 此选项以stabs格式声称调试信息,但是不包括gdb调试信息.
* ^& J# o' @9 ^: y' e' I
; O9 |. `; j7 z9 U$ ?7 Z-gstabs+
- @6 r! t8 a: X 此选项以stabs格式声称调试信息,并且包含仅供gdb使用的额外调试信息.
4 E' _) c) r: t" C
' O2 g' r# a' [5 U$ F-ggdb
' h) ^( {9 u# q 此选项将尽可能的生成gdb的可以使用的调试信息. , k1 _- I1 h9 A
-static 7 j9 U2 I# t0 {- r! P
此选项将禁止使用动态库,所以,编译出来的东西,一般都很大,也不需要什么 1 e( b: u5 |! }- }3 X
动态连接库,就可以运行. ( K1 ?0 X6 G) k: n i- V* }% V. m, c
-share
- h. H7 s6 X/ x4 D2 s 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
8 T. m$ a( k3 n# i6 a-traditional 7 X" P- r* I8 L# X" ]1 t
试图让编译器支持传统的C语言特性 4 F0 }/ Q. Z) F: S3 ^( @
[参考资料] D5 ^, p T2 ~2 i
-Linux/UNIX高级编程 5 S8 s0 v+ u, o) A* N
中科红旗软件技术有限公司编著.清华大学出版社出版 5 R8 m" n; G2 Y( z, v. _- a$ |
-Gcc man page ' x P3 f/ h& M( b
. O5 A3 r6 B3 P2 q" A5 M6 V" w. @[ChangeLog] 7 b; ]0 `4 t: G9 N- r
-2002-08-10
& d1 z% u$ N( H* l7 i3 w! ~ ver 0.1 发布最初的文档
4 O$ T7 T5 H7 U4 @7 G# h2 z-2002-08-11
5 E, M& ~, O* F2 V. G( s' x( z ver 0.11 修改文档格式
2 c8 i) a3 U. i-2002-08-12
! W6 G' t- _' S2 U% g ver 0.12 加入了对静态库,动态库的参数
& I+ I/ M7 l( A" K. }-2002-08-16 ! l# Z, K" {- {, O
ver 0.16 增加了gcc编译的4个阶段的命令 ) m! ^ o. `# }- V5 O1 }6 v
运行 gcc/egcs
* y! I& E" x, b# J! A/ r**********运行 gcc/egcs*********************** 8 {' z( X7 M, B
GCC 是 GNU 的 C 和 C++ 编译器。实际上,GCC 能够编译三种语言:C、C++ 和 O m1 {( N1 ~; a: F; C+ T
bject C(C 语言的一种面向对象扩展)。利用 gcc 命令可同时编译并连接 C 和 C++ * P d9 d: m" w0 @, v
源程序。
" h$ y$ Z; t k. [ 如果你有两个或少数几个 C 源文件,也可以方便地利用 GCC 编译、连接并生成可 . p) i1 O/ R, _2 e6 w5 r
执行文件。例如,假设你有两个源文件 main.c 和 factorial.c 两个源文件,现在要编 # K6 U' O6 J- O0 Y
译生成一个计算阶乘的程序。 y3 Y6 c P# W3 C
代码: 3 x0 h( M! O6 d. P9 Q* i
----------------------- 8 V, J8 v V) e4 u
清单 factorial.c & E0 Z2 a# H# g' h! ~
----------------------- # s+ P/ `- |3 [9 m( A
int factorial (int n)
* ^7 ^2 L$ M1 O- P; S9 g{ 3 F1 b# } a R5 I O5 |8 f
if (n <= 1) + f: k( S. U! I7 D2 _
return 1; # {: S3 U5 Q2 B/ g7 C
else
8 P: N: O/ f: M0 ]' [ return factorial (n - 1) * n;
# |4 R& w) K8 H) H2 l2 O}
8 E9 n9 y) s# O/ j) F/ x6 t-----------------------
, W. U% C. f7 K# j- _清单 main.c : H& {& j& I& D. k; w0 W
-----------------------
]$ c. u3 M5 A7 E, ?% N& Q0 P#include <stdio.h> 8 Q1 q6 h% e7 `' w
#include <unistd.h> # ?0 }9 r A) D! |+ s6 ~0 `
int factorial (int n);
$ `# M/ E ]+ ?. Wint main (int argc, char **argv)
( w% G( W7 j2 w& q; C{
" J" T) l1 Q1 M' ] int n;
% {! {% R) e5 U X, R# g; u if (argc < 2) ( {/ R3 Z" b `' z
{ 6 z# g- e& a* C/ z' R; e0 K+ C! ~
printf ("Usage: %s n\n", argv [0]);
, T4 k% L# Q/ G8 n( w4 T: i return -1; 8 F7 H+ l0 z$ m
}
, d4 S ]( O+ I9 d; o* G4 ] else # b2 B: i, _/ F! b2 e0 J
{ 4 e( \" R8 h: k) p( ~; t
n = atoi (argv[1]);
$ s8 A G. j. [2 [ printf ("Factorial of %d is %d.\n", n, factorial (n)); 4 U8 U+ c$ M4 S0 i; @
}
$ P% r; l3 z/ h2 i8 h return 0;
; C7 H: C' I3 ^$ r! }! B3 |! M}
6 P0 c6 m5 B" o6 R' \ I( d----------------------- " r$ J1 i$ |. W0 z) Q
利用如下的命令可编译生成可执行文件,并执行程序:
' r5 A- e" W3 e- k5 K6 |$ gcc -o factorial main.c factorial.c
( O7 s: j8 N; ~! P% |/ H5 w9 o$ ./factorial 5
4 ^* {" ^9 d4 X: ^$ S1 d# \Factorial of 5 is 120. " d o8 T- S3 z3 h! u0 `; Q
GCC 可同时用来编译 C 程序和 C++ 程序。一般来说,C 编译器通过源文件的后缀 0 @! N( G1 b( P6 I" d0 N7 B
名来判断是 C 程序还是 C++ 程序。在 Linux 中,C 源文件的后缀名为 .c,而 C++ 源 2 O0 S5 k9 l+ {: ?2 Y
文件的后缀名为 .C 或 .cpp。但是,gcc 命令只能编译 C++ 源文件,而不能自动和 C
1 n5 I2 \8 P8 O; C++ 程序使用的库连接。因此,通常使用 g++ 命令来完成 C++ 程序的编译和连接,该程 & R; W: }+ v& r- f" q# k2 V
序会自动调用 gcc 实现编译。假设我们有一个如下的 C++ 源文件(hello.C): 9 i: y/ h/ P8 `* t6 C1 L+ U5 `( A. C) d
#include <iostream> . Q8 ]+ a; v' i% H4 Y
void main (void)
g9 L* l) t, d, I{
4 ?5 T: x( X# Y& ?- R7 s; I cout << "Hello, world!" << endl;
/ K( m3 o+ m9 n4 g6 Q7 w; ~}
9 Q9 h7 u% G1 {! r) ^( \则可以如下调用 g++ 命令编译、连接并生成可执行文件:
" i5 b) ~4 Z8 a* R- O1 w$ g++ -o hello hello.C
4 j6 b6 x! F8 d4 s+ v; i$ ./hello
7 j" f3 X* n9 t: p6 G* ZHello, world!
" Z& U3 u4 e) R0 G0 O+ s7 |**********************gcc/egcs 的主要选项********* . S, h0 C; \, w+ X9 o
gcc 命令的常用选项 " L" c, ~4 N# [3 e2 Y
选项 解释
; n* U5 l8 Q# W-ansi 只支持 ANSI 标准的 C 语法。这一选项将禁止 GNU C 的某些特色, 4 e( K5 ~3 `; j5 z7 R
例如 asm 或 typeof 关键词。
0 ]$ j1 x Q, K, L s; W-c 只编译并生成目标文件。
I7 |3 Y+ n/ _-DMACRO 以字符串“1”定义 MACRO 宏。 - l9 {/ @0 J3 k4 Q
-DMACRO=DEFN 以字符串“DEFN”定义 MACRO 宏。
# r' S0 G9 Z; F/ s4 P-E 只运行 C 预编译器。 # t0 C8 e4 p$ p7 e
-g 生成调试信息。GNU 调试器可利用该信息。 ( \, A/ K( c$ U, S
-IDIRECTORY 指定额外的头文件搜索路径DIRECTORY。 1 m% }; f. K+ y+ y! Z+ B0 T7 P
-LDIRECTORY 指定额外的函数库搜索路径DIRECTORY。 * S& I; u5 K# M; O$ u
-lLIBRARY 连接时搜索指定的函数库LIBRARY。 % }$ t, t- W E9 i
-m486 针对 486 进行代码优化。 + l' f9 ^* Y: ]: y' i* Y9 O- ]
-o FILE 生成指定的输出文件。用在生成可执行文件时。 3 q3 G8 ^) ?# F: e
-O0 不进行优化处理。 ) X+ H2 T5 @( b, I( }; u
-O 或 -O1 优化生成代码。
' [! O: W- {! z! C- P1 }-O2 进一步优化。
/ z# L5 Y1 E) i" V: t# W/ |-O3 比 -O2 更进一步优化,包括 inline 函数。
6 v4 z% k* ^: j: \-shared 生成共享目标文件。通常用在建立共享库时。 & t" s" y) ~% a& [/ | Z7 Z$ Z
-static 禁止使用共享连接。 - u- o2 e) b r0 ] \0 r2 A0 L
-UMACRO 取消对 MACRO 宏的定义。 $ `) u, s; ^- @
-w 不生成任何警告信息。
- r: k; T5 y* F3 V0 M-Wall 生成所有警告信息。
9 l5 t8 ?( w. t: c% T8 y. W$ j. U9 R, J |
|