假设项目有以下文件,其中第一个文件依赖于无序列表中其类别下的文件:
- 主程序
- global.h(包含枚举和#define 宏)
- sdlevent.h(通用头文件)
- sdlevent.c(包含 sdlevent.h 的实现)
- sdlshape.h(通用头文件)
- sdlshape.c(包含 sdlshape.h 的实现)
现在,我有以下生成文件:
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
不关心写入什么序列目标,所以答案是否定的。读取整个 makefile 并在缺少目标时执行查找规则以创建目标。从技术上讲,make
创建一个 directed acyclic graph在考虑构建任何东西之前,目标和依赖项的 (DAG)。变量引用在使用时被替换,而不是在读取时被替换(异常(exception):GNU make 的 :=
赋值运算符)。
尝试调整目标的顺序。您甚至可以将变量赋值移动到底部。
我敢肯定 GNU make 中有一些深奥的角落,工作方式略有不同,但在像您这样的简单 makefile 中,不要偏离 POSIX makefile 太远,这就是它的工作方式。
关于c - 了解 makefile 的依赖级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55774955/