[makefile] makefile에서 .PHONY의 목적은 무엇입니까?

.PHONYMakefile에서 무엇을 의미합니까? 나는 이것을 겪었 지만 너무 복잡하다.

누군가 간단한 용어로 설명해 줄 수 있습니까?



답변

기본적으로 Makefile 대상은 “파일 대상”이며 다른 파일에서 파일을 작성하는 데 사용됩니다. Make는 대상이 파일이라고 가정하고 Makefile을 작성하는 것이 상대적으로 쉽습니다.

foo: bar
  create_one_from_the_other foo bar

그러나 때로는 Makefile이 파일 시스템에서 실제 파일을 나타내지 않는 명령을 실행하기를 원합니다. 이에 대한 좋은 예는 공통 대상 “clean”및 “all”입니다. 그렇지 않을 수도 있지만 clean기본 디렉토리에 이름이 지정된 파일 이 있을 수 있습니다 . 이러한 경우 기본적으로 clean대상이이 파일과 연관되고 Make가 파일이 해당 종속성과 관련하여 최신 상태가 아닌 것으로 표시 될 때만이를 실행 하므로 Make가 혼동 됩니다.

이러한 특수 대상을 가짜 라고 하며 파일과 연결되지 않도록 Make와 같이 명시 적으로 말할 수 있습니다.

.PHONY: clean
clean:
  rm -rf *.o

지금 make clean과 같은라는 이름의 파일이 할 경우에도 예상 실행됩니다 clean.

Make의 관점에서, 가짜 대상은 단순히 오래된 대상이므로 make <phony_target>파일 시스템의 상태와 관계없이 요청할 때마다 실행됩니다. 일반적인에 make종종 가짜입니다 목표는 다음과 같습니다 : all, install, clean, distclean, TAGS, info, check.


답변

installmakefile에서 매우 일반적인 대상 이 있다고 가정 해 봅시다 . 을 사용 하지 않고.PHONY 이름 install이 지정된 파일 이 Makefile과 동일한 디렉토리에 있으면 아무 것도make install 수행하지 않습니다 . 이는 Make가 규칙을 해석하여 “파일을 생성하기위한 이러한 레시피를 실행하여 install” 라는 파일을 생성하기 때문 입니다. 파일이 이미 있고 종속성이 변경되지 않았으므로 아무 것도 수행되지 않습니다.

그러나 install대상을 PHONY로 만들면 make 도구에 대상이 가상임을 알리고 실제 파일을 작성할 것으로 예상해서는 안됩니다. 따라서 install파일이 존재 하는지 여부를 확인 하지 않습니다. 즉, a) 파일이 존재하면 해당 동작이 변경되지 않으며 b) 추가 stat()가 호출되지 않습니다.

일반적으로 Makefile에서 대상 이름과 이름이 같은 출력 파일을 생성하지 않는 모든 대상은 PHONY 여야합니다. 이것은 일반적으로 포함 all, install, clean, distclean, 등.


답변

참고 : make 도구는 makefile을 읽고 규칙에서 ‘:’기호 양쪽에있는 파일의 수정 타임 스탬프를 확인합니다.

‘test’디렉토리에는 다음 파일이 있습니다.

prerit@vvdn105:~/test$ ls
hello  hello.c  makefile

makefile에서 규칙은 다음과 같이 정의됩니다.

hello:hello.c
    cc hello.c -o hello

이제 ‘hello’파일이 ‘hello.c’파일 다음에 작성된 일부 데이터를 포함하는 텍스트 파일이라고 가정하십시오. 따라서 ‘hello’의 수정 (또는 생성) 타임 스탬프는 ‘hello.c’의 타임 스탬프보다 최신입니다. 따라서 명령 행에서 ‘make hello’를 호출하면 다음과 같이 인쇄됩니다.

make: `hello' is up to date.

이제 ‘hello.c’파일에 액세스하여 공백을 넣으십시오. 이는 코드 구문이나 논리에 영향을 미치지 않으며 저장하고 종료합니다. 이제 hello.c의 수정 타임 스탬프가 ‘hello’보다 수정되었습니다. 이제 ‘make hello’를 호출하면 다음과 같이 명령이 실행됩니다.

cc hello.c -o hello

그리고 ‘hello'(텍스트 파일) 파일은 새로운 바이너리 파일 ‘hello'(위의 컴파일 명령의 결과)로 덮어 씁니다.

다음과 같이 makefile에서 .PHONY를 사용하는 경우 :

.PHONY:hello

hello:hello.c
    cc hello.c -o hello

그런 다음 ‘make hello’를 호출하면 pwd ‘test’에있는 파일을 무시하고 매번 명령을 실행합니다.

이제 ‘hello’대상에 선언 된 종속성이 없다고 가정하십시오.

hello:
    cc hello.c -o hello

‘hello’파일이 이미 pwd ‘test’에 존재하면 ‘make hello’는 항상 다음과 같이 표시됩니다.

make: `hello' is up to date.


답변

.PHONY: install
  • “install”이라는 단어가이 Makefile의 파일 이름을 나타내지 않음을 의미합니다.
  • Makefile은 동일한 디렉토리에있는 “install”이라는 파일과 아무 관련이 없음을 의미합니다.

답변

파일 이름이 아닌 빌드 대상입니다.


답변

가장 좋은 설명은 GNU make manual 자체입니다 : 4.6 Phony Targets section .

.PHONYmake의 특수 내장 대상 이름 중 하나입니다 . 관심있는 다른 목표가 있으므로이 참조를 통해 감추는 것이 좋습니다.

.PHONY 대상을 고려해야 할 때 make는 해당 이름의 파일이 존재하는지 또는 마지막 수정 시간이 무엇인지에 관계없이 레시피를 무조건 실행합니다.

또한 메이크업의에 관심이있을 수 있습니다 표준 대상allclean.


답변

“.PHONY”에 대한 하나의 중요한 까다로운 처리 방법이 있습니다. 물리적 대상이 다른 물리적 대상에 의존하는 가짜 대상에 의존하는 경우 :

TARGET1-> PHONY_FORWARDER1-> PHONY_FORWARDER2-> TARGET2

TARGET2를 업데이트 한 경우 TARGET1은 TARGET1에 대해 오래된 것으로 간주되므로 TARGET1을 다시 빌드해야합니다. 그리고 그것은 실제로 이런 식으로 작동합니다 .

까다로운 부분은 TARGET2 TARGET1 부실 하지 않은 경우입니다.이 경우 TARGET1을 다시 빌드하지 않아야합니다.

:이 의외로 때문에 작동하지 않습니다 (가짜 대상으로 평소의 방법대로) 가짜 대상 어쨌든 실행 된 것을하는 수단, 가짜 대상이 업데이트 간주되었다 . 그리고 그 때문에 TARGET1은 가짜 대상에 대해 오래된 것으로 간주됩니다 .

치다:

all: fileall

fileall: file2 filefwd
    echo file2 file1 >fileall


file2: file2.src
    echo file2.src >file2

file1: file1.src
    echo file1.src >file1
    echo file1.src >>file1

.PHONY: filefwd
.PHONY: filefwd2

filefwd: filefwd2

filefwd2: file1
    @echo "Produced target file1"


prepare:
    echo "Some text 1" >> file1.src
    echo "Some text 2" >> file2.src

이것을 가지고 놀 수 있습니다 :

  • 먼저 “소스 파일”을 준비하기 위해 ‘make ready’
  • 특정 파일을 터치하여 업데이트 된 파일을보고

fileall이 가짜 대상을 통해 간접적으로 file1에 의존한다는 것을 알 수 있지만 이 종속성으로 인해 항상 다시 작성됩니다. 에서의 종속성을 fileall에서 (으) filefwd로 변경하면 file이제는 fileall매번 다시 빌드되지 않고 종속 대상이 파일로 부실한 경우에만 다시 빌드됩니다.