Linux系统编程:Makefile

一、什么是Makefile

  • 一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,Makefile 文件定义了一系列的规则来指定那些文件需要先编译,那些文件需要后编译,那些文件需要重新编译,甚至于进行更复杂的功能操作,因为 Makefile 文件就像一个 shell 脚本一样,也可以执行操作系统命令。
  • Makefile 带来的好处就是“自动化编译”,一旦写好,只需要一个 make 命令,整个工程完全自动编译,极大的提高软件开发效率。make 是一个命令工具,是一个解释 Makefile 文件中指令的命令工具,一般来说,大多数的 IDE 都有这个命令,比如 Delphi 的 make,Visual C++ 的 nmake,Linux 下 GUN 的 make

二、Makefile文件命名、规则和示例

1、文件命名

makefile 或者 Makefile

2、Makefile 规则

a. 一个 Makefile 文件中可以有一个或者多个规则
  目标 … : 依赖 …
    命令(shell命令)
    …

  目标:最终要生成的文件(伪目标除外)
  依赖:生成目标所需要的文件或是目标
  命令:通过执行命令对依赖操作生成目标(命令前必须Tab缩进)
b. Makefile 中的其他规则一般都是为第一条规则服务的。

3、示例

实验代码
a、建立并打开 Makefile 文件

nowcode@nowcode:~/test03$ vim Makefile

b、向 Makefile 文件加入一下命令

app:add.c  div.c  head.h  main.c  mult.c  sub.c
        gcc add.c  div.c  head.h  main.c  mult.c  sub.c -o app

c、使用 make 命令自动编译

nowcode@nowcode:~/test03$ make
gcc add.c  div.c  head.h  main.c  mult.c  sub.c -o app
nowcode@nowcode:~/test03$ ls
add.c  app  div.c  head.h  main.c  Makefile  mult.c  sub.c
nowcode@nowcode:~/test03$ ./app
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667

三、工作原理

  • 命令执行之前,需要先检查规则中的依赖是否存在
    • 如果存在,执行命令
    • 如果不存在,向下检查其他的规则,检查有没有一个规则是用来生成这个依赖的,如果找到了,则执行该规则中的命令
  • 检测更新,在执行规则中的命令时,会比较目标和依赖文件的时间
    • 如果依赖的时间比目标的时间晚,需要新生成目标
    • 如果依赖的时间比目标的时间早,目标不需要更新,对应规则的命令不需要被执行
  • 前面的示例 Makefile 文件可以这样写
app:add.o div.o mult.o sub.o main.o
	gcc add.o div.o mult.o sub.o main.o -o app
add.o:add.c
	gcc -c add.c -o add.o
div.o:div.c
	gcc -c div.c -o div.o
mult.o:mult.c
	gcc -c mult.c -o mult.o
sub.o:sub.c
	gcc -c sub.c -o sub.o
main.o:main.c
	gcc -c main.c -o main.o

四、变量

1、自定义变量

变量名=变量值  var=hello

2、预定义变量

AR : 归档维护程序的名称,默认值为 ar
CC : C编译器的名称,默认值为 gcc
CXX : C++编译器的名称,默认值为 g++
$@ : 目标的完整名称
$< : 第一个依赖文件的名称
$^ : 所有的依赖文件

3、获取变量的值

$(变量)  $(var)

注意:自动变量只能在规则的命令中使用

app:add.o div.o main.o mult.o sub.o
	gcc add.o div.o main.o mult.o sub.o -o app

以上的语句可以用以下语句替换

app:add.o div.o mult.o sub.o main.o
	$(CC)  $^ -o $@

五、模式匹配

%.o:%.c
  % : 通配符,匹配一个字符串
  两个%匹配的是同一个字符串

add.o:add.c
        gcc -c add.c -o add.o
div.o:div.c
        gcc -c div.c -o div.o
mult.o:mult.c
        gcc -c mult.c -o mult.o
sub.o:sub.c
        gcc -c sub.c -o sub.o
main.o:main.c
        gcc -c main.c -o main.o

以上的语句可以用以下语句替换

%.o:%.c
	gcc -c $< -o $@

六、函数

1、$(wildcard PATTERN…)
  • 功能:获取指定目录下指定类型的文件列表
  • 参数:PATTERN 指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔
  • 返回:得到的若干文件的文件列表,文件名之间使用空格间隔
  • 示例:
    $(wildcard *.c ./sub/*.c)
    返回值格式:a.c b.c c.c d.c e.c f.c
2、$(parsubst < pattern >, < replacement >, < text >)
  • 功能:查找 <text> 中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是符合模式 <pattern>,如果匹配的话,则以 <replacement> 替换。
  • <pattern> 可以包括通配符‘%’,表示任意长度的字符串。如果 <replacement> 中也包含‘%’,那么,<replacement> 中的这个‘%’将是 <pattern> 中的那个‘%’所代表的字符串。(可以用‘\’来转义,以’%‘来表示真实含义的‘%’字符串)
  • 返回:函数返回被替换过后的字符串
  • 示例:
    $(patsubst %.c, %.o, x.c bar.c)
    返回值格式:x.o bar.o

上面实验(第二的示例)可以用以下代码实现

# 获取所有的.c文件
src=$(wildcard ./*.c) # src的值为 add.c  div.c  head.h  main.c  mult.c  sub.c
# 将.c文件替换.o文件
objs=$(patsubst %.c, %.o, $(src)) # objs的值为 add.o div.o main.o mult.o sub.o
target=app

$(target):$(objs)
        $(CC) $^ -o $@
%.o:%.c
        $(CC) -c $< -o $@

七、删除.o文件

使用 make 命令自动编译后,文件夹中会多了 .o 文件

nowcode@nowcode:~/test03$ vim Makefile
nowcode@nowcode:~/test03$ make
cc -c mult.c -o mult.o
cc -c main.c -o main.o
cc -c add.c -o add.o
cc -c div.c -o div.o
cc -c sub.c -o sub.o
cc mult.o main.o add.o div.o sub.o -o app
nowcode@nowcode:~/test03$ ls
add.c  add.o  app  div.c  div.o  head.h  main.c  main.o  Makefile  mult.c  mult.o  sub.c  sub.o

Makefile 文件中加入下面语句

.PHONY:clean
clean:
	rm $(objs) -f

加入后执行以下命令就可以将所有 .o 文件删除

nowcode@nowcode:~/test03$ make
make: “app”已是最新。
nowcode@nowcode:~/test03$ make clean
rm  ./add.o  ./mult.o  ./main.o  ./div.o  ./sub.o  -f
nowcode@nowcode:~/test03$ ls
add.c  app  div.c  head.h  main.c  Makefile  mult.c  sub.c
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CodeKwang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值