首页 > 其他分享 >makefile的基本使用方法

makefile的基本使用方法

时间:2022-10-26 22:14:13浏览次数:52  
标签:基本 文件 make makefile 如下 规则 执行 方法

41P-makefile基础规则

makefile: 管理项目。

命名:makefile Makefile --- make 命令

1 个规则:

目标:依赖条件

(一个tab缩进)命令

1. 目标的时间必须晚于依赖条件的时间,否则,更新目标

2. 依赖条件如果不存在,找寻新的规则去产生依赖条件。

ALL:指定 makefile 的终极目标。

2 个函数:

src = $(wildcard ./*.c): 匹配当前工作目录下的所有.c 文件。将文件名组成列表,赋值给变量 src。 src = add.c sub.c div1.c

obj = $(patsubst %.c, %.o, $(src)): 将参数3中,包含参数1的部分,替换为参数2。 obj = add.o sub.o div1.o

clean: (没有依赖)

-rm -rf $(obj) a.out “-”:作用是,删除不存在文件时,不报错。顺序执行结束。

3 个自动变量:

$@: 在规则的命令中,表示规则中的目标。

$^: 在规则的命令中,表示所有依赖条件。

$<: 在规则的命令中,表示第一个依赖条件。如果将该变量应用在模式规则中,它可将依赖条件列表中的依赖依次取出,套用模式规则。

模式规则:

%.o:%.c

gcc -c $< -o %@

静态模式规则:

$(obj):%.o:%.c

gcc -c $< -o %@

伪目标:

.PHONY: clean ALL

参数:

-n:模拟执行make、make clean 命令。

-f:指定文件执行 make 命令。 xxxx.mk

下面来一步一步升级makefile

第一个版本的Makefile:

makefile的依赖是从上至下的,换句话说就是目标文件是第一句里的目标,如果不满足执行依赖,就会继续向下执行。如果满足了生成目标的依赖,就不会再继续向下执行了。

make会自动寻找规则里需要的材料文件,执行规则下面的行为生成规则中的目标。

执行make指令

运行hello,没有问题

42P-makefile的一个规则

修改hello.c如下:

此时要进行编译,则需要多文件联合编译:

gcc hello.c add.c sub.c div1.c -o a.out

对这个新的代码,写出下面的makefile

执行:

此时,修改add.c为下图

此时,再使用make,发现了问题

可以看到,只修改add.c,但是编译的时候,其他.c文件也重新编译了,这不太科学。

明明只改了一个,全部都重新编译了

于是将makefile改写如下:

执行make指令如下

执行程序输出如下:

此时修改sub为下图:

再次make

可以看到,只重新编译了修改过的sub.c和最终目标

执行程序:

makefile检测原理:

修改文件后,文件的修改时间发生变化,会出现目标文件的时间早于作为依赖材料的时间,出现这种情况的文件会重新编译。

修改sub.c后,sub.o的时间就早于sub.c ,a.out的时间也早于sub.o的时间了,于是重新编译这俩文件了。

关于makefile指定目标问题,先修改makefile如下:

只是将a.out放在了文件末尾

执行make,如下:

这是因为,makefile默认第一个目标文件为终极目标,生成就跑路,这时候可以用ALL来指定终极目标

指定目标的makefile

执行:

43P-午后回顾

44P-makefile两个函数和clean

src = $(wildcard *.c)

找到当前目录下所有后缀为.c的文件,赋值给src

obj = $(patsubset %.c,%.o, $(src))

把src变量里所有后缀为.c的文件替换成.o

用这两个函数修改makefile如下:

执行,make指令,如下所示:

每次要删除.o文件,很恶心,于是改写makefile如下:

加了clean部分

rm前面的-,代表出错依然执行。比如,待删除文件集合是5个,已经手动删除了1个,就只剩下4个,然而删除命令里面还是5个的集合,就会有删除不存在文件的问题,不加这-,就会报错,告诉你有一个文件找不到。加了-就不会因为这个报错。

执行make:

由于没有文件变动,a.out的时间戳晚于所有依赖文件,这里make就没干活

于是,执行时加新指令,先模拟执行clean部分:

可以看到模拟执行后,会删除哪些文件。

确定没有问题,执行

45P-makefile3个自动变量和模式规则

3个自动变量

$@ :在规则命令中,表示规则中的目标

$< :在规则命令中,表示规则中的第一个条件,如果将该变量用在模式规则中,它可以将依赖条件列表中的依赖依次取出,套用模式规则

$^ :在规则命令中,表示规则中的所有条件,组成一个列表,以空格隔开,如果这个列表中有重复项,则去重

用自动变量修改makefile,如下:

sub,add这些指令中使用$<和$^都能达到效果,但是为了模式规则,所以使用的$<

执行make,如下:

再来,上面这个makefile,可扩展性不行。比如,要添加一个乘法函数,就需要在makefile里面增加乘法函数的部分。不科学,所以,模式规则就来了

%.o:%.c

gcc -c $< -o $@

修改makefile,如下:

执行make,如下:

这时,增加一个mul函数,并添加mul.c文件如下:

mul.c如下:

直接执行make:

增加函数的时候,不用改makefile,只需要增加.c文件,改一下源码,就行。很强势。

继续优化makefile,使用静态模式规则,就是指定模式规则给谁用,这里指定模式规则给obj用,以后文件多了,文件集合会有很多个,就需要指定哪个文件集合用什么规则

$(obj):%.o:%.c

gcc -c $< -o $@

修改后makefile如下:

运行如下:

再来一个扩展

当前文件夹下有ALL文件或者clean文件时,会导致makefile瘫痪,如下所示,make clean没有工作

用伪目标来解决,添加一行 .PHONY: clean ALL

makefile如下所示:

再来执行make clean,就不会受到干扰了

还有一个扩展就是,编译时的参数,-g,-Wall这些,可以放在makefile里面

修改后makefile如下:

执行makefile,如下:

46P-习题和作业

源码add.c,sub.c这些在src目录下,.o文件要放在obj目录下,头文件head.h在inc目录下。如下所示:

首先,将hello.c中的头文件单独拿出来

如下:

修改makefile如下,主要是注意%的匹配理解,只匹配文件名,目录位置要手动添加

执行一波,如下:

可以说是非常强势了

调用clean删除文件,直接用就行

如果makefile的名字变化一下,比如,叫m6

用m6执行makefile, make -f m6

用m6执行clean make -f m6 clean

标签:基本,文件,make,makefile,如下,规则,执行,方法
From: https://www.cnblogs.com/cyberbase/p/16830271.html

相关文章

  • Linux基本操作
    01P-Linux命令基础习惯-Linux系统编程date显示系统当前时间cat/etc/shells 查看当前可使用的shellecho$SHELL 查看当前使用的shell主键盘快捷键:上 Ctrl-p 下 Ct......
  • Vim基本操作
    18P-vim的三种工作模式19P-vim基本操作-跳转和删字符i进入编辑模式,光标前插入字符a进入编辑模式,光标后插入字符o进入编辑模式,光标所在行的下一行插入I进入编辑模式,光标......
  • 通过类的公用方法操作类的私有成员
    #include<iostream>usingnamespacestd;classgoods{public: goods(){total=0;} voidget_toal(){ cout<<"当前货物总量total="<<total<<endl; }......
  • DFS(图的深搜)--判断图是否构成环以及对set利用迭代器插值插入set的方法
    题目描述以边关系表示客户间的转账行为,若客户1向2转账,就认为存在1指向2的边。假设从某个客户1出发,沿着其任意转账关系边查找,若最终均可以到达终止客户(不存在帐务转出的客户......
  • asp.net 页面跳转的方法
    1.Response.Redirect("http://www.hao123.com",false);目标页面和原页面可以在2个服务器上,可输入网址或相对路径。后面的bool值为是否停止执行当前页。跳转向新的页面,原......
  • Android开发页面重定向导致WebvView.canGoBack一直返回true的解决方法
    Android开发页面重定向导致WebvView.canGoBack一直返回true的解决方法原因:打开页面A的时候重定向到页面B,页面B回退的时候回退到页面A,但是接着又重定向到页面B,所以canGoB......
  • Java方法覆盖的语法规则
    一、定义方法覆盖是指,继承父类的子类,写出的方法对于其父类中某一个方法,名称相同,参数列表、名称相同,返回类型相同,而此时,以父类作申请类型,子类作申请空间时的构造函数时,子类......
  • 【Vue】动态方法调用
     JS的动态方法调用是通过eval函数实现但是在Vue中是通过组件的$options.methods实现,写这篇的随笔的原因是因为今天为了封装面包屑组件,花了一下午折腾这个动态方法调用......
  • Vue项目中,html高度无法撑开的解决方法
    在src目录中新建CSS目录,并在此目录下创建global.css文件,填写如下内容:  随后在main.js中引入该CSS文件。如下: ......
  • 软件测试基本概述
    软件质量概述1)软件质量:软件产品基本满足需求及隐式需求的程度。2)软件产品满足基本需求指其能满足软件开发时所规定需求的特性,其次是软件产品满足隐式需求的程度。3)......