了解 makefile 的依赖级别

Understand the dependency levels of makefiles

假设该项目有以下文件,其中第一个文件依赖于无序列表中其类别下的文件:

现在,我有以下生成文件:

CC = gcc
CFLAGS = -g -w -std=c99
LIBS = -lSDL2 -lSDL2_image -lSDL2_ttf

SRCS = main.c sdlshape.c sdlevent.c
OBJS = $(SRCS:.c=.o)
EXE = play

all: $(EXE)

.c.o:
    $(CC) -c $(CFLAGS) $<

$(EXE): $(OBJS)
    $(CC) -o $(EXE) $(OBJS) $(LIBS)

$(OBJS): global.h sdlevent.h sdlshape.h

run : all
    ./$(EXE)

clean:
    rm -f *.o *~ $(EXE)

The target $(EXE) is dependent on the target .c.o. Do I absolutely need to define the target $(EXE) after the target .c.o?

我不这么认为,因为即使目标 $(EXE) 依赖于目标 $(OBJS),目标 ($EXE) 之前声明 $(OBJS).

Do I absolutely need to define the target $(EXE) after the target .c.o?

首先,.c.o不是一个目标,它是一个后缀规则

其次,make不关心写入什么序列目标,所以答案是"no"。读取整个 makefile 并在缺少目标时执行查找规则以创建目标。从技术上讲,make 在考虑构建任何东西之前会创建目标和依赖项的 directed acyclic graph (DAG)。变量引用在使用时被替换,而不是在读取时被替换(例外:GNU make 的 := 赋值运算符)。

尝试调整目标的顺序。您甚至可以将变量赋值移动到底部。

我敢肯定 GNU make 中有一些深奥的角落,工作方式略有不同,但在像您这样的简单 makefile 中,不要偏离 POSIX makefile 太远,这就是它的工作方式。