makefile单目录编写和多目录编写

makefile

makefile的好处:自动化编译,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高软件的开发效率。

makefile的规则

make clean命令,可以删除makefile生成的各种文件。

#新建一个makefile文件
touch makefile
#编写makefile文件
vim makefile
#makefile文件编写规则
target1,target2....:depend1,depend2....
	command
	......
	......
	......
#例子1
app:a.c,b.c,c.c
	gcc a.c b.c c.c -o app
#例子2	
app,app1:a.c,b.c,c.c,d.c
	gcc a.c b.c -o app
	gcc c.c,d.c -o app1
#例子3
app:a.o,b.o,c.0
	gcc a.o b.o c.o -o app
a.o:a.c
	gcc a.c -c
b.o:b.c
	gcc b.c -c
c.o:c.c
	gcc c.c -c

makefile的工作原理

使用make命令,搜索当前目录中的emakefile文件,执行makefile里面的命令

#makefile只想执行某一部分的时候,规则为
make [target]

makefile变量

#makefile变量有三种,用户自定义、预定义、自动变量。
#自定义变量
变量名=变量值
#取出变量值
$(变量名)
#eg:
obj=main.c tools.c
target=calc
$(target):$(obj)
	gcc $(obj) -o $(target)

自动变量

自动变量用来代表这些规则中的目标文件和依赖文件,并且他们只能够在规则中使用

$< #表示依赖项中的第一个依赖文件的名称
$@ #表示目标文件的名称,包含文件扩展名
$^ #依赖项中所有不重复的依赖文件,这些文件以空格分开

app:a.c,b.c,c.c
	gcc a.c b.c c.c -o app
	
app:a.c,b.c,c.c
	gcc $^ -o $@  #自动变量只能在规则中使用。

模式匹配

#例子3
app:a.o,b.o,c.0
	gcc a.o b.o c.o -o app
a.o:a.c
	gcc a.c -c
b.o:b.c
	gcc b.c -c
c.o:c.c
	gcc c.c -c
#上面的makefile文件显示很冗余
#使用模式模板
app:a.o,b.o,c.0
	gcc a.o b.o c.o -o app
%.o:%.c
	gcc $< -c

makefile中的函数

#在makefile中所有的函数都是有返回值的,格式$(函数名 参数1,参数2,参数3......)
#wildcard函数  获取指定目录下指定类型的文件名,其返回值是以空格来分割的,指定目录下的所有符合条件的文件名列表。
src=$(wildcard ./*.c ./sub/*.c ./a/*.c)
#patsubst函数  按照指定的模式替换指定的文件名的后缀
$(patsubst <pattern>,<replacement>,<text>)
#pattern表示指定文件的后缀
#replacement表示更改为文件的后缀
#text表示将那哪里的文件更改后缀
obj=$(patsubst %.c,%.o,$(src))

完整makefile文件编写

#标准的makefile文件
target=calc
src=$(wildcard ./*.c ./test/*.c)
obj=$(patsubst %.c,%.o,$(src))
$(target):$(obj)
	gcc $(src) -o $(target)
%.o:%.c
	gcc $^ -c
.PHONY:clean	#伪目标的声明
clean:
	-rm -rf $(obj) $(target) # 前面的-表示,当前命令执行失败后继续向下面执行。

单目录makefile最终版

其中的c文件存放在./src下,h文件放在inc目录下,o文件放在obj文件夹下,还有库文件放在./lib文件夹下

src=$(wildcard ./src/*.c)
obj=$(patsubst ./src/%.c,./obj/%.o,$(src))
ALL:a.out
my_inc=./inc
my_lib=./lib
myArgs=-Wall -g -O

a.out:$(obj)
	gcc $< -o $@ $(myArgs)
$(obj):./obj/%.o:./src/%.c 
	gcc -c $< -o $@	$(my_inc) $(myArgs)

.PHONY:clean ALL
clean:
	-rm -rf $(obj) a.out

多目录下的makefile

  • 所有的头文件放在./include文件夹下。

  • 所有程序生成的.o文件都放在./obj文件夹下

  • 生成的可执行文件放在./bin文件夹下

  • 其中add 和div1和main的文件夹下存在各自的.c文件

在这里插入图片描述

INST_DIR:=/usr/bin
CC:=gcc
INC_DTR:=-I./../include
OBJS_DIR:=obj
BIN_DIR:=bin
SUB_DIRS:=div1 sub add main obj
TARGET:=test_112
export CC INST_DIR INC_DTR BIN_DIR OBJS_DIR SUB_DIRS

all:$(SUB_DIRS)
$(SUB_DIRS):MK_bin
	make -C $@
Mk_bin:
	mkdir -p ./$(BIN_DIR)
clean:
	-rm -rf ./$(OBJS_DIR)/*.o ./$(BIN_DIR)
cleanall:
	-rm -rf ./$(OBJS_DIR)/*.o ./$(BIN_DIR) ./$(TARGET).tar.gz
install:
	cp ./$(BIN_DIR)/$(TARGET) $(INST_DIR)
uninstall:
	rm -rf $(INST_DIR)/$(TARGET)
tar:
	tar -zvcf $(TARGET).tar.gz ./
.PHONY:clean cleanall install uninstall tar

在其他的目录compute input main obj中有各自的makefile文件

#在obj目录下的
./../$(BIN_DIR)/$(TARGET):./*.o
	$(CC)  $^ -o $@
#在sub目录下的
./../$(OBJS_DIR)/sub.o:./*.c
	$(CC) -c $< -o $@ $(INC_DTR)
#在add目录下的
./../$(OBJS_DIR)/add.o:./*.c
	$(CC) -c $< -o $@ $(INC_DTR)
#在div1目录下的
./../$(OBJS_DIR)/div1.o:./*.c
	$(CC) -c $< -o $@ $(INC_DTR)
#在main目录下的
./../$(OBJS_DIR)/test.o:./*.c
	$(CC) -c $< -o $@ $(INC_DTR)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值