Make

我的 Makefile 是空的,但 make 正在執行一些舊命令

  • March 3, 2020

我有一個奇怪的錯誤,我設法減少到以下錯誤。我有一個只有兩個空文件的文件夾:一個 Makefile 和一個 cpp 文件:

$ ls -la
total 8
drwxrwxr-x  2 erelsgl erelsgl 4096 Mar  3 20:12 .
drwxrwxr-x 13 erelsgl erelsgl 4096 Mar  3 20:10 ..
-rw-rw-r--  1 erelsgl erelsgl    0 Mar  3 20:12 Demo.cpp
-rw-rw-r--  1 erelsgl erelsgl    0 Mar  3 20:09 Makefile
$ cat Makefile 
$ cat Demo.cpp 

當我執行時,make我得到了預期的結果:

$ make
make: *** No targets.  Stop.

但是當我跑步時,make Demo.o我得到了一個非常奇怪的結果:

$ make Demo.o
clang++-5.0 -std=c++17   -c -o Demo.o Demo.cpp
make: clang++-5.0: Command not found
<builtin>: recipe for target 'Demo.o' failed
make: *** [Demo.o] Error 127

命令“clang++-5.0 -std=c++17”實際上是幾天前在 Makefile 中的,但我早就用 clang++-9 替換了它。現在,如您所見,Makefile 完全是空的。為什麼make仍在執行這些舊命令?

編輯:當我將 Makefile 更改為包含這兩行時,也會發生同樣的事情:

%.o: %.cpp xxx.h
   clang++-9 --compile $< -o $@

當文件 xxx.h 不存在時。這非常令人困惑:我執行make Demo.o它是用 clang++-5.0 而不是 clang++-9 建構的!

請參閱此 Makefile 如何在不指定編譯器的情況下製作 C 程序?為背景。Make 有內置的規則,告訴它如何建構各種文件;在這種特殊情況下,由於您要求一個目標文件,並且.cpp目前目錄中有一個匹配的文件,它使用指定如何從.cpp文件建構目標文件的規則。

在 GNU Make 中,該規則的某些部分最終會使用變數;特別是CXX對於 C++ 編譯器,以及CXXFLAGS編譯 C++ 程式碼時使用的標誌。如果環境包含這些變數的值,則這些值優先於內置預設值。由於CXX仍設置為clang++-5.0,因此 Make 嘗試使用它來建構Demo.o.

使用您的兩行 Makefile,您定義的配方不會被使用,因為它的先決條件並不全部存在,也不能全部製作。相反,通用模式規則再次被使用,仍然CXX設置為clang++-5.0

-r您可以使用選項完全禁用內置規則make。您也可以補充它們;因此

Demo.o: Demo.cpp xxx.h

沒有配方將使用內置規則,但xxx.h除了需要Demo.cpp(並且正確失敗,因為xxx.h不存在且無法建構)。

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