我有一个奇怪的错误,我设法减少到以下错误。我有一个只有两个空文件的文件夹:一个 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
。您也可以补充它们;因此没有配方将使用内置规则,但
xxx.h
除了需要Demo.cpp
(并且正确失败,因为xxx.h
不存在且无法构建)。