linux 系统下gcc

linux c

gcc

gcc编译可以执行4步骤:预处理、编译、汇编、链接

预处理 gcc -E

hello.c----->hello.i

展开宏、头文件,替换条件编译,删除注释、空行、空白

编译 gcc -S

hello.i------>hello.s

检查语法规范

汇编 gcc -c

hello.s------>hello.o

将汇编指令翻译成机器指令

链接 (无参数)

hello.o----->a.out

数据段合并地址回填

-o不是链接阶段的参数是起名的

image-20230504153351783

  • 编译阶段消耗时间、和系统资源最多
常用参数
-v查看gcc版本号

-version

-I目录指定头文件

当头文件和源码不在一级目录下,就需要指定头文件的位置

hello.c包含hello.h,hello.h在inc目录下

-I放在编译的前面和后面都可以

gcc -I ./inc hello.c -o hello
静态库和动态库

库可以提高程序编写速度,提高效率

静态库

占内存,速度快

使用在对空间要求较低,对时间要求较高的核心程序中(操作系统启动例程)

image-20230504161748254

制作静态库
ar rcs libmylib.a(起名必须以.a结尾,lib开头) file1.o
  1. 将 .c 生成 .o 文件 gcc -c add.c -o add.o
  2. 使用ar工具制作你静态库 ar rcs lib库名.a add.o sub.o div1.o
  3. 编译到可执行文件中:gcc test.c lib库名.a -o a.out
共享库(动态库)

省内存,速度慢

对时间较低,对空间要求较高

image-20230504162327595

制作动态库
  1. 将 .c 生成 .o 文件,需要生成与位置无关的代码(-fPIC)gcc -c add.c -o -fPIC
  2. 使用gcc -shared 制作动态库 gcc -shared lib库名.so add.o sub.o div1.o
  3. 编译可执行程序时指定所使用的动态库. -l ,指定库名,-L,指定库路径 gcc test.c -o a.out -l mymath -L /lib
  4. 运行可执行程序./a.out,出错原因:

​ 链接器: 工作于链接阶段,工作时需要 -l 和 -L

​ 动态连接器: 工作于程序运行阶段,工作时需要提供动态库所在目录位置

image-20230504180108539

要 -l 和 -L

​ 动态连接器: 工作于程序运行阶段,工作时需要提供动态库所在目录位置

[外链图片转存中…(img-Nuy1sGcf-1683213588529)]

静态函数有位置,动态函数没有位置,动态函数的位置取决于@plt,@plt在动态库加载到内存的时候被填充,动态库的函数比自己定义的函数绑定地址的时间比晚,即plt是一个基地址,需要动态库加载到内存才能确定,而调用的函数是相对于动态库的一个偏移地址。而调用函数的绝对地址是plt的基地址加上偏移地址确定的

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

计算机小混子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值