我正在尝试编写一个简单的Makefile来构建.expected
文件并进行比较,但是失败了。
APSSCHED=../../bin/apssched
BASE=.:../../base:../../examples
FLAGS=-DCOT
EXAMPLES=../../examples/
CASES=simple-binding1 simple-binding2
# skipping lines doesn't work ...
# run command and skip the first line
%.aps:
${APSSCHED} ${FLAGS} -p ${BASE} ${EXAMPLES}/$* | tail -n +2
# get all cases as an array to pipe it to different make targets
# maybe overcomplicating
cases:
echo ${CASES} | \
awk '{split($$0,numbers," ")} END {for(n in numbers){ print numbers[n] }}'
# create all .expected files from ${CASES}
build.expected:
$(MAKE) cases | xargs -n1 -I file /bin/bash -c '$(MAKE) file.build.expected'
# create single .expected file
%.build.expected:
$(MAKE) $*.aps > $*.expected
# compare result with
%.compare:
$(MAKE) $*.aps | diff $*.expected -
# run command for all cases and diff the result with corresponding expected
all:
$(MAKE) cases | xargs -n1 -I file /bin/bash -c '$(MAKE) file.compare'
clean.expected:
rm *.expected
在没有任何目标的情况下运行make
并没有任何反应。
echo simple-binding1 simple-binding2 | \ awk '{split($0,numbers," ")} END {for(n in numbers){ print numbers[n] }}' simple-binding1 simple-binding2
我认为问题出在我的cases
目标上。我不确定自己走的路是否正确。
感谢您的帮助或提示。
答案 0 :(得分:1)
我会避免仅仅为了调用另一个目标而重新运行make
-这会降低性能,并且可能不可靠(取决于Makefile
的其余部分),因为单独的调用可能无法跟踪正确的依赖关系。
此外,我将避免使用|
-每次命令与管道连接时,管道命令的退出代码将是最后一个命令的退出代码。因此,像command | tail
这样的调用将返回tail
的退出代码(几乎总是成功)。即使command
失败了,它也会被tail
的退出代码0覆盖,并且make
将不会检测到错误并且不会停止。
因此,我试图通过仅在目标之间创建依赖关系来重写您的方法,如下所示:
$ cat Makefile
APSSCHED=../../bin/apssched
EXAMPLES=../../examples
BASE=.:../../base:$(EXAMPLES)
FLAGS=-DCOT
CASES=simple-binding1 simple-binding2
# Just for reproducing
$(EXAMPLES)/%.aps: ;
# Generate output and store it in a file
%.output: $(EXAMPLES)/%.aps
# echo is only for reproducing
echo $(APSSCHED) $(FLAGS) -p $(BASE) $< > $@
# Copy actual output as expected
%.expected: %.output
cp -f $< $@
# Compare actual output with expected
.PHONY: %.compare
%.compare: %.output | %.expected
diff $| $<
# Generate and verify all outputs
.PHONY: all
all: $(addsuffix .compare,$(CASES))
# Regenerate expected output
.PHONY: build.expected
build.expected: $(addsuffix .expected,$(CASES))
.PHONY: clean.expected
clean.expected:
-rm -f *.expected
现在make build.expected
将创建预期的输出文件,而make all
或make
将根据预期检查实际输出:
$ make build.expected
echo ../../bin/apssched -DCOT -p .:../../base:../../examples ../../examples/simple-binding1.aps > simple-binding1.output
cp -f simple-binding1.output simple-binding1.expected
echo ../../bin/apssched -DCOT -p .:../../base:../../examples ../../examples/simple-binding2.aps > simple-binding2.output
cp -f simple-binding2.output simple-binding2.expected
rm simple-binding1.output simple-binding2.output
$ make
echo ../../bin/apssched -DCOT -p .:../../base:../../examples ../../examples/simple-binding1.aps > simple-binding1.output
diff simple-binding1.expected simple-binding1.output
echo ../../bin/apssched -DCOT -p .:../../base:../../examples ../../examples/simple-binding2.aps > simple-binding2.output
diff simple-binding2.expected simple-binding2.output
rm simple-binding1.output simple-binding2.output