用GCC编译链接程序--编译链接器GCC常用功能

来源:互联网 发布:linux链接mysql数据库 编辑:程序博客网 时间:2024/05/18 01:16

用GCC编译链接程序--编译链接器GCC常用功能(菜鸟级)

一,GCC编译器简介

GCCLinux平台下常用的编译链接器。编译链接的过程分为:

源代码-->预处理文件(.i-->编译后的汇编代码(.s)-->汇编后的二进制文件(.o)-->链接后的二进制物件(无后缀)

处理程序分别是 :cppcclasld

使用 -v选项,可以看到各个阶段关联的处理程序。

使用gcc -E 指示gcc对源代码进行预处理,结果直接输出到终端。

使用gcc -S 指示gcc编译成为汇编语言

使用gcc -c 指示gcc直至形成二进制文件(不进行链接)

使用gcc 指示gcc链接形成二进制物件(多个二进制模块链接形成大的模块或者可执行程序)

因此你需要的目标文件的种类是 -E-S-c或者不带这些参数确定的,

源文件可以是中间文件的一种。-o参数控制的仅仅是输出文件的名称。

但是gcc默认会根据源文件的后缀去判断应该调用处理程序的那些。例如源文件的后缀是.c,则gcc -E使用的是cppgcc -c则使用cppcclas。如果源文件的后缀是.o,则gcc -E 是无法进行的,会报错:linker input file unused because linking not done。这是gcc发现这个应该进行链接,但是选项指示不使用linker程序,因而报这种错误信息。如果源文件是二进制的文件,但是保存的源文件后缀却是.c,则gcc会当作这是.c文件,如果采用gcc不带参数,则gcc会很多错,因为它把这个文件当作源代码处理的。

注意:这里,源文件指的是gcc的输入文件,源代码指的是程序源代码文件。

以下是使用gcc 不带-E-S-c这些参数时,将会进行的处理与输入文件后缀(类型)的对应关系。

使用-save-temps可以保存编译各个阶段的临时文件。

<!-- [if !mso]> <mce:style><! v/:* {behavior:url(#default#VML);} o/:* {behavior:url(#default#VML);} p/:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} v/:textbox {display:none;} --><![endif]--><!-- [if !ppt]--><!-- [endif]-->

后缀 名

种类说明

源文件相应的后续处理

预处理

编译

汇编

链接

.c

C 语言 源 程序

.C/.cc/.cxx

C++ 语言 源程序

.h

源程序所包含的头文件

--

--

--

--

.i

经过预处理的 C 源程序

 

.ii

经过预处理的 C++ 源程序

 

.s

汇编语言源程序

  

.S

汇编语言源程序

 

.o

目标文件

   

.a

由目标文件构成的档案文件

   

<!-- [if !mso]> <mce:style><! v/:* {behavior:url(#default#VML);} o/:* {behavior:url(#default#VML);} p/:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} v/:textbox {display:none;} --><!-- [endif]--><!-- [if !ppt]--><!-- [endif]-->

二,GCC常用编译选项

格式为:

gcc [option | filename] .......

gcc的命令可以分为如下几类:

1,全局选项 -c-S-E -o

2,目录选项 -Ipath-Lpath

3,链接选项 -shared-llibrary -Wl option

4,警告选项 -Wall -Wextra-Wconversion-Wshardow-Wcast-qual

5,调试选项 -g ,-ggdb

6,优化选项 -O, -O0,-O1,-O2,-O3

7,其它选项 -fPIC

部分选项简介:

-Wl,option : 传递 option 给链接程序

-Wl,-Bstatic : 明确限定链接静态库 ( 链接程序将不再接受动态链接库,直到再次指定 -Bdynamic)

-Wl,-Bdynamic : 明确限定链接动态库

-fPIC : 生成动态链接用位置无关代码 (Position-independent code)

-shared : 生成动态链接目标文件

-L : 指定链接阶段链接库所在路径

-l : 指定要链接的库(原库名去除前缀 lib 和后缀 .a/.so 的剩余部分)

a)目录选项

目录选项是为编译器指定搜索头文件和库文件所在目录的,

编译时,头文件的搜索顺序为:

-Ipath指定--------->环境变量C_INCLUDE_PATH或者CPLUS_INCLUDE_PATH--------->/usr/local/include/usr/include

库文件搜索顺序:

-Lpath指定-------->环境变量LIBRARY_PATH----------->/usr/local/lib/usr/lib

<!-- [if !mso]> <mce:style><! v/:* {behavior:url(#default#VML);} o/:* {behavior:url(#default#VML);} p/:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} v/:textbox {display:none;} --><!-- [endif]--><!-- [if !ppt]--><!-- [endif]-->

可以利用搜索顺序使得当前目录下的程序编译时链接静态c++libstdc++.a

ln -s ` g++ -print-file-name = libstdc++.a` (注意是反引号,不是引号,意是运行反引号里的命令)

这样便建立了一个到g++使用的静态库libstdc++.a的符号链接。

g++ -o hello -L. hello.cpp 命令会使得g++搜索当前目,搜索到了libstdc++.a,因而采用静态链接。

使用ldd编译结果,可以看到没有c++动态链的依

#ldd hello

linux-gate.so.1 => (0x00a58000)

libm.so.6 => /lib/libm.so.6 (0x006d7000)

libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00858000)

libc.so.6 => /lib/libc.so.6 (0x00591000)

/lib/ld-linux.so.2 (0x00573000)

b)调试信息选项

-g [Format][LEVEL] : 设定生成的调试信息的格式和级别。

-g

编译器指示操作系统生成本地格式(如stabsCOFFXCOFFDRAWF-2

-ggdb

生成的调试信息且其中尽可能包含所有额外的GDB扩展

FORMAT: 指定调试信息的格式,如 stabs+, stabs, xcoff+, xcoff, or vms

LEVEL

0:不生成调试信息

1:最小调试信息,用于跟踪程序的部分内容:函数、外部变量,不能跟踪局部变量和行 号。

2:默认的debug信息生成级别。可跟踪局部变量和行号。但不包含宏。

3:包含额外的debug信息,包括宏的信息。

建议使用: 调试使用-ggdb,发布使用GNU package发布默认的-g

注意事项

因为GCC允许 –g 和 –O选项同时存在,在这种情况使用GDB调试会产生奇怪的结果

(如: 某 些变量不存在了,某些语句没有被执行,处理流程发生了变化等等),

在开发调试过程中尽量关闭 优化选项。

 

c选项

-Onn03的数,表示级别

 

方案

对目标文 件的影响

对编译过程 的影响

优化级别选用的方案

○: 使用; △: 部分使用; ×: 不使用)

执行 速度

代码 大小

编译 速度

内存 使用

-O0 或者默认 (default)

-O1 或者 - O

-O2

-O3

合并公共表达式(源代码级别优 化)

加快

减少

减慢

增加

×

函数内联(源代码级别优 化)

加快

增加

减慢

增加

×

循环展开

(空间换时间优 化)

加快

增加

减慢

增加

×

×

×

度优化

加快

不增 加

减慢

增加

×

×

推荐:调试使用-O0,发布使用与GNU package发布优化级别相同的-O2

 

d)警告选项

 

推荐使用:

-Wall -W -Wconversion -Wshadow -Wcast-qual

 

-Wall 开启多个常用的错误警告选项。它结合了很多可以单独使用的警告选项。

- Wformat (included in -Wall)

选项 -Wall 中包含了。选项对 printf scanf 些函数中的不正确的字符串 格式的使用提出警告,

这种情况下,指定的字符串格式与对应函数的参数的型不 匹配。

例如: printf(“my name is %s/n”, name, name);

<!-- .shape { }v:textbox { display: none; } -->

-Wimplicit (included in -Wall)

<!-- .shape { }v:textbox { display: none; } --> 这个选项在 -Wall 中包含了。这个选项对使用没有声明的任何函数进行警告。

常见的没有声明就引用的函数的典型原因是没有包含头文件

 

<!-- .shape { }v:textbox { display: none; } -->-Wreturn-type (included in -Wall)

<!-- .shape { }v:textbox { display: none; } -->

这个选项在 -Wall 中包含了。这个函数对没有返回值,但是没有声明返回值是 void 的函数提出警告。

<!-- .shape { }v:textbox { display: none; } -->

example : int func() { }

<!-- .shape { }v:textbox { display: none; } -->

-W or -Wextra

<!-- .shape { }v:textbox { display: none; } -->

启一些而外的 -Wall 没有包含的警告标识。例如在有符号数和无符号数之间进行比

证书 0 行除了! = 的比运算等。

<!-- .shape { }v:textbox { display: none; } -->example : void func( void * pointer ){ if (pointer <= 0 ) … }

 

-Wconversion <!-- .shape { }v:textbox { display: none; } -->

 

这个选项对可能引发不可预料的结果的隐式类型转换提出警告。

例如: unsigned int length = - 1 ;

 

<!-- .shape { }v:textbox { display: none; } -->

-Wshadow

 

这个选项对于某个范围内已经被声明的变量的重新声明提出警告。 <!-- .shape { }v:textbox { display: none; } -->

例如: { int xxx = 1 ; { int xxx= 2 ; … } … } <!-- .shape { }v:textbox { display: none; } -->

<!-- .shape { }v:textbox { display: none; } -->

-Wcast-qual

<!-- .shape { }v:textbox { display: none; } -->

选项对化的除一个型限定符的指提出警告,例如 const 型限定符。

<!-- .shape { }v:textbox { display: none; } -->

例如: void func( const char * xxx) { char * yyy = xxx ; … }

e)编译链接、创建库文件的过程:

使用源代码文件test.cmain.c作为说明例子,其中main.c用到了test.c中的函数:

test.c:

int max(int a,int b) {

return a>b?a:b;

}

main.c:

int main(){

printf("max(1,2)=%d/n",max(1,2));

return 0;

}

1,创建动态库 :

1gcc -fPIC -c -o test.o test.c

-fPIC表示产生位置无关代码(position independence code,

-c表示产生的是二进制文件,不进行链接,

-o表示产生的文件名。

2gcc -shared -o libtest.so test.o

使用1)中编译的二进制文件,产生动态库

2,使用动态库

gcc -o main mian.c -L. -ltest

使用链接的库文件在前目录,名字为test

3,创建静态库

1gcc -c -o test.o test.c

-c表示产生的是二进制文件,不进行链接,

-o表示产生的文件名。

2)ar rcs libtest.a test.o

使用1)的二进制文件,产生静态库(文档文件)

4,使用静态库

gcc -o main main.c -L. -ltest

使用链接的库文件在当前目录,名字为test

 

<!-- [if !mso]> <mce:style><! v/:* {behavior:url(#default#VML);} o/:* {behavior:url(#default#VML);} p/:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} v/:textbox {display:none;} -->

<!-- [endif]--><!-- [if !ppt]--><!-- [endif]-->

三,本文结束语

gcclinux平台下的强大的编译链接工具,希望本文对您有所帮助。

 

 

[转自]http://daimajishu.iteye.com/blog/1089740

 

原创粉丝点击