牛客Linux高并发服务器开发学习第四天

Makefile

工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中。

Makefile文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为Makefile文件就像一个shell脚本一样,也可以执行操作系统的命令。

Makefile带来的好处就是"自动化编译",一旦写好只需要一个make命令,整个工程完全自动编译,提高了软件开发的效率。

Makefile文件命名和规则

文件命名

makefile 或者 Makefile

Makefile规则

  • 一个Makefile文件中可以有一个或者多个规则

目标 ...: 依赖 ...

命令 (Shell 命令)

...

目标:最重要生成的文件(伪目标除外)

依赖:生成目标所需要的文件或是目标

命令:通过执行命令对依赖操作生成目标(命令前必须Tab缩进)

  • Makefile中的其他规则一般都是为第一条规则服务的。

举例:

创建Makefile文件

通过make直接生成app文件

可以运行

Makefile工作原理

命令在执行之前,需要先检查规则中的依赖是否存在

  • 如果存在,执行命令
  • 如果不存在,向下检查其他的规则,检查有没有一个规则是用来生成整个依赖的,如果找到了,执行该规则中的命令

检测更新 ,在执行规则中的命令时,会比较目标和依赖文件的时间

如果依赖的时间比目标的时间晚,需要重新生成目标。

如果依赖的时间比目标的时间早,目标不需要更新,对应规则中的命令不需要被执行。

举例:

修改Makefile为以下,此时依赖在文件夹中不存在,因此向下检查其他规则生成依赖。

生成app以后,如果不修改.c文件,再进行make,会提示app已为最新,但如果此时修改.c文件,在main.c中加了个换行,再进行make,会先更新main.o,再重新生成app。

这种写法相对于上一种写法的好处在于,如果只有main.c更新了,那么make的时候,只重新编译make.c,但上一种写法会同时编译所有.c。效率优于上一种。

变量

自定义变量

变量名=变量值 var=hello

预定义变量

AR:归档维护程序的名称,默认值为ar

CC:C编译器的名称,默认值为cc

CXX:C++编译器的名称,默认值为g++

$@:目标的完整名称

$<:第一个依赖文件的名称

$^:所有的依赖文件

获取变量的值

$(变量名)

#自动变量只能在规则的命令中使用

app:main.c a.c b.c

(CC) -c ^ -o $@ 与gcc -c main.c a.c b.c -o app等价

在Makefile中定义变量,可以在规则的命令中简化语法

模式匹配

%:通配符,陪陪一个字符串

函数

$(wildcard PATTERN ...)

功能:获取指定目录下指定类型的文件列表

参数:PATTERN 指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔

返回:得到的若干个文件的文件列表,文件名之间使用空格间隔

示例:

$(wildcard *.c ./sub/*.c)

返回值格式: a.c b.c c.c d.c e.c f.c

$(patsubst <pattern>,<replacement>,<text>)

功能:查找<text>中的单词(单词以"空格"、"Tab"或"回车""换行"分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。

<pattern>可以包括通配符"%",表示任意长度的字串。如果<replacement>中也包含"%",那么,<replacement>中的这个"%"将是<pattern>中的那个"%"所代表的字串。(可以用"\"来转义,以"\%"来表示真正含义的"%"字符)

返回:函数返回被替换过后的字符串

示例:

$(patsubst %.c, %.o, x.c bar.c)

返回值格式:x.o bar.o

make默认只执行第一条命令 clean这条命令可以通过

make clean执行

GDB调试

  1. GDB 是由 GNU 软件系统社区提供的调试工具,同 GCC 配套组成了一套完整的开发环境,GDB 是Linux 和许多类 Unix 系统中的标准开发环境。

通常,在为调试而编译时,我们会()关掉编译器的优化选项( -o ), 并打开调试选项( -g )。另外, -Wall 在尽量不影响程序行为的情况下选项打开所有 warning,也可以发现许多问题,避免一些不必要的 BUG。

gcc -g -Wall program.c -o program

-g 选项的作用是在可执行文件中加入源代码的信息,比如可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证 gdb 能找到源文件。

GDB命令

启动和退出

gdb 可执行程序

quit

给程序设置参数/获取设置参数

set args 10 20

show args

GDB使用帮助

help

查看当前文件代码

list/l (从默认位置显示)

list/l 行号 (从指定的行显示)

list/l 函数名 (从指定的函数显示)

查看非当前文件代码

list/l 文件名:行号

list/l 文件名:函数名

设置现实的行数

show list/listsize

set list/listsize 行数

如果直接用gcc test.c -o test

没有使用-g选项,文件中不会包含源代码的信息,导致gdb test, list时,没有符号被读取。

gcc -g -Wall program.c -o program

断点操作

设置断点

b/break 行号

b/break 函数名

b/break 文件名:行号

b/break 文件名:函数

查看断点

i/info b/break

删除断点

d/del/delete 断点编号

设置断点无效

dis/disable 断点编号

设置断点生效

ena/enable 断点编号

设置条件断点(一般用在循环的位置)

b/break 10 if i==5

调试命令

运行gdb程序

start(程序停在第一行)

run(遇见断点才停)

继续运行,到下一个断点停

c/continue

向下执行一行代码(不会进入函数体)

n/next

变量操作

p/print 变量名 (打印变量值)

ptype 变量名 (打印变量类型)

向下单步调试(遇到函数进入函数体)

s/step

finish(跳出函数体)

自动变量操作

display num(自动打印指定变量的值)

i/info display

undisplay 编号

其他操作

set var 变量名=变量值

until(跳出循环)

学习进度

Linux系统编程入门 04:17:14

相关推荐
米小葱8 分钟前
【学习笔记】cmake
笔记·学习
zyl8372115 分钟前
Docker 使用手册
运维·docker·容器
古月方枘Fry35 分钟前
MGRE实验
运维·服务器
叠叠乐1 小时前
redmi k90 pro max 强解BL,刷海外rom, 并刷入sukisu ultra
linux
stolentime1 小时前
FreeDomain 本地开发环境快速搭建指南
运维·服务器·网络
辰海Coding1 小时前
MiniSpring框架学习-分解 Dispatcher
java·学习·spring·架构
初夏睡觉1 小时前
数据结构学习之~二叉堆 (P3378 【模版】堆)
数据结构·c++·学习
xiaoye-duck2 小时前
《Linux系统编程》Linux 进程间通信之管道基础解析:从匿名管道原理到基于管道的进程池实现
linux
z200509302 小时前
【Linux学习】Linux中的进程程序替换
linux·服务器·学习