Linux:项目自动化构建工具make/Makefile

  • 概念
    Makefile:是一个普通的文本文件,有一点不普通,这个文件记录的是一个项目的所有构建规则
    make:是一个解释程序,在执行make命令时,会到当前目录下寻找Makefile文件,然后对Makefile中记录的构建规则进行逐行解释执行,最终完成整个项目。
  • Makefile编写规则
    例如:含有main.c文件,执行vim Makefile,编写以下
main:main.c
        gcc main.c -o main

然后make,可得

[Daisy@localhost ~]$ make
gcc main.c -o main

其中main就是要生成的目标对象,main.c就是依赖对象,然后一定要有tab键,然后再输入目标对象所指向的命令,即Makefile编写规则就是:
目标对象:依赖对象
[tab键]为了生成目标对象所指向的命令

预定义变量:$ ^:所有的依赖对象;$ @:目标对象的内容;$ <:依赖对象的第一个
例如将Makefile改为:

main:child.c main.c
        gcc $^ -o $@ 

就会产生错误,因为并没有child.c这个文件,没有child.c这个依赖对象,因此报错
但是如果有很多个.c文件,如果要将所有的.c文件编写,会很麻烦,因此可以使用wildcard关键字,它的作用是获取所有以.c结尾的文件放到一个变量中:

src=$(wildcard ./*.c)#获取当前目录下所有以.c结尾的文件放到src变量中
main:$(src)
        gcc $^ -o $@ 
  • make解释执行规则
    从上往下找到第一个目标对象,生成后,则退出,例如:
    有main.c、child.c文件,vim Makefile,执行
main:main.o child.o
        gcc $^ -o $@
main.o:main.c
        gcc -c $^ -o $@
child.o:child.c
        gcc -c $^ -o $@ 

它的意思就是先要生成main,但是这时没有main.o和child.o对象,因此向下找到main.o和child.o对象,make得到

[Daisy@localhost ~]$ make
gcc -c main.c -o main.o
gcc -c child.c -o child.o
gcc main.o child.o -o main

分析:可以看出要生成目标对象main,要先找到main.o和child.o,因为要依赖两个.o文件生成main,两个.o都不存在,在下方找依赖对象.o文件的生成规则,先生成依赖对象,然后再来生成目标对象,
但是如果是这样的情况,重新vim Makefile

child.o:child.c
        gcc -c $^ -o $@ 
main.o:main.c
        gcc -c $^ -o $@
main:main.o child.o
        gcc $^ -o $@

就只是生成了child.o之后就结束,结果是:

gcc -c child.c -o child.o

分析:从上往下找到第一个目标对象child.o,它有依赖对象child.c,所以生成child.o就直接退出了。
如果修改时间属性,例如touch main.c,出现:

gcc -c main.c -o main.o

结果是先生成了main.o文件,因为touch改变了时间属性,让main.c先作为目标对象生成main.o文件
%:通配符,因为上述vim Makefile写.o文件和.c文件很麻烦,所以可以使用通配符,例如

src=$(wildcard ./*.c)#获取当前目录下所有已.c结尾的文件名放到src变量中
obj=$(patsubst %.c,%.o,$(src))#main.o chile.o tmp.o
#patsubst关键字将src中的内容进行字符串替换,将.c替换为.o
main:$(obj)
        gcc $^ -o $@
%.o:%.c
        gcc -c $^ -o $@

这样就提高了效率,其中patsubst关键字作用就是将src中的内容进行字符串替换,在代码中的作用就是将.c文件替换成为.o文件,最终生成的结果是

[Daisy@localhost ~]$ make
cc    -c -o main.o main.c
cc    -c -o child.o child.c
gcc main.o child.o -o main

那么如果我们想要实现这样的命令(vim Makefile)

src=$(wildcard ./*.c)#获取当前目录下所有已.c结尾的文件名放到src变量中
obj=$(patsubst %.c,%.o,$(src))#main.o chile.o tmp.o
#patsubst关键字将src中的内容进行字符串替换,将.c替换为.o
main:$(obj)
        gcc $^ -o $@
#为了统配任意一个.o依赖对象的生成规则
%.o:%.c
        gcc -c $^ -o $@
clear:
        rm -f $(obj)

make之后并不能删除掉所有的.o文件,它的结果还是

[Daisy@localhost ~]$ make
gcc -c main.c -o main.o
gcc -c child.c -o child.o
gcc main.o child.o -o main

那么这时可以

[Daisy@localhost ~]$ make clear
rm -f ./main.o ./child.o

直接执行make clear命令即可,但是如果出现当前目录下有一个clear文件,make clear就会显示:

make: “clear”是最新的。

但是如果这时就要在vim Makefile中执行clear 命令,所以可以:

src=$(wildcard ./*.c)#获取当前目录下所有已.c结尾的文件名放到src变量中

obj=$(patsubst %.c,%.o,$(src))#main.o chile.o tmp.o
#patsubst关键字将src中的内容进行字符串替换,将.c替换为.o
main:$(obj)
        gcc $^ -o $@
%.o:%.c
        gcc -c $^ -o $@
.PHONY:clear
clear:
        rm -f $(obj)

加上.PHONY:clear命令,表示要执行clear命令,因为重新生成了clear,这时make clear得到:

[Daisy@localhost ~]$ make clear
rm -f ./main.o ./child.o

就执行了Makefile中的clear命令,不影响目录下的clear文件,ls发现没有影响

[Daisy@localhost ~]$ ls
child.c  clear  file.txt  main  main.c  Makefile  公共  模板  视频  图片  文档  下载  音乐  桌面

所以就有了伪对象的概念:不管目标对象是否最新,每次都需要重新生成
声明伪对象:.PHONY:target_name(要执行的命令名称)表示这个对象不管是不是最新的,都要重新生成它。
提示:在用vim编写代码之前,最好先将Makefile构建规则写好,以防在编译代码时出错,容易使代码丢失。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值