etc./StackOverFlow

Makefile에서 .PHONY의 목적은 무엇입니까?

청렴결백한 만능 재주꾼 2021. 12. 20. 10:11
반응형

질문자 :Lazer


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

누군가 나에게 간단한 용어로 설명할 수 있습니까?



기본적으로 Makefile 대상은 "파일 대상"입니다. 다른 파일에서 파일을 빌드하는 데 사용됩니다. Make는 대상이 파일이라고 가정하고 Makefile을 비교적 쉽게 작성할 수 있습니다.

 foo: bar create_one_from_the_other foo bar

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

이러한 특수 대상을 phony 라고 하며 Make가 파일과 연결되어 있지 않다고 명시적으로 알릴 수 있습니다. 예를 들면 다음과 같습니다.

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

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

Make의 관점에서 phony target은 항상 오래된 대상이므로 make <phony_target> 을 요청할 때마다 파일 시스템의 상태와 무관하게 실행됩니다. 종종 가짜인 일반적인 make all , install , clean , distclean , TAGS , info , check 입니다.


Eli Bendersky

makefile에서 매우 일반적인 install 대상이 있다고 가정해 보겠습니다. .PHONY 사용하지 않고 install 이라는 파일이 Makefile과 같은 디렉토리에 존재하면 make install아무 작업도 하지 않습니다. install 이라는 파일을 생성한다"는 의미로 규칙을 해석하기 때문입니다. 파일이 이미 있고 종속성이 변경되지 않았으므로 아무 작업도 수행되지 않습니다.

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

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


George Y.

참고 : 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.

prerit jain

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

YourBestBet

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


JohnMcG

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

.PHONY 는 make의 특수 내장 대상 이름 중 하나입니다. 관심을 가질 만한 다른 대상이 있으므로 이러한 참조를 훑어볼 가치가 있습니다.

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

allclean 과 같은 make의 표준 대상 에도 관심이 있을 수 있습니다.


James Wald

특수 대상 .PHONY: 가짜 대상을 선언할 수 있으므로 make 는 실제 파일 이름으로 확인하지 않습니다. 이러한 파일이 여전히 존재하더라도 항상 작동합니다.

Makefile .PHONY: 를 넣을 수 있습니다.

 .PHONY: all all : prog1 prog2 ... .PHONY: clean distclean clean : ... distclean : ...

가짜 대상을 선언하는 또 다른 방법이 있습니다. 전제 조건 없이 ::

 all :: prog1 prog2 ... clean :: ... distclean :: ...

:: 에는 다른 특별한 의미가 있습니다( 여기 참조). 그러나 전제 조건 없이 대상이 이미 존재하더라도 항상 레시피를 실행하므로 가짜 대상으로 작동합니다.


Edouard Thiel

또한 ".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 prepare'를 수행하여 "소스 파일"을 준비합니다.
  • 특정 파일을 터치하여 업데이트된 파일을 확인하세요.

fileall은 가짜 대상을 통해 간접적으로 file1에 의존한다는 것을 알 수 있지만 이 의존성 때문에 항상 다시 빌드됩니다. 당신이 종속성을 변경하는 경우 fileall 에서 filefwdfile 지금 fileall 때마다 다시 얻을 수 있지만, 의존 대상의 경우라도 파일로에 대한 부실하지 않습니다.


Ethouris

나는 종종 기본 대상에게 발사하지 않도록 지시하는 데 사용합니다.

 superclean: clean andsomethingelse blah: superclean clean: @echo clean %: @echo catcher $@ .PHONY: superclean

PHONY가 없으면 make superclean clean , andsomethingelse , 그리고 catcher superclean . 그러나 PHONY를 사용하면 make superclean catcher superclean 하지 않습니다.

clean 대상이 PHONY라고 말하는 것에 대해 걱정할 필요가 없습니다. 왜냐하면 완전히 가짜가 아니기 때문입니다. 깨끗한 파일을 생성하지는 않지만 실행할 명령이 있으므로 make는 이것이 최종 대상이라고 생각할 것입니다.

그러나 superclean superclean 대상에 대한 deps를 제공하는 다른 모든 것과 스택을 시도합니다. 여기에는 다른 superclean 대상과 % 대상이 포함됩니다.

andsomethingelse 또는 blah 에 대해 아무 말도 하지 않으므로 분명히 포수에게 이동합니다.

출력은 다음과 같습니다.

 $ make clean clean $ make superclean clean catcher andsomethingelse $ make blah clean catcher andsomethingelse catcher blah

jettero

출처 : http:www.stackoverflow.com/questions/2145590/what-is-the-purpose-of-phony-in-a-makefile

반응형