Note/Makefile2008. 2. 12. 18:39


Makefile - 가짜 목적물(Phony Targets)

가짜 목적물은 실제로 파일의 이름이 아닌 것이다. 이것은 여러분이 명시적인 요구를 할 때 실행되는 어떤 명령들에 대한 이름이다. 가짜 목적물을 사용하는 데는 두 가지 이유가 있다: 동일한 이름을 가진 파일과 충돌을 피하기 위해서가 하나이고 퍼포먼스를 개선하기 위한 것이 하나이다.

그것의 명령들이 목적 파일을 생성하지 않을 규칙을 만든다면, 그 명령들은 목적물이 다시만들어야 하는 것으로 나타날 때마다 실행될 것이다. 다음은 하나의 예제이다:

clean:
        rm *.o temp

rm 명령이 `clean'이라는 이름의 파일을 생성하지 않기 때문에, 아마도 그런 파일은 앞으로 절대 존재하지 않을 것이다. 그러므로, rm 명령은 여러분이 `make clean'이라고 말할 때마다 실행될 것이다.

가짜 목적물은 이 디렉토리에서 `clean'이라는 이름의 파일을 무엇인가가 생성한다면 작업을 멈출 것이다. 그것은 종속물을 갖지 않기 때문에 `clean'이라는 파일은 무조건 가장 최근 것으로 생각될 것이고 그것의 명령들은 절대 수행되지 않을 것이다. 이런 문제를 피하기 위해서 여러분은 명시적으로 가짜가 될 목적물을, 특수한 목적물 .PHONY(see section 특수 내장 타겟 이름(Special Built-in Target Names))를 써서 다음과 같이, 선언할 수 있다:

.PHONY : clean

일단 이렇게 설정하면 `make clean'`clean'이라는 이름의 파일의 존재를 신경쓰지 않고서 그 명령들을 실행할 것이다.

가짜 목적물들은 다른 파일들로부터 실제 리메이크될 수 있는 실제 파일을 지칭하는 것이 아니란 것을 알기 때문에, make은 가짜 목적들을 검색하는 묵시적인 규칙을 스킵한다(see section 묵시적 규칙(Using Implicit Rules)). 비록 실제 파일의 존재 여부를 신경쓰지 않더라도, 이것이 바로 가짜 목적물이 퍼포먼스에 좋다고 한 이유이다.

그래서 다음과 같이 여러분은 먼저 clean이 가짜 목적물이다라고 말하는 라인을 쓰고, 규칙을 써야 한다:

.PHONY: clean
clean:
        rm *.o temp

포니 타겟은 실제 타겟 파일의 종속물이 되어서는 안된다; 만일 그렇다면, 그것의 명령들이, make가 그 파일을 업데이트할 때마다, 실행될 것이다. 포니 타겟이 실제 타겟의 종속물이 절대로 아닌 한, 포니 타겟 명령들은 포니 타겟이 특수한 goal일 때만 실행될 것이다 (see section goal을 지정하는 매개변수(Arguments to Specify the Goals)).

포니 타겟들은 종속물들을 가질 수 있다. 한 디렉토리가 다수의 프로그램들을 포함하고 있을 때, 이런 프로그램 모두를 하나의 makefile `./Makefile' 안서 기술하는 것이 가장 편하다. 디폴트로 만들어진 타겟이 makefile에서 첫번째가 될 것이기 때문에 이것이 `all'라는 이름의 포니 타겟이 되도록 하고 그것의 종속물로써 모든 개별 프로그램들로 설정하는 것이 일반적이다. 예를 들어서:

all : prog1 prog2 prog3
.PHONY : all

prog1 : prog1.o utils.o
        cc -o prog1 prog1.o utils.o

prog2 : prog2.o
        cc -o prog2 prog2.o

prog3 : prog3.o sort.o utils.o
        cc -o prog3 prog3.o sort.o utils.o

이제 여러분은 `make'가 모든 세개의 프로그램들을 다시 만들도록 할 수 있거나 매개변수로써, 다시 만들 하나를 지정할 수 있다 (`make prog1 prog3'와 같이).

하나의 포니 타겟이 다른 것의 종속물이라면 이것은 다른 것의 서브루틴으로 작동된다. 예를 들어서 다음 `make cleanall' 는 오브젝트 파일들, 차이 파일들, 그리고 `program' 파일을 모두 지울 것이다:

.PHONY: cleanall cleanobj cleandiff

cleanall : cleanobj cleandiff
        rm program

cleanobj :
        rm *.o

cleandiff :
        rm *.diff


Posted by 스카이데이즈