Makefile 重新编译未更改的文件

Makefile recompiling unchanged files

我正在尝试让我的 Makefile 仅在文件发生更改时重新编译,并且它对 Java 目标非常有效,但不适用于 JS。没有报告任何错误,但是当我第二次 运行 make bundle 时,它仍然会重新 运行 执行所有这些命令。

手动 运行ning find ... 的输出似乎完全符合预期,没有多余或缺失的行。

JAVA_SRC_DIR := .
JAVA_SOURCES := $(shell find $(JAVA_SRC_DIR) -name '*.java' -o -name '*pom.xml')

JS_SRC_DIR := ./ui-bundle
JS_EXCLUDE := \(node_modules\|coverage\)
JS_SOURCES := $(shell find $(JS_SRC_DIR) -name '*.js' -o -name '*.jsx' -o -name '.babelrc' -o -name 'package.json' | grep -v $(JS_EXCLUDE) | grep -v -e '^$')

bundle: $(JS_SOURCES)
    npm install
    ./node_modules/jest-cli/bin/jest.js --verbose
    ./node_modules/gulp/bin/gulp.js package

service: $(JAVA_SOURCES)
    mvn clean install -pl "!integration"

我猜这与它有关,但是当我尝试查找 make 认为已更改 make -d | grep "\(older\|newer\)" 的文件时,它没有找到任何内容,但是 make -d 结束于:

 Finished prerequisites of target file `bundle'.
 Must remake target `bundle'.

另外 make -d 似乎尝试 运行 某种 npm 命令。

我哪里错了?

问题是 bundle 只是规则的名称,规则实际上并没有构建名为 "bundle" 的文件。无论先决条件多新或多旧,当您 make bundle 时,Make 发现不存在这样的文件,推断它必须被构建,并执行规则。

如果你想让 Make 在先决条件没有改变的情况下避免执行规则,你必须给它一些东西来比较它们。如果您可以识别规则总是修改的某个文件,则可以将该文件作为目标。我不能推荐候选人,因为我不知道 npmjestgulp 做什么,但假设它是 jest_output:

jest_output: $(JS_SOURCES)
    ...

或者你可以有一个名为 bundle 的实际文件,它用作 Make 的标记,一个只有名称和修改时间的空文件:

bundle: $(JS_SOURCES)
    npm install
    ./node_modules/jest-cli/bin/jest.js --verbose
    ./node_modules/gulp/bin/gulp.js package
    touch bundle