这是一个用于编译小型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命令,并让它从依赖项中推断出来。
答案 0 :(得分:3)
隐式规则总是强制将模式匹配先决条件放在首位,而不管它们在别处定义的顺序如何。这几乎总是你想要的,因为在大多数规则中,模式匹配的先决条件是特殊的。
例如,在编译目标文件时,先决条件包括一个源文件和一堆头文件;源文件很特殊,需要在命令行中列出。 Make确保对于模式规则%.o : %.c
(例如),先决条件匹配%.c
在列表中排在第一位,因此分配给$<
自动变量,并且可以区别对待
在任何情况下,简答都是否定的,您无法修改此行为。与目标% : %.cmx
匹配的隐式规则playground
将始终强制先决条件playground.cmx
首先列在先决条件列表中。其他先决条件将维持其秩序。
如果您确实需要维护订单的先决条件,那么我建议使用静态模式规则:
TARGETS = playground
$(TARGETS) : % :
$(LD) -o $@ $^
(您也可以使用“匹配任何”模式规则,但这可能是一个真正的性能降级程序)。因为您在先决条件列表中没有模式,所以不会重新排序任何模式。