makefile学习

发布时间 2023-09-15 14:54:34作者: yoy116

makefile

目标: 依赖文件
tab 命令
如果依赖文件比目标文件新,则执行命令来重新生成目标文件。

四个版本makefile对比

version 1:

test:main.c sub.c sub.h
	gcc -o test main.c sub.c

version 2: 优点:当只有一个文件更新时,不用重复编译

test:main.o sub.o
	gcc -o test main.o sub.o
main.o: main.c
	gcc -c -o main.o main.c
sub.o: sub.c
	gcc -c -o sub.o sub.c
clean:
	rm *.o test -f

version 3: 升级点:makefile文件简单一点

test:main.o sub.o
	gcc -o test main.o sub.o
%.o:%.c
	gcc -c -o $@ $<
clean:
	rm *.o test -f

version 4: 支持检测头文件(需要手工添加头文件规则)

test:main.o sub.o
	gcc -o test main.o sub.o
%.o:%.c
	gcc -c -o $@ $<
sub.o:sub.h
clean:
	rm *.o test -f

自动化变量

$@ : 目标文件

$^ : 所有依赖文件

$< : 第一个依赖文件

wildcard函数

$(function arguments)的写法用于函数调用。

$(wildcard *.c)

变量的赋值和修改

= : 递归赋值,最后赋值
:= : 简单赋值,直接赋值
+= : 文本添加,用于向已经定义好的变量中添加文本
?= : 条件赋值,用于第一次对该变量赋值

复杂场景的makefile

源文件和头文件按照功能或层级散落在一个个子文件夹下。

应对复杂的目录结构

简单的做法:使用wildcard匹配所有的源文件,把这些源文件一同添加到SRCS变量中。缺点:很难看出哪些路径得到了使用
gcc中 -I 指定头文件所在的路径

配置路径:将文件目录添加到工程文件配置中去。
foreach函数的使用:$(foreach var, list, text)

SUBDIR := .
SUBDIR += ./func

EXPANDED := $(foreach dir, $(SUBDIR), $(dir)/*.c)
SUBDIR :=.
SUBDIR += ./func

INCS := $(foreach dir, $(SUBDIR), -I$(dir))
SRCS := $(foreach dir, $(SUBDIR), $(wildcard $(dir)/*.c))

main: $SRCS
	gcc $(INCS) $(SRCS) -o main

makefile入门指南