07makefile学习之习题1

07makefile学习之习题1

以下为相关makefile的学习文章
01makefile学习之GCC编译的四个阶段(带编译阶段、汇编阶段、-S,-c的区别)
02makefile学习之makefile的基本原则
03makefile学习之makefile的一个规则
04makefile学习之多个规则处理多个文件
05makefile学习之两个函数和一个特殊规则clean
06makefile学习之三个自动变量(@ , @,@,^,$<)和模式规则
07makefile学习之习题1
08makefile学习之习题2

1 习题1
环境:假设在当前目录day01有一个用于存放.c文件的目录src;一个用于存放.h文件的目录inc;有一个用于存放.o文件的目录obj。
要求:在当前目录day01编写makefile,用于编译inc,src内的文件,并将编译过程中生成的.o目标文件放在obj中。可执行程序放在当前目录。

解析:
这题非常简单,环境是模拟我们平时项目的实战环境,文件已经放置好,只需我们编写makefile即可。经过之前makefile的学习,我们只需要将中间生成的.o文件路径修改一下即可。
环境准备:
将hello.c的头文件全部拷贝至head.h。命令如下:

//1 进入src打开hello.c文件
vim hello.c
//2 用:vsp head.h多窗口编辑创建新文件,拷贝过去并且添加头文件唯一标识宏
:vsp head.h
//3 将head.h剪切至../inc
mv ./head.h ../inc/

这样我们就将上一次学习的环境准备好。

答案如下(用之前学习的例子举例)
之前的答案:

src = $(wildcard ./*.c)
obj = $(patsubst %.c,%.o,$(src)) #param bewteen is ","

debug = -Wall -g

ALL:hello

hello:$(obj)
	gcc $(obj) -o $@
$(obj):%.o:%.c
	gcc -c $< -o $@ $(debug)

clean:
	-rm -rf $(obj)

本习题答案:

src = $(wildcard ./src/*.c)  #src=./src/add.c ...
obj = $(patsubst ./src/%.c, ./obj/%.o ,$(src)) #%=add,obj=./obj/add

incl = ./inc  #编译所需要的头文件

debug = -Wall -g

ALL:hello

hello:$(obj)
	gcc $(obj) -o $@
$(obj):./obj/%.o:./src/%.c        #
	gcc -c $< -o $@ $(debug) -I $(incl) #只需要在编译加头文件,上面的链接不需要

clean:
	-rm -rf $(obj)

.PHONY:clean ALL    # 防止执行make clean当前目录有clean文件名而不能成功删除

结果为:
在这里插入图片描述
需要注意的一点是,hello.c中若不正确添加以下头文件的话,会出现隐式声明的警告。

#include"../inc/head.h"

2 对上面答案进行解释
1)由于我们要索引./src/目录下的所有.c文件,所以此时src的值为:

src=./src/hello.c,./src/add.c,./src/sub.c,./src/mul.c 

2)此时第二行obj的产生1和2才是比较难的点。若我们仍按照上一次匹配的话,那么经过patsubst函数转换后:

对比:%.c,%.o
取src的第一个值举例;
src=./src/hello.c,那么此时%就是为:./src/hello
这样的话obj返回的值就为./src/hello.o,结果与我们题目要求的放置目标文件的路径./obj/不符合。

所以我们就需要让%号匹配的字符仅仅为函数名即可,具体路径我们可以自己配。
例如:

取src的第一个值举例;
src=./src/hello.c
若想使%匹配函数名,那么参数1就应该为./src/%.c=./src/hello.c
拿到函数名后,剩下就比较简单了,在函数名前补充我们想要放置的路径即可。所以参数2为:
./obj/%.o,填上名字后就是./obj/hello.o
其它文件也是同理。

3)正确拿到src和obj的返回路径后,就仍需要往下检查我们的makefile命令。先检查第一组,发现是不需要改的;然后第二组是模式规则,发现是需要修改的,因为不修改的话,%=函数名,而没有具体路径,所以它是无法找到对应文件的。例如当%=hello时,$(obj):hello.o:hello.c,当前目录是没有hello.o和hello.c,而是放在了obj和src中。所以必须修改。接着是第三组特殊的删除规则,不需要修改。

4)添加对应的头文件变量选项,只需要在编译时添加该选项即可。

5)每一次写makefile,在写完src和obj的变量后,都必须检查一遍每组规则的目标和依赖是否正确,养好良好的习惯。并且在使用makefile时注意加-n选项模拟删除。防止项目文件被删除。

3 这里额外的讲一下关于makefile的两个参数选项:

//1)
-n:模拟命令,并不会真正执行。
例如make -n make clean -n//分别模拟make和make clean

//2)
-f:指定名字不为makefile的文件执行makefile的功能
例如你当前目录下编写了一个叫m1的makefile文件,注意:不是makefile名字的文件执行make时是不会被系统执行的。
当我们加上-f就可以让系统执行。
make -f m1

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值