GNU制作通配符扩展的目标和先决条件顺序的显式列表

时间:2019-04-17 05:37:39

标签: makefile

有一个简单的任务。

有两个目录- in out

初始状态

$ tree .
.
├── in
│   ├── 1
│   ├── 2
│   └── 3
├── Makefile
└── out
    ├── 1
    ├── 2
    └── 3

其中1、2、3是空文件。

现在

$ touch in/*

目标是在目录 in 中打印文件名,该文件名比目录 out 中的对应文件新,例如: in / 2 -> 出/ 2

Makefile是

out/* : in/*
    @ echo $?

运行

$ make -rd

...
 Prerequisite 'in/3' is newer than target 'out/3'.
 Prerequisite 'in/2' is newer than target 'out/3'.
 Prerequisite 'in/1' is newer than target 'out/3'.
...

订单未保留。

有人可以修复它吗?

1 个答案:

答案 0 :(得分:0)

您的makefile不能满足您的期望。它将扩展为:

out/1 out/2 out/3 : in/1 in/2 in/3
        @ echo $?

这与说每个in文件是其特定out文件的先决条件不同。以上与写作相同:

out/1 : in/1 in/2 in/3
        @ echo $?
out/2 : in/1 in/2 in/3
        @ echo $?
out/3 : in/1 in/2 in/3
        @ echo $?

,也就是说,每个out文件都取决于 ALL in文件。这就是为什么获得输出的原因。

还请注意,make仅构建它在Makefile中找到的第一个目标(当然还有该目标的所有先决条件),因此,您看不到其他out文件的任何信息。您需要一个依赖于所有all文件的第一个目标,例如out

您需要使用三个明确的规则:

.PHONY: all
all: out/1 out/2 out/3

out/1 : in/1
        @ echo $?
out/2 : in/2
        @ echo $?
out/3 : in/3
        @ echo $?

(需要预先知道哪些文件),或者使用模式规则:

.PHONY: all
all: out/*

out/% : in/%
        @ echo $?