Eu tenho um monte de .c
arquivo de origem de teste no diretório tests/
. Agora eu quero compilar e vinculá-los respectivamente e produzir o executável *.out
em tests/
. Então eu escrevi um makefile, que não funcionou.
# ...
TestDir := tests
TestSourceFile := $(shell sh -c "ls tests/*.c")
TestTargetFile := $(subst .c,.out,$(TestSourceFile))
TestFrame := testframe.o
TestNeededObjectFile := $(TestFrame) \
+ util.o \
+ tokennames.o \
+ lex.yy.o \
+ hex.o \
.PHONY: test-%
test-%: $(TestDir)/%.out
$^
.PHONY: test
test: $(TestTargetFile)
@for t in $(TestTargetFile); do \
$$t ; \
done
$(TestDir)/%.out: $(TestDir)/%.o $(TestNeededObjectFile)
gcc -o $@ $^
%.o : %.c
gcc -c $(CFLAGS) $^
clean:
rm -rf *.o lextest *.yy.? *.tab.? *.output $(TokenNameFile) \
$(TestDir)/*.out
Quando executo make test-add
( add.c
is in tests/
), espero ver add.out
in, tests/
mas ocorre um erro:
> make test-add
make: *** No rule to make target 'tests/add.out', needed by 'test-add'. Stop.
Eu quero saber como escrever este makefile corretamente e porque este makefile está errado.
As regras de padrão no make GNU não serão consideradas se seus pré-requisitos não resolverem os arquivos existentes, diretamente ou recursivamente por meio de outras regras de padrão[1]:
Como sua
TestNeededObjectFile
macro inclui+
s espúrios e você provavelmente não possui nenhum arquivo com esse nome, isso violará a$(TestDir)/%.out:
regra.[1] de acordo com o manual GNU make :