为什么我的 makefile 在构建后会调用 rm 依赖项?

sar*_*ter 6 makefile

当我运行时make -j tests,它使测试正常,但随后删除了依赖项。为什么会这样?我该如何解决?对于复杂的 makefile,我深表歉意。makefile 的相关部分是测试部分。

生成文件:

# Build tools
CC = clang++ -g --std=gnu++11 -O3
LEX = flex
YACC = bison -d

# Includes
CC_HEADERS   = `llvm-config-3.5 --cppflags`
CC_LIBRARIES = -lboost_program_options `llvm-config-3.5 --libs all --ldflags` -ltinfo -lpthread -lffi -ldl -lm -lz

# Created files
GENERATED_SOURCES = parser.cpp tokens.cpp
GENERATED_FILES   = $(GENERATED_SOURCES)
EXEC = brainfuck.out

# Test cases
TESTS            = $(wildcard ./tests/*.bf)
TESTS_IN         = $(TESTS:.bf=.in)
TESTS_BUILD      = $(TESTS:.bf=.build)
TESTS_EXPECTED   = $(TESTS:.bf=.expected)
TESTS_ACTUAL     = $(TESTS:.bf=.actual)
TESTS_DIFF       = $(TESTS:.bf=.diff)
GENERATED_FILES += $(TESTS_BUILD) $(TESTS_EXPECTED) $(TESTS_ACTUAL) $(TESTS_DIFF)

# Generic config
SOURCES  = $(filter-out $(GENERATED_SOURCES), $(wildcard *.cpp))
SOURCES += $(GENERATED_SOURCES)
OBJECTS  = $(SOURCES:.cpp=.o)

# Main targets
target: $(EXEC)

all: target tests

# Generated source targets
tokens.cpp: tokens.l parser.hpp
    $(LEX) -o $@ $<

parser.hpp: parser.cpp

parser.cpp: parser.y
    $(YACC) -o $@ $<

# Test targets
tests: $(TESTS_DIFF)
    @echo ""
    @echo "#####################"
    @echo "# Begin test output #"
    @echo "#####################"
    @$(foreach f,$^, echo "Test:" $(f:.diff=.bf); cat $(f); echo "";)
    @echo "#####################"
    @echo "#  End test output  #"
    @echo "#####################"
    @echo ""

tests/%.build: tests/%.bf $(EXEC)
    ./brainfuck.out $< -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o $@

tests/%.expected: tests/%.bf tests/%.in
    -bf -c65535 $< < $(word 2,$^) > $@

tests/%.actual: tests/%.build tests/%.in
    -$< < $(word 2,$^) > $@

tests/%.diff: tests/%.expected tests/%.actual
    -diff $< $(word 2,$^) > $@

# Generic targets
clean:
    rm -rf $(EXEC) $(OBJECTS) $(GENERATED_FILES) $(GENERATED_SOURCES:.cpp=.hpp)

$(EXEC): $(OBJECTS)
    $(CC) -o $@ ${OBJECTS} $(CC_LIBRARIES)

%.o: %.cpp parser.hpp
    $(CC) $(CC_HEADERS) -c $< -o $@
Run Code Online (Sandbox Code Playgroud)

进行输出:

bf -c65535 tests/awib-0.4.bf < tests/awib-0.4.in > tests/awib-0.4.expected
./brainfuck.out tests/awib-0.4.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/awib-0.4.build
bf -c65535 tests/dbfi.bf < tests/dbfi.in > tests/dbfi.expected
./brainfuck.out tests/dbfi.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/dbfi.build
bf -c65535 tests/factor.bf < tests/factor.in > tests/factor.expected
./brainfuck.out tests/factor.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/factor.build
bf -c65535 tests/hanoi.bf < tests/hanoi.in > tests/hanoi.expected
./brainfuck.out tests/hanoi.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/hanoi.build
bf -c65535 tests/long.bf < tests/long.in > tests/long.expected
./brainfuck.out tests/long.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/long.build
bf -c65535 tests/mandelbrot.bf < tests/mandelbrot.in > tests/mandelbrot.expected
./brainfuck.out tests/mandelbrot.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/mandelbrot.build
bf -c65535 tests/prime.bf < tests/prime.in > tests/prime.expected
./brainfuck.out tests/prime.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/prime.build
tests/dbfi.build < tests/dbfi.in > tests/dbfi.actual
tests/long.build < tests/long.in > tests/long.actual
tests/factor.build < tests/factor.in > tests/factor.actual
tests/prime.build < tests/prime.in > tests/prime.actual
tests/mandelbrot.build < tests/mandelbrot.in > tests/mandelbrot.actual
tests/hanoi.build < tests/hanoi.in > tests/hanoi.actual
tests/awib-0.4.build < tests/awib-0.4.in > tests/awib-0.4.actual
diff tests/factor.expected tests/factor.actual > tests/factor.diff
diff tests/awib-0.4.expected tests/awib-0.4.actual > tests/awib-0.4.diff
diff tests/mandelbrot.expected tests/mandelbrot.actual > tests/mandelbrot.diff
diff tests/hanoi.expected tests/hanoi.actual > tests/hanoi.diff
diff tests/long.expected tests/long.actual > tests/long.diff
diff tests/prime.expected tests/prime.actual > tests/prime.diff
diff tests/dbfi.expected tests/dbfi.actual > tests/dbfi.diff

#####################
# Begin test output #
#####################
Test: tests/awib-0.4.bf

Test: tests/dbfi.bf

Test: tests/factor.bf

Test: tests/hanoi.bf

Test: tests/long.bf

Test: tests/mandelbrot.bf

Test: tests/prime.bf

#####################
#  End test output  #
#####################

rm tests/mandelbrot.actual tests/hanoi.build tests/long.actual tests/mandelbrot.build tests/factor.actual tests/awib-0.4.actual tests/long.build tests/prime.actual tests/hanoi.expected tests/factor.build tests/awib-0.4.build tests/dbfi.expected tests/prime.build tests/mandelbrot.expected tests/dbfi.actual tests/long.expected tests/dbfi.build tests/hanoi.actual tests/factor.expected tests/prime.expected tests/awib-0.4.expected
Run Code Online (Sandbox Code Playgroud)

注意最后一行rm ...。这是从哪里来的?

sar*_*ter 7

解决方案是将其放在.SECONDARY:makefile 的顶部。更多信息在这里:http://www.thinkplexx.com/learn/howto/build-chain/make-based/prevent-gnu-make-from-always-removing-files-it-says-things-like-rm-或删除中间文件

\n\n

摘抄:

\n\n
\n

GNU make 确实会跟踪一些在构建期间创建的文件,\n 并且它会在构建后删除这些文件。这些文件称为“中间文件”。它们应该由 make\xe2\x80\x99s“隐式规则链”创建。因为创建它们是为了促进其他事情,所以 make 在构建后认为它们无用并删除它们。

\n\n

...

\n\n

.SECONDARY没有先决条件会导致所有目标都被视为次要目标(即,不会删除任何目标,因为它被视为中间目标

\n
\n