gcc常用参数(静动态链接优化调试)_第1页
gcc常用参数(静动态链接优化调试)_第2页
gcc常用参数(静动态链接优化调试)_第3页
gcc常用参数(静动态链接优化调试)_第4页
gcc常用参数(静动态链接优化调试)_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

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

文档简介

1、一、编译过程概览gcc编译器对程序的编译过程有四个阶段:预处理(preprocessing)编译(com-pilation proper)> 汇编(assembly和链接(linking)。预处理:对源文件(source file)进行预处理,进行宏定义的替换等。编译:将进行完预处理的源文件编译成汇编文件(assembly file)。将C源代码编译成汇编语言。汇编:将汇编文件汇编成目标文件(object file)。链接:将一个或多个目标文件链接成一个可执行的二进制文件(execute file)。链接的目标文件中有且只有一个 main函数,作为可执行文件的开始。-E在预处理阶段之后停

2、止,不进行编译。输出是预处理之后的源码,默认发送 到标准输出(standard output。输入文件格式为.c等,默认输出为标准输出。-S在编译阶段之后停止,不进行汇编。输出为每一个指定的未编译的输入文件 的汇编代码文件。输入文件格式为.c、.i等,输出文件格式为.s。-c编译或者汇编源文件,不进行链接。输出为每一个源文件的目标文件。输入文件格式为.c、.i、.s,输出文件格式为.0。-o file name-o指定输出文件的文件名,如果没有指定-o,则默认输出的可执行文件名是a.out,默认输出的source.suffix的汇编文件名为source.s目标文件名位 source. 默认的预

3、处理后的源文件输出到标准输出。main .c/*Study for using gcc*/Iinclude <stdia hA#include <stdlib.h>#define TESTD 2int main(int argcr char *argv)#lfdef _MYDEBUG_ prlntf fan*);#elseprintf("bn"); #endifreturn EXITSUCCESS;gcc -E main.c -o main.itali main.iwy白wyaibyn-desktop:'/learnning$ gee -E mai

4、n.c -o main.i wyaibynwyaibyn-desktop/learnning$ tail main i# 3 llmainTCM 2int main(int argc, char *airgv)printf(hbnH);return 0;wyaibynwyaibyn-desktop:*/learnning$ |gcc-S main.i -o main.s tail main.swyaibyn(9wyaibyn-desktop:'/learnnings gcc *S main,c -0 main,s wyaibyntyaibyn-desktop:-/learnnings

5、tail mainandl$-16r %e$psubl$16, %espmovl$4LC9r (esp)callputsmo讥$0, %eaxleaveret.size main, .-main,ident "GCC: (Ubuntu 4.4.3*4ubuntu5) 4,4.3" section.note.GNU-stack,"Mfprogbitsps: gcc -S main.c main.s也是可以的。gcc -c main.s -o main.o gcc main.o-o test ./testwyaibynyaibyn-desktop:-/learnnin

6、gs gcc -c main£ -0 main.o wyaibynwyaibyn-desktop:-/learnning$ gcc main.o -o test wyaibynwyaibyn-desktop:-/learnningS ./testbps: gcc -c main.i(main.c) main.ogcc ma in .c(ma in.i mai n.s) -o test 者 E是可以的二、预处理 预处理阶段可以用到的一些选项。-C 保留文件头注释。-D n ame-D n ame=defi niti on预定义宏(源文件中不能定义该宏),-D name宏定义的值为1-U

7、 n ame取消宏定义nameo按照他们在命令行自左至右的顺序执行-U和-D。-un def不预定义任何系统指定和GCC指定的宏,标准的宏仍然预定义。-I directory设置头文件(.h)的搜索路径。可以多次使用-I包含多个搜索路径。在搜索 头文件的时候,先搜索-I指定的路径,再搜索系统头文件路径。-M-MM查看依赖文件。按照make的描述规则输出源文件的依赖,目标文件:所有 被包含的文件名。如果在编译时使用到了 -I dir,这里也需要指定对应的dir。-MM 忽略标准库的依赖。gcc -D _MYDEBUG_ -E main.c -o main.i tali main.iwyaibyn

8、(awyaibyn-desktop:/learnning$ gcc -D MYDEBUG -E main.c -o main.i wyaibynwyaibyn-desktop/learnning$ tail mainiint mainfint ags char *argv)printf("an");retun S;gcc -MM main.cwyaibynwyajbyn-desktop:*/learnning$ gcc -MM main matrro: main-c三、链接1. 静态库和动态库库只不过是目标文件的一个集合(一个容器)。如果一些目标文件针对某个 给定的问题有相

9、互关联的行为,那么久可以把这些目标文件整合到一个库当中, 从而简化应用程序开发人员对这些目标文件的存取和分发。静态库(archive file,归档文件)由ar或者archive工具创建。在开发人员 编译并与库链接后,库中被需要的部分就会被整合到可执行映像中。 从应用程序 的角度看,应用程序映像已经包含了库中自己所需要的部分, 因此它与外部的库 不再有关联。共享库(share file)或动态库也是与应用程序映像链接在一起,但是这种链 接分两个阶段完成。第一阶段(应用程序生成阶段),链接器会检查确认应用程 序生成所需要的全部符号(函数或变量)在应用程序或库中可用。但是库中相应 的部分并不被整合

10、到应用程序的映像中(静态库就是这样直接整合的),而是在第二阶段(运行阶段)由动态加载器将所有需要的共享库中的那部分加载入内存, 与应用程序映像动态地链接在一起。 这样可以形成更小的映像文件,因为共享库与应用程序映像是独立的。使用共享库节省内存的代价是库必须在运行时解析。 明确库中那些部分是需要的,找到这些部分,然后将它载入内存这个过程需要点时间。应用程 序A应用程 序B静态库静态库I应用程I I应目程II 序A| 序B |p/2. 链接阶段可以用到的一些选项-l library在链接的时候搜索名字为library的库。搜索的目录是标准系统目录加上-L 指定的目录。真正搜索的库的文件名为libl

11、ibrary.a或者liblibrary.so (即在库名前 加lib,后面添加后缀.a或者.so)。.a为静态库,.so为动态库。若两个库同时存 在,默认链接动态链接库。-L directory为-l添加搜索的目录。-static在支持动态链接的系统上,阻止一切动态链接。3. 静态库和动态库的创建(1)动态库的创建-fPIC为了创建动态链接库,源文件的编译要有些不同,在编译的时候添加-fPIC参数。-shared用添加了 -fPIC参数编译后的目标文件(一个或者几个)创建一个动态库。静态库的创建静态库就是多个目标文件的打包。创建静态库需要借助ar工具包将多个目标文件打包。ar -cru &l

12、t;archive> <object1> <object2>ar工具的重要选项选项名称示例-d删除ar <archive> <object>-r插入(替换)ar - <archive> <object>-t列表ar -<archive>-x提取ar <archive> <object>-c创建ar <archive>-ru更新目标ar -u <archive> <object>main.c严study for using gcc*/#includ

13、e <stdio4h> include <stdlib.h> include "libah" #include "libb.h"int main(int argc, char *argv) #ifdef _MYDEBUG_printf("ayn");#elseprintf(flbnu);#endiflibafuncf);libbfuncO;return EXIT SUCCESS; liba.h#ifndef MYLIBA H#define MYLIBA_H_| #elseint libafunc(); #end

14、ifliba.c妙include *liba.h"include <stdio.h>int libafuncf)( printf("I am a liba functionYn");return 0;|libb.h#ifndefMYILIBB H#definemylibbI h#else int libbfuncf);#endiflibb.c#include "libb.h*include <stdio h>int libbfuncf)(printf ("I am a libb functionn1F);return 0

15、;4举例生成静态库libmylib.a。gcc -c liba.cgcc -c libb.car -cru -o libmylib.a liba.o libb.owyaibyn(awyaibyn-desktop: /lea rnnings rm libmylib. so wyaibyrKawyaibyn-desktop:-/learnnings gcc -c liba wyaibyrxawyaibyn-desktop:'/learnnings gcc -c libb.c wyaibynwyaibyn-desktop:-/learnning$ ar *cru *o libmylib.a

16、liba.o libb.o wyaibyrn?wyaibyn-desktop:/learnningS Islibm.c liba.h libo.o libblibb*h libb”o libmylib.a main链接静态链接库,对于静态链接库来说,只要在链接的时候找到静态链接库 即可。因为在链接时已经将映像包含在可执行程序之中。 程序在运行的时候与静 态链接库没有任何关系。链接时用-I指明要搜索的静态链接库。丄添加搜索路径,若不添加仅搜索系 统路径,/lib /usr/lib 等gcc -o artest main.c -mylib -L. ./artestwyaibyn(?wyaibyn-

17、desktop: -/learnnings ./artest bI am a liba functionI am a libb function使用静态链接库的绝对路径进行链接。gcc -o artest main.c ./libmylib.a./artestwyaibyn(3wyaibyn-desktop:-/learnningS gcc -o artest m白irrc ./libmylib.a wyaibynwyaibyn-desktop:/learnnings ,/artest bI am a liba furctionI am a libb function生成动态库libmylib

18、.sogcc liba.c -PICgcc libb.c -PICgcc -shared -o libmylib.so liba.o libb.owyaibynwyaibyn-desktop:'/learnnirigs gcc -c liba.c -fPIC wyalbynwyai byn-des ktop:-/lea rnningl gcc libb.c -fPIC wyaibynwyaibyn-desktop:-/learnningS gcc -shared -o libmylib.so liba.o libb.o wyaibynwyaibyn-desktop:-/learnnin

19、gs Is artest liba-h kibb.c libb.o libmylib £<> lib占lib占.d libb.h libmylib.寻 皿占in.t链接动态链接库,对于动态链接库来说,不仅在链接的时候能够找到动态链 接库,在运行的时候也要找到静态链接库。动态链接库在链接时的操作与静态链接库相同。这里注意一点,若对于mylib库同时存在动态库libmylib.so和静态库 libmylib.a,用-l搜索时会优先链接动态库。gcc -o shtest main.c-mylib wyaibynwyaibyn-desktop:'/learnningj g

20、cc -o shtest mainx -1 mylib -L wyaibynwyaibyn-desktop:/learnningi Idd ./shtestlinux-gate.so.1 => (BxOBcf librnylibn so => not found libc.so.6 => /lib/tls/1686/CHOV/libc.so.6 (SxGSllQOSO /Ub/ld-Unux.so.2wyaibynfyaibyn-desktop:'/learnningt /slitest./shtest: error while loading shared libr

21、aries: libmylib.so: cannot open shared object file: no such file or directory./路径下存在libmylib.a和libmylib.so,但是优先链接libmylib.so。通过ldd 可以查看shtest使用的动态链接库。libmylib.so=>not found,意思是shtest使用了 动态链接库libmylib.so,但是没找到。因为对于动态链接库,不仅要在编译的时 候找到,在运行的时候也需要找到。这个与路径有关,下面我们会提到。应用程序独享的动态链接库。有很多共享库只被特定的应用程序使用,那么就没有必

22、要加入系统库路径,以免应用程序的共享库之间发生版本冲突。因此Linux还可以通过设置环境变量LD_LIBRARY_PATH 来临时指定应用程序的共享库搜索路径。export LD_LIBRARY_PATH=./ldd shtest./shtestwyaibynwyaibyn-desktop:*/learnningiS export LD LIBRARY PATH=./ wyaibyngwyaibyn-desktop:-/learnning$ ldd shtest linux-gate,so.1 =>(9xO9c28060libmylib.so => ./libmylib.so (0

23、x00b380Q0)libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xQ0ce9069) /lib/ld-limix.so.2 6x00751000)wyaibynwyaibyn-desktopr'/learnningS /shtest bI am a liba functionI am a libb function也可以将动态链接库最为系统共享的动态链接库。 方法一,可以将动态链接 库放入系统库的目录下;方法二,将动态链接库放入一个自定义的目录下, 然后 通过修改配置文件/etc/ld.so.conf,将该目录添加到Linux系统指定搜索路径中。sudo cp libmylib.so /usr/lib Idd shtest./shtestwyaibynOwyaibyn-desktop:*/learnning$ sudo cp libmylib.so /usr/lib wyaibynwyaibyn- desktop:'/learnningS Idd shtestlinux-gate.so.l =>(ex091f5000)libmylib.so => /usr/lib/libmylib.so (0x00fb4006) libc.so.6 =&

温馨提示

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

评论

0/150

提交评论