程序的编译过程

程序编译分为四个过程:

1.预编译--gcc -E xx.c -o xx.i(预处理器cpp对#做替换:头文件、宏,去掉注释,条件编译)

2.编译--gcc -S xx.i -o xx.s(编译器ccl对程序进行语法及词法分析)

3.汇编--gcc -c xx.s -o xx.o(汇编器as将汇编代码转换机器码  )

4.链接--gcc xx.o -o xx(链接器ld将.o文件链接到一起生成可执行程序)

.c .i .s 均为文本文件,.o为二进制文件

链接的时候需要链接到库,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。

库分为:静态库和动态库两种。

静态库的命名方式:libxx.a

动态库的命名方式:libxx.so

如果想把file1.c,file2.c...filen.c做成库文件,可以通过以下命令来实现:

静态库:

gcc -c file1.c -o file1.o

gcc -c file2.c -o file2.o

......

gcc -c filen.c -o filen.o

ar -rcs libname.a file1.o file2.o...filen.o  通过此命令生成的静态库名字为libname.a

在链接库的时候需要加上 -l(小写的L)来指明需要链接的库的名字,比如:-lname,同时如果不是在系统库路径的库(即你自己写的静态库),则需要通过-L来指明库的路径,此路径最后为绝对路径。以下动态库同理。

使用静态库:gcc test.c -o test -L/.../  -lname

静态库优点:

1.发布程序的时候不需要提供对应的库(动态库需要);

2.加载库的速度快(库函数就在代码区)。

缺点:库被打包到代码中,增加了代码的体积;

2.库一旦发生了改变,需要对整个程序进行重新编译。

动态库:

gcc -shared -fPIC name.c -o libname.so  file1.c file2.c......filen.c  

通过此命令生成的动态库名字为libname.so

使用动态库:gcc test.c -o test -L/.../  -lname

如果当我们运行此可执行文件./test的时候报错:No such file or directory,可以考虑因为运行的可执行文件时操作系统默认到/bin、/usr/bin下去找,如果你的可执行文件不在这些路径下,系统就会找不到,此时需要通过设置环境变量来解决这一问题:

首先找到你要运行的可执行文件的位置,然后pwd得到绝对路径,然后export LD_LIBRARY_PATH=/../(刚刚得到的绝对路径),此时再运行./test就能成功了。此设置为临时设置,下一次运行还需要再设置。

动态库优点

1、执行程序体积小

2、动态库更新了,不需要重新编译程序

 缺点:

1、发布程序的时候,需要将动态库提供给用户

2、动态库没有被打包到应用程序中,加载速度相对较慢(动态库在打包可执行程序的时候不会将动态库打包到可执行程序中,只会做一个标记,也就是需要调用哪些函数,在执行的时候需要先加载动态库,然后在调用动态库里面的函数然后执行相应的操作。)

区别:静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。

           动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。

当静态库和动态库同时存在时, gcc命令将优先使用动态库。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值