Makefile拆分字符串并将其管道化到不同的目标。

问题描述 投票:1回答:1

我试图写一个简单的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 目标。我不确定我是否在正确的轨道上。

我感谢任何帮助或提示。

bash makefile
1个回答
1
投票

我会避免重新运行 make 只是为了调用不同的目标--这对性能有影响,而且可能不可靠(取决于其他的)。Makefile),因为单独的调用可能无法正确跟踪依赖关系。

此外,我会避免使用 | - 每当一个命令与管道连接时,被管道连接的命令的退出代码将是最后一个命令的退出代码。所以像这样的调用 command | tail 将返回 tail (几乎都会成功)。即使 command 失败了,它将用来自于 tailmake 不会检测到错误,也不会停止。

因此,我尝试重写你的方法,只在目标之间创建依赖关系,就像这样。

$ 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 allmake 将检查实际输出和预期输出。

$ 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
© www.soinside.com 2019 - 2024. All rights reserved.