【问题标题】:Understand the dependency levels of makefiles了解 makefile 的依赖级别
【发布时间】:2019-04-20 15:27:01
【问题描述】:

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

  • main.c
    • global.h(包含枚举和#define 宏)
    • sdevent.h(通用头文件)
      • sdevent.c(包含 sdevent.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)

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

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

【问题讨论】:

  • Cmake有更好的教程,是一个更通用的生成make文件的工具。我强烈建议检查一下。
  • @SimonHobbs,AFAIK,make 是最通用的构建工具。但是,如果您说 Cmake 是,那么我会检查一下。感谢您的建议。
  • @klaus 我不确定,但我认为最好删除它。

标签: c makefile gnu-make


【解决方案1】:

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

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

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

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

我确信 GNU make 中存在一些深奥的角落,其中的工作方式略有不同,但在像你这样的简单 makefile 中,与 POSIX makefile 并没有偏离太远,它就是这样工作的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2011-03-13
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    相关资源
    最近更新 更多