我在Makefile有奇怪的行为。基本上,对于grammar.aps,它需要先运行grammar.generate来创建文件,然后运行grammar.class来编译生成的文件。如果我单独运行依赖项,所有这些都可以工作。但是如果我运行grammar.aps,它就不工作了。
// Running everything
➜ tests git:(first-follow-tests) ✗ make
scalac -cp .:../../../lib/aps-library-2.12.jar Spec.scala
make: *** No rule to make target 'grammar.class', needed by 'grammar.aps'. Stop.
// Now running first depdency of `grammar.aps` which is `grammar.generate`
➜ tests git:(first-follow-tests) ✗ make grammar.generate
../../../bin/aps2scala -DCOT -p ../..:../../../base grammar
// Now running second depdency of `grammar.aps` which is `grammar.generate`
➜ tests git:(first-follow-tests) ✗ make grammar.class
scalac -cp .:../../../lib/aps-library-2.12.jar grammar.scala
// Okay but why grammar.aps didn't work? ... Makefile continues further now
➜ tests git:(first-follow-tests) ✗ make
scalac -cp .:../../../lib/aps-library-2.12.jar grammar.scala
../../../bin/aps2scala -DCOT -p ../..:../../../base grammar
echo "Building aps"
Building aps
scalac -cp .:../../../lib/aps-library-2.12.jar GrammarUtil.scala
echo "Building GrammarUtil.scala"
Building GrammarUtil.scala
// Same problem with `first.aps`
make: *** No rule to make target 'first.aps', needed by 'FirstSpec.compile'. Stop.Makefile:
SPECS=First Follow
EXAMPLES_PATH=../..
ROOT_PATH=../${EXAMPLES_PATH}
SCALAV=2.12
APSLIB=${ROOT_PATH}/lib/aps-library-${SCALAV}.jar
SCALA_FLAGS=.:${APSLIB}
APS2SCALA=${ROOT_PATH}/bin/aps2scala
.PHONY:
all: $(addsuffix Spec.compile, $(SPECS))
%.class: %.scala
scalac -cp ${SCALA_FLAGS} $<
%.generate:
${APS2SCALA} -DCOT -p ${EXAMPLES_PATH}:${ROOT_PATH}/base $*
%.aps: %.generate %.class
echo "Building aps"
%.run: %.class
@scala -cp ${SCALA_FLAGS} $<
FirstSpec.compile: Spec.class GrammarUtil.compile first.aps FirstSpec.class
echo "Building FirstSpec.scala"
FollowSpec.compile: Spec.class GrammarUtil.compile follow.aps FollowSpec.class
echo "Building FollowSpec.scala"
GrammarUtil.compile: grammar.aps grammar.class GrammarUtil.class
echo "Building GrammarUtil.scala"
.PHONY:
clean:
rm -f *.class grammar.scala first.scala follow.scala发布于 2021-04-05 17:37:03
,我在Makefile上有奇怪的行为。基本上,对于grammar.aps,它需要先运行grammar.generate来创建文件,然后运行grammar.class来编译生成的文件。如果我单独运行依赖项,所有这些都可以工作。但是如果我运行grammar.aps,它就不工作了。
您正在尝试将makefile当作脚本对待。在最基本的层次上,它是对您的项目的声明性描述,它告诉make如何构造一个或多个目标,并给出每个目标的特定先决条件列表。每个先决条件列表都是偶然排序的。一个先决条件出现在词汇上高于另一个先决条件,这一点没有任何意义。由make根据makefile中的信息和可用文件选择和执行构建计划。
特别是,make根据声明的构建规则,根据运行开始时可用的先决条件对要构建的中间目标进行分析。此外,先决条件构建顺序仅受先决条件本身的前提条件的限制,并不一定是可预测的。
但是,make确实为您提供了信息丰富的错误消息。例如,这个..。
make:*没有规则可以使目标“gramar.class”成为“gramar.aps”所需要的。停止播放。
..。非常清楚:需要构建目标grammar.aps,并且它以grammar.class为先决条件,但是没有构建grammar.class的规则。也就是说,没有以grammar.class为目标的规则。实际上,构建grammar.generate将创建grammar.class是不相关的,因为您还没有将其表达给make。
您可以通过将%.generate的规则转换为%.class的规则来解决这个特殊问题。
%.class:
${APS2SCALA} -DCOT -p ${EXAMPLES_PATH}:${ROOT_PATH}/base $*
%.aps: %.class
echo "Building aps"更广泛地说,你应该更喜欢用真正的目标写规则,而不是用假的规则。虚假的目标不一定是坏的,但它们并不是真正的目标的可行替代品。
https://stackoverflow.com/questions/66956620
复制相似问题