在GNU Make中强制隐式规则/模式规则评估的顺序

时间:2013-12-04 18:51:59

标签: makefile gnu-make

我有一个特定于域的语言编译器(自制),它接收文件x.inflow并生成两个文件:x.cx.h。 C文件以传统方式编译,生成的头文件必须包含在调用其中定义的函数的任何文件中。

因此,必须在编译使用它们的任何C文件之前生成头文件。我下面的当前Makefile工作正常,但是第一次构建来自clean,它可以在创建它包含的头文件之前尝试编译main.c

NAME = simplest

OBJ = $(patsubst %.c,%.o,$(wildcard *.c)) \
        $(patsubst %.inflow,%.o,$(wildcard *.inflow))

CC = gcc
CFLAGS = -g -Wall

$(NAME): $(OBJ)
    $(CC) $(CFLAGS) -o $@ $^ $(CLIBS)

# Dependencies for existing .o files.
-include $(OBJ:.o=.d)

# Compile an inflow file into both a .c and .h file.
# Note that this rule has two targets.
%.c %.h: %.inflow
    inflow $<

# Compile object files and generate dependency information.
%.o: %.c
    $(CC) -MD -MP -c $(CFLAGS) -o $@ $<

显然,我可以通过添加例如(其中simplest.h是生成的标头)来解决特定情况:

main.o: simplest.h

但有没有一种通用的方法可以强制在另一个(%.c %.h: %.inflow)的任何调用之前运行一种模式规则(%.o: %.c)?

2 个答案:

答案 0 :(得分:1)

好吧,您可以强制任何目标在仅订单先决条件的任何其他目标之前运行。例如,你可以写:

%.o : %.c | simplest.h
        $(CC) -MD -MP -c $(CFLAGS) -o $@ $<

这将确保在创建目标simplest.h之前不会调用使用此模式规则构建的目标。但是,我不认为您可以将模式放在仅限订单的先决条件中。说实话,我从来没有尝试过,所以它可能有效,我不确定。

如果没有,您只需在%.o模式规则中列出所有仅限订单的先决条件;这将确保在构建任何目标文件之前生成所有流入文件。那可能没事。

答案 1 :(得分:0)

似乎问题有两个:

  1. Make不知道在编译simplest.h之前需要生成main.c
  2. 您不希望明确告诉Make有关依赖关系(并记得在更改时更新它)。
  3. 您可以通过让Make为您创建依赖项来解决您的问题,而不是强制Make按设定顺序评估规则。查看Gnu Make手册的这一部分:http://www.gnu.org/software/make/manual/make.html#Automatic-Prerequisites

    当您运行Make时,它将扫描您的源文件并为您收集其依赖项(您不必明确列出main.o取决于simplest.h)。