이상한 오류가 발생하여 다음과 같이 줄였습니다. 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++-9가 아닌 clang++-5.0으로 빌드되었습니다!
답변1
바라보다이 Makefile은 컴파일러를 지정하지 않고 어떻게 C 프로그램을 생성합니까?배경. Make에는 다양한 파일을 빌드하는 방법을 알려주는 기본 제공 규칙이 있습니다. 이 특별한 경우에는 개체 파일을 요청했고 .cpp
현재 디렉터리에 일치하는 파일이 있으므로 .cpp
개체 파일을 빌드하는 방법을 지정하는 규칙을 사용합니다. 파일에서.
GNU Make에서 이 규칙의 일부 부분은 특히 CXX
C++ 컴파일러용 변수와 CXXFLAGS
C++ 코드를 컴파일할 때 사용되는 플래그를 사용합니다. 환경에 이러한 변수에 대한 값이 포함되어 있는 경우 해당 값은 기본 제공 기본값보다 우선합니다. CXX
여전히 로 설정되어 있으므로 Make clang++-5.0
는 이를 사용하여 빌드를 시도합니다 Demo.o
.
두 줄의 Makefile을 사용하면 정의한 레시피가 사용되지 않습니다.왜냐하면 모든 전제 조건이 존재하지도 않고, 모두 실현될 수도 없기 때문입니다.. 대신 일반 패턴 규칙을 다시 사용하되 여전히 CXX
로 설정하세요 clang++-5.0
.
-r
이 옵션을 사용하여 기본 제공 규칙을 완전히 비활성화할 수 있습니다 make
. 따라서 보충할 수도 있습니다.
Demo.o: Demo.cpp xxx.h
어떤 레시피도 내장된 규칙을 사용하지 않지만 xxx.h
추가 해야 합니다 Demo.cpp
( xxx.h
존재하지 않고 빌드할 수 없으므로 올바르게 실패합니다).