linux下.o、.a、.so文件解析

来源:互联网 发布:java解压缩gz文件 编辑:程序博客网 时间:2024/05/01 11:28

linux下.o、.a、.so文件解析
首先,假设以下都使用有main.cpp、test.h、test.cpp 三个文件。
1.linux下文件的类型是不依赖于其后缀名的,但一般来讲:
.o,是目标文件,相当于windows中的.obj文件
.so 为共享库,是shared object,用于动态连接的,和dll差不多
.a为静态库,是好多个.o合在一起,用于静态连接
.la为libtool自动生成的一些共享库,vi编辑查看,主要记录了一些配置信息。可以用如下命令查看*.la文件的格式 $file *.la
*.la: ASCII English text
所以可以用vi来查看其内容。

2.创建.a库文件和.o库文件:
生成单个.o文件:g++ -c main.cpp ,生成结果:main.o
生成单个.a文件:ar -r main.a main.o,生成结果:main.a

3.动态链接库*.so的编译与使用
编译:g++ main.cpp test.cpp -fPIC -shared -o main.so
链接:已经生成了main.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test1.cpp。
将test1.cpp与动态库main.so链接生成执行文件test:
g++ test1.cpp -L. -ltest -o test
ldd test 测试是否动态连接,如果列出main.so,那么连接正常了.
[编译参数详解]
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号,调用程序根据符号表找对应的符合【即函数和变量】),不用该标志外部程序无法连接。相当于一个可执行文件
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的,所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
-L.:表示要连接的库在当前目录中 实际测试中并没有其效果,而需要复制so到/usr/lib
-ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称。
LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

4.静态链接库
创建一个静态函数库文件,或者往一个已经存在地静态函数库文件添加新的目标代码,可以用下面的命令:
ar rcs my_library.a file1.o file2.o
这个例子中是把目标代码file1.o和file2.o加入到my_library.a这个函数库文件中,如果my_library.a不存在则创建一个新的文件。

5.生成执行文件
单个以main为文件名的执行文件:g++ -g main.cpp -o main
将多个文件链接到一个文件:g++ main.o test.o -o main
[编译参数详解]
-x language filename
设定文件所使用的语言,使后缀名无效,对以后的多个有效.也就是根
据约定C语言的后缀名称是.c的,而C++的后缀名是.C或者.cpp,如果
你很个性,决定你的C代码文件的后缀名是.pig 哈哈,那你就要用这
个参数,这个参数对他后面的文件名都起作用,除非到了下一个参数
的使用。
可以使用的参数吗有下面的这些
`c', `objective-c', `c-header', `c++', `cpp-output',
`assembler', and `assembler-with-cpp'.
看到英文,应该可以理解的。
例子用法:
gcc -x c hello.pig

-x none filename
关掉上一个选项,也就是让gcc根据文件名后缀,自动识别文件类型
例子用法:
gcc -x c hello.pig -x none hello2.c

-c
只激活预处理,编译,和汇编,也就是他只把程序做成obj文件
例子用法:
gcc -c hello.c
他将生成.o的obj文件
-S
只激活预处理和编译,就是指把文件编译成为汇编代码。
-E
只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里
面.
例子用法:
gcc -E hello.c > pianoapan.txt
gcc -E hello.c | more
慢慢看吧,一个hello word 也要与处理成800行的代码
-o
指定生成对象名称
-pipe
使用管道代替编译中临时文件,在使用非gnu汇编工具的时候,可能有些问

gcc -pipe -o hello.exe hello.c
-ansi
关闭gnu c中与ansi c不兼容的特性,激活ansi c的专有特性(包括禁止一
些asm inline typeof关键字,以及UNIX,vax等预处理宏,
-fno-asm
此选项实现ansi选项的功能的一部分,它禁止将asm,inline和typeof用作
关键字。

-fno-strict-prototype
只对g++起作用,使用这个选项,g++将对不带参数的函数,都认为是没有显式
的对参数的个数和类型说明,而不是没有参数.
而gcc无论是否使用这个参数,都将对没有带参数的函数,认为城没有显式说
明的类型

-fthis-is-varialble
就是向传统c++看齐,可以使用this当一般变量使用.

-fcond-mismatch
允许条件表达式的第二和第三参数类型不匹配,表达式的值将为void类型

-funsigned-char
-fno-signed-char
-fsigned-char
-fno-unsigned-char
这四个参数是对char类型进行设置,决定将char类型设置成unsigned char(前
两个参数)或者 signed char(后两个参数)

-include file
包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以
用它设定,功能就相当于在代码中使用#include
例子用法:
gcc hello.c -include /root/pianopan.h

-imacros file
将file文件的宏,扩展到gcc/g++的输入文件,宏定义本身并不出现在输入文件


-Dmacro
相当于C语言中的#define macro

-Dmacro=defn
相当于C语言中的#define macro=defn

-Umacro
相当于C语言中的#undef macro
-undef
取消对任何非标准宏的定义

-Idir
在你是用#include"file"的时候,gcc/g++会先在当前目录查找你所制定的头
文件,如果没有找到,他回到缺省的头文件目录找,如果使用-I制定了目录,他
回先在你所制定的目录查找,然后再按常规的顺序去找.
对于#include,gcc/g++会到-I制定的目录查找,查找不到,然后将到系
统的缺省的头文件目录查找

-I-
就是取消前一个参数的功能,所以一般在-Idir之后使用

-idirafter dir
在-I的目录里面查找失败,讲到这个目录里面查找.

-iprefix prefix
-iwithprefix dir
一般一起使用,当-I的目录查找失败,会到prefix+dir下查找

-nostdinc
使编译器不再系统缺省的头文件目录里面找头文件,一般和-I联合使用,明确
限定头文件的位置

-nostdin C++
规定不在g++指定的标准路经中搜索,但仍在其他路径中搜索,.此选项在创建
libg++库使用

-C
在预处理的时候,不删除注释信息,一般和-E使用,有时候分析程序,用这个很
方便的

-M
生成文件关联的信息。包含目标文件所依赖的所有源代码
你可以用gcc -M hello.c来测试一下,很简单。

-MM
和上面的那个一样,但是它将忽略由#include造成的依赖关系。

-MD
和-M相同,但是输出将导入到.d的文件里面

-MMD
和-MM相同,但是输出将导入到.d的文件里面

-w 不生成任何警告信息。

-Wall 生成所有警告信息。
-Wa,option
此选项传递option给汇编程序;如果option中间有逗号,就将option分成多个选
项,然后传递给会汇编程序

-Wl.option
此选项传递option给连接程序;如果option中间有逗号,就将option分成多个选
项,然后传递给会连接程序.

-llibrary
制定编译的时候使用的库

-Ldir
制定编译的时候,搜索库的路径。比如你自己的库,可以用它制定目录,不然
编译器将只在标准库的目录找。这个dir就是目录的名称。

-O0
-O1
-O2
-O3
编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最
高 

-g
只是编译器,在编译的时候,产生调试信息。

-gstabs
此选项以stabs格式声称调试信息,但是不包括gdb调试信息.

-gstabs+
此选项以stabs格式声称调试信息,并且包含仅供gdb使用的额外调试信息.

-ggdb
此选项将尽可能的生成gdb的可以使用的调试信息.
-static
此选项将禁止使用动态库,所以,编译出来的东西,一般都很大,也不需要什么
动态连接库,就可以运行.
-share
生成共享目标文件。通常用在建立共享库时。
-traditional
试图让编译器支持传统的C语言特性
0 0