了解makefile的依赖级别

时间:2019-04-20 15:27:01

标签: c makefile gnu-make

假定项目具有以下文件,其中第一个文件取决于无序列表中其类别下的文件:

  • main.c
    • global.h(包含枚举和#define宏)
    • sdlevent.h(通用头文件)
      • sdlevent.c(包含sdlevent.h的实现)
    • sdlshape.h(通用头文件)
      • sdlshape.c(包含sdlshape.h的实现)

现在,我有以下makefile:

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)
  

目标$(EXE)取决于目标.c.o。我绝对需要在目标$(EXE)之后之后定义目标.c.o吗?

我不这样认为,因为即使目标$(EXE)依赖于目标$(OBJS),目标($EXE)也会被声明为之前 {{ 1}}。

1 个答案:

答案 0 :(得分:2)

  

我绝对需要在目标.c.o之后定义目标$(EXE)吗?

首先,.c.o不是目标,而是后缀规则

第二,make不在乎要写入什么序列目标,因此答案为“否”。将读取整个makefile,并且当缺少目标时,将执行查找规则以创建目标。从技术上讲,make在考虑构建任何对象之前会创建目标和依赖项的directed acyclic graph(DAG)。变量引用在使用时会被替换,而不是在读取时被替换(例外:GNU make的:=赋值运算符)。

尝试按目标顺序进行游戏。您甚至可以将变量分配移到底部。

我确定GNU make中有一些深奥的地方,它们的工作原理略有不同,但是在您的简单makefile中,它的工作方式与POSIX makefile相距不远。