强制不要在自动变量扩展中重新排序先决条件

时间:2013-12-14 11:28:34

标签: makefile ocaml gnu-make

这是一个用于编译小型OCaml程序的makefile(GNU make):

SUFFIXES:=
OCAML=ocamlopt
LD=ocamlopt
OFLAGS=

.PHONY: all clean

all: playground

playground.cmx: playground.ml lstream.cmi
playground: lstream.cmx playground.cmx

%.cmi: %.ml
    $(OCAML) $(OFLAGS) -c $<

%.cmx: %.ml
    $(OCAML) $(OFLAGS) -c $<

%: %.cmx
    $(LD) -o $@ $^

playground使用Lstream模块中的函数。在这种情况下,ocaml链接器要求链接的文件按依赖顺序指定(例如:ocamlopt -o playground lstream.cmx playground.cmx)。

尽管我按正确的顺序定义了playground规则的依赖项, make始终重新排序并执行ocamlopt -o playground playground.cmx lstream.cmx,这会导致链接器错误。

有没有办法强制执行正确的行为?我想避免明确指定link命令,并让它从依赖项中推断出来。

1 个答案:

答案 0 :(得分:3)

隐式规则总是强制将模式匹配先决条件放在首位,而不管它们在别处定义的顺序如何。这几乎总是你想要的,因为在大多数规则中,模式匹配的先决条件是特殊的。

例如,在编译目标文件时,先决条件包括一个源文件和一堆头文件;源文件很特殊,需要在命令行中列出。 Make确保对于模式规则%.o : %.c(例如),先决条件匹配%.c在列表中排在第一位,因此分配给$<自动变量,并且可以区别对待

在任何情况下,简答都是否定的,您无法修改此行为。与目标% : %.cmx匹配的隐式规则playground始终强制先决条件playground.cmx首先列在先决条件列表中。其他先决条件将维持其秩序。

如果您确实需要维护订单的先决条件,那么我建议使用静态模式规则:

TARGETS = playground

$(TARGETS) : % :
        $(LD) -o $@ $^

(您也可以使用“匹配任何”模式规则,但这可能是一个真正的性能降级程序)。因为您在先决条件列表中没有模式,所以不会重新排序任何模式。