gcc/gdb/make/动/静态链接库介绍

        gcc是一个编译工具,我们平时写的c/c++代码要想变成可执行文件,必须要经过预处理、编译、汇编、连接等步骤。gcc工具就完成这些动作。

一gcc编译过程

在这里插入图片描述

二、gcc常用参数

1.编译过程常用参数

参数 解释
-c 只编译不连接,生成目标文件.o
-S 只编译不汇编,编译后停止
-E 只预处理
-g 包含调试信息的编译
-o file 指定输出文件。无论是预处理、编译、汇编、链接都可以使用.
-I[dir] 指定搜索头文件路径

        举例:

        将hello.c只做预处理为hello.i

在这里插入图片描述

        将预处理后的hello.i文件编译成hello.s汇编文件

在这里插入图片描述

        将hello.s汇编文件编译成hello.o的目标文件

在这里插入图片描述

        将hello.o文件编译成最后的可执行文件,并执行

在这里插入图片描述

2.库选项

        linux下静态链接库和动态链接库

        .a[libname.a] 静态库格式

        .so[libname.so] 动态库格式

参数 解释
-ststic 静态编译
-shared 1.生成动态库
2.进行动态编译
-L dir 库文件搜索中添加路径
-fPIC 生成使用相对位置无关的目标代码,然后通常用于使用gcc的=static选项从该PIC目标文件生成动态库文件

3.警告选项

参数 解释
-w 关闭所有警告
-Wall 发出gcc提供的所有有用的警告
-pedantic 发出ansi c的所有警告

4.优化选项

参数 解释
-o/-o1 编译器会试图减少目标码的大小和执行时间
-o2(常用) 多优化一些。除了设计空间和速度的交换的优化选项,执行几乎所有的选项
-o3 优化的更多
-o0 不优化

三、gdb调试工具

1.进入调试模式

        下面是事先写好的为了调试用的代码

在这里插入图片描述

        带调试信息的编译,进入调试模式。进入调试模式后命令行的开头变成(gdb)

在这里插入图片描述

2.断点

先使用list命令,查看源代码。看将断点打在哪里

在这里插入图片描述

①打断点

b(break) 函数名
b(break) 行号
b(break) 文件名:行号
b(break) 行号if条件

②查看断点

ib(info break)

③删除断点

d(delete) 短点号

在这里插入图片描述

在这里插入图片描述

3.运行

r (run) 运行到断点处会停下来
c (continue) 运行到断点处会停下来
q (quit) 退出gdb调试

在这里插入图片描述

4.单步调试

n(next) 运行到函数处直接跳过,而不进入函数体内
s(step) 进到函数体内
f(finsh) 跳出当前函数体

5.打印值/监控

 p (printf)  打印出当前变量的值wi   会弹出一个类似windows下的图像框,更方便的观察调试步骤

在这里插入图片描述

使用wi命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ON7aX6KZ-1625276433959)(\images\linux\21.png)]

四、make命令的介绍

        在linux中常常使用make命令来编译程序,特别是大程序。而make命令所执行的动作依赖Makefile

1.Makefile作用

        i.工程文件组织,编译成复杂的程序

        ii.安装及卸载我们的程序。

2.Makefile编写规则

        Makefile由若干条规则构成

        形式:

                targets(目标):prerequisites(依赖) …

                command(命令)

例如:

hello:main.c fun1.c fun.cgcc main.c fun1.c fun2.c -o hello
//这就是一个Makefile文件包含的一系列规则
//第二行是table键的缩进,不能以空格键缩进

在这里插入图片描述

来个稍微复杂的

在这里插入图片描述

在这里插入图片描述

3.Makefile变量

①用户自定义变量

        有点类似于c语言中的宏定义

        定义的变量引用$(变量名)

在这里插入图片描述

上面是原内容。我们定义一个myobject的变量,让它等于debug.o add.o mux.o下面再使用时用$(变量名)即可

在这里插入图片描述

        变量中有一些特殊的赋值操作:

        = :普通的赋值

        := :立即赋值

        ?= :判断赋值

        += :追加赋值

        立即赋值:立即把变量的当前值,赋值给别的变量

        判断赋值:判断被赋值的对象是否为空,如果是,执行赋值操作,如果不为空,不执行赋值操作

        追加赋值:拼接字符串的效果,把一个变量,添加到另一个变量的后面

②预定义变量

        相当于系统自带的变量

变量 解释
AR 库文件维护程序的名称,默认值为ar
AS 汇编程序的名称。默认值为as
CC c编译器的名称,默认值为cc
CXX c++编译器的名称,默认值为g++
ARFLAGS 库文件维护程序选项,无默认值
ASFLAGS 汇编程序选项,无默认值
CFLAGS c编译器选项
CxxFLAGS c++编译器选项

③自动变量及环境变量

变量 解释
$* 不包含扩展名的目标文件名称
$< 第一个依赖文件名称
$? 所有时间戳比目标文件晚的依赖文件
$@ 目标文件完整名称
$^ 所有不重复的依赖文件

4.make工作流程

      1、make会在当前目录下找名字叫“Makefile”或者“makeflie”的文件

        2、如果找到,它会找文件中的第一个目标文件(target)并把这个文件最为最终的目标文件  

        3、根据时间戳生成目标文件

        4、递归去寻找目标文件依赖文件,并且递归生成

5.Makefile管理命令

命令 解释
-C dir 读入指定目录下面的Makefile
-f file 读入当前目录下的file文件为Makefile
-i 忽略所有命令执行错误
-I dir 指定被包含的Makefile所在目录

五、静态库与动态库的制作

        前面已经介绍了在linux中动态库用libxx.a,静态库用libxx.so表示。

        静态库: 是在程序编译的时候会被链接到当前的程序当中

        动态库: 程序在运行过程中会被加载到程序当中

1、动态库的制作

①首先准备三个文件,这里以add.c、add.h、main.c为例

        这里只做简单的动态库的封装的演示,代码比较简单。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

封装的对象为:add.c 即功能实现的过程

②将add.c转换成xxx.o文件

gcc -c add.c -o add.o

转换后xx.o已经是二进制文件

③制作静态库ar cr指令

ar cr libadd.a add.o 
//libxx.o库文件已生成

静态库制作完成,下面是将静态库添加到工程中

④编译

gcc -static main.c -L./ -l add -o add
//第一个add为库文件的名字,第二个add为生成目标对象的名字

上述命令解释:

        -static:声明这是一个静态库

        -L:后面跟libxx.o库文件的路径(该命令的路径为当前目录)

        -l(小写L):后面跟库文件名

执行add的结果正确,使用的是静态库。

2、动态库的制作

①制作库的源码(这里还是以上述三个文件为例)

main.c、add.c、add.h

②将add.c转换成add.o

gcc -c add.c -o add.o

③制作动态库

gcc -shared -fpic add.o -o libadd.so
//动态库libadd.so生成

④编译

gcc main.c -L./ -l add -o main
//-L:后面跟库路径
//-l:后面跟动态库的名字

⑤运行

这里需要把我们制作的动态库文件libxx.so放到系统/usr/lib目录下。才能运行我们的代码。否则会报错找不到动态库文件。

参考学习视频

更多详细参考资料

提取码:g4hp

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注