Linux

我的 makefile 關於萬用字元有問題

  • March 22, 2019

我在目錄中有一堆.c測試源文件tests/。現在我想分別編譯和連結它們並將執行檔輸出*.outtests/. 所以我寫了一個makefile,沒有用。

# ...
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

當我執行make test-add( add.cis in tests/) 時,我期待看到add.outintests/但出現錯誤:

> make test-add
make: *** No rule to make target 'tests/add.out', needed by 'test-add'.  Stop.

我想知道如何正確編寫這個makefile以及為什麼這個makefile是錯誤的。

如果GNU make 的先決條件不能直接或通過其他模式規則遞歸地解析為現有文件,則不會考慮 GNU make 中的模式規則

$$ 1 $$:

$ make -f <(echo '%.foo: %.bar file.txt;') a.foo
make: *** No rule to make target 'a.foo'.  Stop.

$ touch a.bar
$ make -f <(echo '%.foo: %.bar file.txt;') a.foo
make: *** No rule to make target 'a.foo'.  Stop.

$ touch a.bar file.txt
$ make -f <(echo '%.foo: %.bar file.txt;') a.foo
make: 'a.foo' is up to date.

由於您的TestNeededObjectFile宏包含虛假+s,並且您可能沒有任何以這種方式命名的文件,這將違反$(TestDir)/%.out:規則。

$$ 1 $$根據 GNU make手冊

為了應用模式規則,其目標模式必須與所考慮的文件名匹配,並且其所有先決條件(在模式替換之後)必須命名存在或可以生成的文件。這些文件成為目標的先決條件。

引用自:https://unix.stackexchange.com/questions/507945