타겟 파일들을 리메이크하는 어떤 표준 방법들이 자주 사용된다. 예를
들어서 오브젝트 파일을 만드는 통상적인 방법은 C
소스로부터 C 컴파일러, cc
를 사용하는 것이다.
묵시적 규칙(Implicit rules) 은 사용하고자 할 때 그것들을
자세하게 지정할 필요없도록, 통상적인 테크닉들을 사용하는 방법을
make
에게 말한다. 예를 들어서 C 컴파일을 위한 묵시적 규칙이
있다. 파일 이름들이 어떤 묵시적 규칙들이 실행될 것인가를
결정한다. 예를 들어서 C 컴파일은 `.c' 파일을 보통 취해서
`.o' 파일을 만든다. 그래서 make
는 이것이
파일 이름의 끝부분들(확장자들)의 조합을 볼 때 C 컴파일을 위한 묵시적
규칙을 적용한다.
묵시적 규칙들의 연쇄고리가 순차적으로 적용될 수 있다; 예를 들어서,
make
는 `.y' 파일로부터 `.o' 파일을, `.c' 파일을
경유해서 리메이크할 것이다.
See section 묵시적 규칙의 연쇄(Chains of Implicit Rules).
내장 묵시적 규칙들은, 변수들의 값들을 변경해서 여러분이 묵시적
규칙들이 작동하는 방식을 변경할 수 있도록, 그들의 명령에서 몇가지
변수들을 사용한다. 예를 들어서 변수 CFLAGS
는 C 컴파일을 위한
묵시적 규칙에 의해서 C 컴파일러에게 주어진 플래그들을 제어한다.
See section 묵시적 규칙에 의해 사용되는 변수(Variables Used by Implicit Rules).
여러분 자신만의 묵시적 규칙들을 패턴 규칙들(pattern rules)를 작성함으로써 정의할 수 있다. See section 패턴 규칙을 정의하고 재정하기(Defining and Redefining Pattern Rules).
접미사 규칙(uffix rules) 은 묵시적 규칙들을 정의하는 좀 더 제한된 방식이다. 패턴 규칙들이 좀 더 일반적이고 명쾌한 것이지만 접미사 규칙들은 호환성을 위해서 아직 남아 있다. See section 구닥다리 접미사 규칙(Old-Fashioned Suffix Rules).
make
가 타겟 파일을 갱신하기 위한 관습적인 방법을 찾도록 하기
위해서 여러분이 해야 할 일은 명령들을 스스로 지정하지 않도록 하는 것이
전부이다. 명령 라인들이 없는 규칙을 작성하거나 그런 규칙을 전혀
작성하지 말자. 그러면 make
는 사용할 묵시적 규칙을, 어떤 종류의
소스 파일이 존재하는가와 만들어질 수 있는가에 기반해서, 찾아낼 것이다.
예를 들어서 makefile이 다음과 같이 생겼다고 하자:
foo : foo.o bar.o cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)
`foo.o'를 언급했지만 그것에 대한 규칙을 지정하지 않았기 때문에
make
는 자동으로 그것을 갱신하는 방법을 말하는 묵시적 규칙을
찾을 것이다. 이것은 `foo.o'가 현재 존재하는지 안하는지에 상관없이
일어난다.
묵시적 규칙이 있으면 이것은 명령들과 하나 이상의 종속물들(소스 파일들) 모두를 공급할 수 있다. 묵시적 규칙이 공급할 수 없는, 헤더 파일들과 같은, 추가의 종속물들을 지정해야 한다면, `foo.o'에 대한 규칙을 명령 라인들이 없이 작성하고자 할 것이다.
각 묵시적 규칙은 하나의 타겟 패턴과 종속물 패턴들을 가진다. 동일한
타겟 패턴을 가지는 많은 묵시적 규칙들이 존재할 수 있다. 예를 들어서
많은 규칙들이 `.o' 파일들을 만들 수 있다: 하나는, `.c' 파일로부터
C 컴파일러를 사용할수도 있고; 다른 것은, `.p' 파일로부터 파스칼
컴파일러를 사용할 수도 있다; 기타 등등. 실제로 적용되는 규칙은 그것의 종속물이
존재하거나 만들어질 수 있는 것 하나이다. 그래서 파일 `foo.c'를
가진다면, make
는 C 컴파일러를 실행할 것이다; 그렇지 않고
`foo.p'를 가진다면 make
는 파스칼 컴파일러를 실행할 것이다;
기타 등등.
물론, makefile을 작성할 때 여러분은 make
가 사용했으면 하는
묵시적 규칙이 어떤 것인가를 알고 있으며, 어떤 종속 파일들이 존재할
것인가를 알고 있기 때문에 make
가 그것을 선택할 것이라는 것을
안다. 모든 사전에 정의된 묵시적 규칙들 카달로그를 보려면
See section 묵시적 규칙들의 카달로그(Catalogue of Implicit Rules).
위에서 우리는 하나의 묵시적 규칙이, 요구된 종속물들이 "존재하거나 만들어질 수 있으면" 적용된다고 말했다. 파일은 그것이 maekefile에서 타겟이나 종속물로 명시적으로 지정되고 묵시적 규칙이 그것을 만드는 방법을 재귀적으로 알아낼 수 있다면, "만들어질 수 있다". 묵시적 종속물이 다른 묵시적 규칙의 결과이라면 우리는 연쇄작용(chaining)이 일어났다고 말한다. See section 묵시적 규칙의 연쇄(Chains of Implicit Rules).
일반적으로 make
는 각 타겟에 대해서 명령이 없는 묵시적규칙, 각
더블-콜론 규칙을 검색한다. 종속물로만 언급된 파일은, 타겟의 규칙이
아무것도 지정하지 않는 타겟으로 생각되고, 그래서 이것에 대한 묵시적
규칙이 검색된다. 검색이 이루어지는 방법에 대한 자세한 내용은
See section 묵시적 규칙 검색 알고리즘(Implicit Rule Search Algorithm).
명시적 종속물들은 묵시적 규칙 검색에 아무런 영향도 미치지 않는다는 점에 주목하자. 예를 들어서 다음과 같은 명시적 규칙을 생각하자:
foo.o: foo.p
`foo.p'의 종속성은 make
가 오브젝트 파일 `.o' 파일에
대한 묵시적 규칙에 따라서 파스칼 소스 파일 `.p' 파일로부터
`foo.o'를 리메이크할 것이다라는 것을 반드시 의미하지 않는다. 예를
들어서 `foo.c'가 이미 존재하고 C 소스 파일로부터 오브젝트 파일을
만드는 묵시적 규칙이 대신 사용된다. 왜냐면 이것이 사전 정의된 묵시적
규칙들의 리스트에서 파스칼에 대한 규칙보다 먼저 나오기 때문이다
(see section 묵시적 규칙들의 카달로그(Catalogue of Implicit Rules)).
묵시적 규칙이 명령들이 없는 타겟에 대해서 사용되기를 원하지 않는다면 타겟에게, 하나의 세미콜론만 작성해서 빈 명령들을 줄 수 있다 (see section 빈 명령 사용하기(Using Empty Commands)).
다음은 makefile이 이들을 명시적으로 오버라이드하거나 취소하지 않았다면 항상 사용이 가능한 사전에 정의된 묵시적 규칙들의 카달로그이다. 묵시적 규칙들을 취소하거나 오버라이드하는 정보에 대해서 See section 묵시적 규칙 취소시키기(Canceling Implicit Rules). `-r'이나 `--no-builtin-rules' 옵션은 모든 사전에 정의된 규칙들을 취소시킨다.
`-r' 옵션이 주어지지 않았다하더라도, 이들 규칙들 모두가 항상
정의되는 것은 아니다. 많은 사전에 정의된 규칙들은 make
에서
접미사 규칙들로 구현된다. 그래서 이들은 접미사 리스트(suffix
list)에 의존적으로 정의될 것이다 (특수한 타겟 .SUFFIXES
의
종속물들의 리스트). 디폴트 접미사 리스트는 다음과 같다:
.out
, .a
, .ln
, .o
, .c
, .cc
,
.C
, .p
, .f
, .F
, .r
, .y
,
.l
, .s
, .S
, .mod
, .sym
, .def
,
.h
, .info
, .dvi
, .tex
, .texinfo
,
.texi
, .txinfo
, .w
, .ch
.web
,
.sh
, .elc
, .el
. 종속물들이 이런 접미사들 중의
하나를 가지는 아래에서 기술된 묵시적 규칙들 모두는 실제로 접미사
규칙들이다. 접미사 리스트를 변경한다면 단지 효력 있는 사전에 정의된 접미사
규칙들만이 여러분이 지정한 리스트에 있는 접미사들 중의 하나나 둘의
이름을 가지는 것들이 될 것이다; 접미사들 중에서 이들 리스트에 있지
않는 규칙들은 사용 불가능이 된다. 접미사 규칙들에 대한 상세한 내용은
See section 구닥다리 접미사 규칙(Old-Fashioned Suffix Rules).
as
를
실행함으로써 자동으로 만들어진다. 정확한 명령은
`$(AS) $(ASFLAGS)'.
`n.s' 는 C 선행 처리기 cpp
를 실행함으로써
`n.S' 파일로부터 자동으로 만들어진다. 정확한 명령은
`$(CPP) $(CPPFLAGS)'.
ld
)를 실행함으로써 자동으로 만들어진다. 정확한 명령은
`$(CC) $(LDFLAGS) n.o $(LOADLIBES)'.
이 규칙은 단일 소스 파일을 가지는 단순한 프로그램에 대해서 정확한 것을
한다. 다수의 오브젝트 파일들이 있더라도(아마도 다양한 다른 소스
파일들로부터 온 것) 정확한 것을 행할 것이다. 이들중 하나는 실행 파일의
이름과 같은 이름을 가진다. 그래서,
x: y.o z.o`x.c', `y.c' 그리고 `z.c' 모두가 존재할 때 다음을 실행할 것이다:
cc -c x.c -o x.o cc -c y.c -o y.o cc -c z.c -o z.o cc x.o y.o z.o -o x rm -f x.o rm -f y.o rm -f z.o좀 더 복잡한 경우, 이름이 실행 파일로부터 유도되는 오브젝트 파일이 없을 때, 링크를 위해서 명시적 명령을 작성해야 한다. `.o' 오브젝트 파일들로 만들어지는 각 종류의 파일은 컴파일러(`$(CC)', `$(FC)', 또는 `$(PC)' 를 사용해서 자동으로 링크된다; C 컴파일러 `$(CC)'는 `-c' 옵션 없이 `.s' 파일들을 어셈블하는 데 사용된다. 이것은 `.o' 오브젝트 파일들을 중간 파일들로 사용함으로써 이루어진다. 그러나 이것은 한 스텝으로 컴파일하고 링크하는 데 더 빠르다. 이것이 어떻게 이루어지는가이다.
make
가 특별한 경우에 이 두 언어들 중의 어떤 것을 사용중인지
자동으로 결정하는 것을 불가능하게 만든다. `.l' 파일로부터
오브젝트 파일을 다시 만들기 위해서 make
가 호출되었다면 이것은
어떤 컴파일러를 사용할 것인가를 반드시 추측해내야 한다. C 컴파일러라고
추측해낼 수도 있을 것이다. 왜냐면 이것이 가장 일반적이기
때문이다. Ratfor를 사용하고 있다면 make
가 이것을 알도록
`n.r'을 makefile안에 언급해야 한다. 또는 Ratfor를 C 파일들
없이, 배타적으로 사용하고 있다면 다음과 같이 해서 묵시적 규칙 접미사
리스트로부터 `.c'를 제거하라:
.SUFFIXES: .SUFFIXES: .o .r .f .l ...
lint
를 실행해서 `n.c' 로부터
만들어진다. 정확한 명령은 `$(LINT) $(LINTFLAGS) $(CPPFLAGS)
-i'. `n.y' 나 `n.l' 로부터 만들어진 C 코드에
대해서 동일한 명령이 사용된다.
보통 위의 있는 테이블에 나온 변수들만을 변경하고자 할 것이다. 이들은 다음 섹션에서 설명된다.
그러나 내장 묵시 규칙들에 있는 명령들이 실제로 COMPILE.c
,
LINK.p
, 그리고 PREPROCESS.S
와 같은 변수들을
사용한다. 이들의 값은 위에 나열된 명령들을 담고 있다.
make
는, `.x' 소스 파일을 컴파일하는 규칙은
COMPILE.x
라는 변수를 사용한다는 관례를
사용한다. 비슷하게 `.x' 라는 파일로부터 실행 파일ㅇ르
만드는 규칙은 LINK.x
를 사용한다; `.x' 를 선행
처리하는 규칙은 PREPROCESS.x
를 사용한다.
오브젝트 파일을 생성하는 모든 규칙들은 OUTPUT_OPTION
변수를
사용한다. make
는 이 변수를 컴파일 때의 옵션에 따라서, `-o
$@'를 담도록, 또는 빈 것이 되도록 정의한다. VPATH
(see section 종속물을 위한 디렉토리 검색(Searching Directories for Dependencies) 를 사용할 때와 비슷하게, 다른 디렉토리에
소스가 있을 때, 결과가 정확한 파일로 가도록 하기 위해서 `-o'
옵션을 사용할 필요가 있다. 그러나, 어떤 시스템들에서 컴파일러들은
오브젝트 파일들에 대해서 `-o' 옵션을 받아들이지 않는다. 그런
시스템을 사용하고 있다면, VPATH
를 사용한다면, 어떤 컴파일은
그들의 결과를 다른 위치에다 놓을 것이다. 이런 문제에 대한 가능한
해결법(workaround)은 OUTPUT_OPTION
에게 `; mv $*.o
$@' 값을 주는 것이다.
내장 묵시적 규칙의 명령들은 어떤 사전정의된 변수들을 자유롭게
사용한다. 이런 변수들을 makefile 안에서, make
에 대한
매개변수들로, 또는 환경에서, 묵시적 규칙들을
재정의하지 않고서 이들이 작동하는 방식을 바꾸기 위해, 변경할 수 있다.
예를 들어서 C 소스 파일을 컴파일하는 데 사용되는 명령은 실제로 `$(CC) -c $(CFLAGS) $(CPPFLAGS)' 이다. 사용된 변수들의 실제 값들은 `cc'와 아무것도 아니기 때문에 결국 `cc -c' 이 된다. `CC' 를 `ncc'로 재정의함으로써, `ncc' 가 묵시적 규칙에 의해서 수행되는 모든 C 컴파일에 대해서 사용되도록 할 수 있다. `CFLAGS' 를 `-g' 로 변경해서 `-g' 옵션을 각 컴파일에 전달할 수 있다. C 컴파일을 수행하는 모든 묵시적 규칙들은 `$(CC)' 를 사용하여 그 컴파일러의 프로그램 이름과 모든 것이 컴파일러에게 주어진 매개변수들 안에 `$(CFLAGS)' 를 포함한다.
묵시적 규칙들안에 사용된 변수들은 두가지 클래스들로 구분된다;
프로그램들의 이름인 것들(CC
와 같이)과, 프로그램에 대한
매개변수들을 담고 있는 것들(CFLAGS
와 같이). ("프로그램의
이름" 도 또한 어떤 명령 매개변수들을 가질 수 있지만 이것은 반드시
실제의 실행 프로그램 이름으로 시작해야 한다.) 하나 이상의 변수 값을
가진다면 그것들을 공백문자들로 구분하라.
다음은 내장 규칙들 안에서 프로그램들의 이름으로 사용되는 변수들을 모은 테이블이다:
AR
AS
CC
CXX
CO
CPP
FC
GET
LEX
PC
YACC
YACCR
MAKEINFO
TEX
TEXI2DVI
WEAVE
CWEAVE
TANGLE
CTANGLE
RM
다음은 이것의 값들이 위에 있는 프로그램들에 대한 추가의 매개변수들이 되는 변수들을 모은 테이블이다. 이런 모든 것들에 대한 디폴트는 다른 언급이 없다면 빈 문자열이다.
ARFLAGS
ASFLAGS
CFLAGS
CXXFLAGS
COFLAGS
co
프로그램에게 주어지는 여분의 플래그.
CPPFLAGS
FFLAGS
GFLAGS
get
프로그램에 주어지는 여분의 플래그.
LDFLAGS
LFLAGS
PFLAGS
RFLAGS
YFLAGS
때때로 어떤 파일은 묵시적 규칙들을 순차적으로 적용해서 만들어질 수
있다. 예를 들어서 `n.o' 라는 파일은 맨먼저 Yacc 를 실행하고
그 다음 cc
를 실행해서, `n.y'로부터 만들어질 수
있다. 이런 시퀀스는 연쇄(chain) 라고 불린다.
`n.c' 이 존재한다면, 또는 makefile 에서 언급되었다면, 어떤
특수한 검색도 필요하지 않다; make
는 `n.c' 로부터 C
컴파일을 통해서 오브젝트 파일이 만들어질 수 있다는 것을 안다; 나중에
`n.c' 를 만드는 방법을 생각할 때, Yacc 를 실행하기 위한
규칙이 사용된다. 결국 두 `n.c' 과 `n.o' 이
갱신된다.
그러나 `n.c' 이 존재하지 않고 언급되지도 않았다하더라도,
make
는 그것이 `n.o' 과 `n.y' 사이에서
끓긴 고리라는 것을 안다. 이런 경우 `n.c' 는 중간
파일(intermediate file) 이라고 불린다. 일단 make
가 중간 파일을
사용하기로 결정하였다면 이것은 마치 makefile안에서 언급된 것처럼,
그것을 생성하는 묵시적 규칙과 함께 데이터베이스에 넣어지게 된다.
중간 파일들은 모든 다른 파일들처럼 그들의 규칙을 사용해서 다시 만들어진다. 그러나 중간 파일들은 다음과 같은 두가지 방식으로 다르게 취급된다.
첫번째 다른점은, 중간 파일이 존재하지 않을 때 일어나는 것이다. 일반
팡리 b 가 존재하지 않고 make
가 b 에 종속적인
타겟을 생각한다면 이것은 항상 b를 생성한 다음 b로부터 그
타겟을 갱신한다. 그러나 b가 중간 파일이라면 make
는 그대로
둘 수도 있다. 이것은 b 또는 궁극적인
타겟을, b의 어떤 종속물도 타겟보다 더 새로운 것이 아니거나
그 타겟을 갱신할
어떤 다른 이유가 없다면, 갱신하려고 하지 않는다.
두번째 다른점은, make
가 어떤 다른 것을 갱신하기 위해서
b를 생성한다면, 이것이 더이상 필요없을 때 b를
지운다는 것이다. 그러므로 make
이전에 존재하지 않던 중간 파일은
make
이후에도 존재하지 않는다. make
는 어떤 파일이
삭제되고 있는가를 보여주는 `rm -f' 명령을
인쇄함으로써 그 삭제 사실을 여러분에게 보고한다.
일반적으로 어떤 파일은 이것이 makefile에서 타겟이나 종속물로
언급된다면 중간 파일이 될 수 없다. 그러나 특수 타겟
.INTERMEDIATE
의 종속물 리스트에 넣어서 어떤 파일을 명시적으로
중간 파일로 지정할 수 있다. 이것은 그 파일이 어떤 다른 식으로
언급되었다 하더라도 효력을 발휘한다.
중간 파일의 자동 삭제를 그 파일을 이차(secondary) 파일로
지정함으로써 막을 수 있다. 이렇게 하기 위해서 이것을 특수 타겟
.SECONDARY
의 종속물 리스트에 넣으면 된다. 어떤 파일이
이차이라면 make
는 그 파일이 사전에 존재하지 않는다는 이유
하나만으로
생성하지는 않을 것이다. 그러나 make
는 그 파일을 자동으로 지우지
않는다. 어떤 파일을 이차로 지정하는 것은 그것을 또한 중간 파일로
지정하는 것이다.
묵시적 규칙(`%.o'와 같은) 의 타겟 패턴을 특수 타겟
.PRECIOUS
의 종속물로 지정해서 타겟 패턴이 그 파일의 이름과
일치하는 묵시적 규칙들에 의해서 만들어진 중간 파일들을 보존할 수
있다. section make
를 인터럽트 또는 죽이기(Interrupting or Killing make
) 참조.
하나의 연쇄가 두개보다 많은 묵시적 규칙들을 가지고 있을 수 있다. 예를
들어서 RCS, Yacc, 그리고 cc
를 실행해서 `RCS/foo.y,v'
로부터 `foo' 를 만드는 것이 가능하다. 여기서 두 파일 `foo.y'
과 `foo.c' 이 마지막에 지워지는 중간 파일드이다.
어떤 묵시적 규칙도 연쇄에서 두번 이상 나타날 수 없다. 이것은
make
가 링커를 두번 실행해서 `foo.o.o' 로부터 `foo'를
만드는 것과 같은 이상한 일을 생각하지 않을 것이라는 것을
의미한다. 이런 제약은 묵시적 규칙 연쇄를 찾으면서 무한 루프에 빠지는
것을 막는 또다른 장점을 가진다.
그렇치 않다면 규칙 연쇄들에 의해서 처리될, 어떤 경우들을 최적화하는
몇가지 특수 묵시적 규칙들이 있다. 예를 들어서 `foo'를
`foo.c' 로부터 만드는 것은 file{foo.o} 를 중간 파일로 사용해서,
분리된 연쇄 규칙들로 컴파일되고 링크됨으로써 처리될 수 있을
것이다. 그러나 이런 경우 실제로 일어나는 것은 단일 cc
명령으로
컴파일과 링크를 같이 수행하는 특수한 규칙 하나이다. 이런 최적화된
규칙은 규칙들의 순서에서 좀 더 먼저 오기 때문에 스텝-바이-스텝
연쇄보다 더 우선 적용된다.
여러분은 패턴 규칙(pattern rule) 을 작성해서 묵시적 규칙을 정의한다. 패턴 규칙은 일반 규칙과, 이것의 타겟이 `%' (그들중 정확히 한개) 문자를 가지고 있다는 점을 제외하고는, 동일하다. 이 타겟은 파일 이름들과 일치하는 패턴으로 생각된다; `%'는 빈 서브문자열이 아니라면 무엇과도 일치할 수 있는 것이다. 반면에 다른 문자들은 그들 자신들과만 일치한다. 그들이 이름들이 타겟 이름과 관련된 방법을 보여주기 위해서 종속물들은 `%'를 사용한다.
그래서 `%.o : %.c' 라는 패턴 규칙은 파일 `stem.c' 로부터 `stem.o' 라는 파일을 만드는 방법을 말한다.
`%' 을 패턴 규칙들에서 사용한 확장이, makefile이 읽힐 때 발생하는 다른 변수나 함수 확장 후에 발생되는 것에 주의하자. See section 변수 사용 방법(How to Use Variables), 그리고 section 텍스트 변환을 위한 함수(Functions for Transforming Text).
패턴 규칙은 타겟 안에 `%' 문자 (정확히 그들 중 하나) 를 담고 있다; 그렇지 않으면 이것은 일반 규칙과 완전히 똑같이 보일 것이다. 타겟은 파일이름들과 일치하는 패턴이다; `%' 는 임의의 빈 것이 아닌 부분문자열과 일치하고 다른 문자들은 그들 자신들과만 일치한다.
예를 들어서, 패턴으로써 `%.c' 는 `.c'로 끝나는 임의의 파일 이름과 일치한다. 패턴으로써 `s.%.c' 는 `s.' 로 시작하고 `.c' 로 끝나며 적어도 다섯개의 문자 이상으로 이루어진 임의의 파일 이름과 일치한다. (`%' 와 일치하는 문자가 적어도 하나 있어야 한다.) `%' 와 일치하는 부분문자열은 줄기(stem) 이라고 불린다.
패턴 규칙의 종속물 안에 있는 `%' 는 타겟에서 `%' 와 일치한 것과 동일한 줄기(stem) 을 나타낸다. 패턴 규칙이 적용되기 위해서 그것의 타겟 패턴은 그 파일 이름과 반드시 일치해야 하며 그것의 종속물 패턴은 반드시 존재하거나 만들어질 수 있는 파일들의 이름을 갖고 있어야 한다. 이런 파일들은 그 타겟의 종속물들이 된다.
그래서 다음과 같은 형태의 규칙은
%.o : %.c ; command...
`n.o' 를, `n.c' 파일이 존재하거나 만들어질 수 있다면 종속물 `n.c' 파일을 가지고 만드는 방법을 지정한다.
`%' 를 사용하지 않는 종속물들이 있을 수 있다; 그런 종속물은 이런 패턴 규칙에 의해서 만들어진 모든 파일들에 첨부된다. 이런 변하지 않는 종속물들은 종종 유용하다.
패턴 규칙은 `%' 를 담고 있는 종속물들을 반드시 가질 필요가 없다. 또는 실제 아무런 종속물을 안가져도 된다. 그런 규칙은 효율적으로 일반 와일드 카드가 된다. 이것은 타겟 패턴과 일치하는 임의의 파일을 만드는 방법을 제공한다. See section 최후의 디폴트 규칙 정의(Defining Last-Resort Default Rules).
패턴 규칙들은 한가지 타겟 이상 가질 수 있다. 일반 규칙들과는 다르게
이런 것은 동일한 종속물들과 명령들을 가진 다른 많은 규칙들과 다르게
작동한다. 어떤 패턴 규칙이 다수의 타겟들을 가진다면, make
는 그
규칙의 명령들이 그 타겟들 모두를 만드는 책임이 있다고
이해한다. 명들들은 타겟들 전부를 만들기 위해서 단 한번만
실행된다. 타겟과 일치하는 패턴 규칙을 검색할 때, 규칙을 필요로 하는 타겟과
일치하는 것(규칙)과 다른 규칙의 타겟 패턴들이 흔히 있다: make
는 현재 문제가 되는 파일에 명령들과 종속물들을 주는 것에 대해서만
신경을 쓴다. 그러나 이 파일의 명령들이 실행중일 때 다른 타겟들은 그들
자신이 갱신된 것처럼 마킹된다.
패턴 규칙들이 makefile 에서 나타나는 순서는 아주 중요하다. 왜냐면 이것이 바로 그들이 생각되어지는 순서이기 때문이다. 동일하게 적용가능한 규칙들 중에서 단지 맨처음 찾아진 것만이 사용된다. 여러분이 작성한 규칙들은 내장된 규칙들보다 더 우선한다. 그러나 종속물들이 실제로 존재하거나 언급된 규칙은 항상, 다른 묵시적 규칙들에 의해서 반드시 만들어져야 하는 종속물들을 가진 규칙보다 우선한다는 것을 주의하자.
다음은 make
에 의해서 실제로 미리 정의된 패턴 규칙들의 몇가지
예제들이다. 먼저 `.c' 파일들을 `.o' 로 컴파일하는 규칙은:
%.o : %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
이것은 `x.c' 으로부터 `x.o' 파일을 만들수 있는 규칙을 정의한다. 명령은 규칙이 적용될 때마다 타겟 파일 이름들과 소스 파일 이름들을 대입하기 위한 자동 변수들 `$@' 과 `$<' 를 사용하고 있다. (see section 자동 변수들(Automatic Variables)).
다음은 두번째 내장 규칙이다:
% :: RCS/%,v $(CO) $(COFLAGS) $<
이것은 서브디렉토리 `RCS' 에서 대응하는 파일 `x,v' 로부터 `x' 파일을 만들 수 있는 규칙을 정의한다. 타겟이 `%' 이기 때문에 이 규칙은, 적절한 종속 파일이 존재한다면, 임의의 파일 무엇에나 용될 것이다. 더블 콜론 은 이 규칙을 terminal 로 만든다. terminal 이란 그것의 종속물이 중간 파일이 아니어야 한다는 것을 의미한다. (see section 임의의 것과도 일치하는 패턴 규칙(Match-Anything Pattern Rules)).
다음 패턴 규칙은 다음과 같은 두 타겟들을 가진다:
%.tab.c %.tab.h: %.y bison -d $<
이것은 make
에게 `bison -d x.y' 명령이
`x.tab.c' 과 `x.tab.h' 둘다 make 하라고 말하는
것이다. `foo' 가 `parse.tab.o' 과 `scan.o' 에
종속적이고 `scan.o' 파일이 `parse.tab.h' 에 종속적이면,
`parse.y' 파일이 변경될 때, `bison -d parse.y' 이 단 ㅏㄴ번
실행될 것이고 두 파일 `parse.tab.o', `scan.o' 의 종속성들이
만족될 것이다. (아마 `parse.tab.o' 파일이 `parse.tab.c'
로부터 그리고 `scan.o' 파일이 `scan.c' 로부터 재컴파일 될
것이고 `foo' 파일은 `parse.tab.o', `scan.o', 그리고
다른 종속물들로 링크될 것이며 이것은 그리고 나서 해피하게 실행될
것이다.)
`.c' 파일을 `.o' 파일로 컴파일하는 패턴 규칙을 작성하고 있다고 가정해보자: 그렇다면 어떻게 `cc' 명령이 적절한 소스 파일에 대해서 작동하도록 작성할 것인가? 그 소스 파일 이름을 명령에 쓸 수 없다. 왜냐면 그 이름은 묵시적 규칙이 적용되는 때마다 다를 것이기 때문이다.
해야할 일은 make
의 특수 기능, 자동 변수(automatic
variables) 를 사용하는 것이다. 이런 변수들은 실행되는 각 규칙에
대해서 매번 새롭게, 규칙의 종속물들과 타겟에 기반해서 다시 계산되는
값을 가진다. 이 예에서 `$@' 를 오브젝트 파일 이름에 대해서
그리고 `$<' 를 소스 파일 이름에 대해서 사용하면 될 것이다.
다음은 자동 변수들을 모아본 테이블이다:
$@
$%
make
사용하기(Using make
to Update Archive Files))일 때, 타겟 멤버 이름. 예를 들어서
타겟이 `foo.a(bar.o)'이면 `$%'는 `bar.o'이고 `$@'는
`foo.a'이다. 타겟이 아카이브 멤버가 아니면 `$%'는 빈 것이
된다.
$<
$?
make
사용하기(Using make
to Update Archive Files)).
$^
make
사용하기(Using make
to Update Archive Files)). 타겟은 이것이 의존하는 다른 각 파일들에 대해서 각
파일이 종속물 리스트에서 몇번이나 나왔는가에 상관없이, 딱 한번만
사용한다. 그래서 어떤 타겟을 위해서 한번 이상 종속물을 사용한다면
$^
의 값은 그 이름을 딱 한번 담고 있는 형태가 된다.
$+
$*
make
는 다른 make
구현물과의 호환성을
위해서만 이런 괴기스런 일을 한다. 일반적으로 묵시적 규칙들이나 정적
패턴 규칙들을 제외하고는 `$*' 를 쓰지 않도록 해야 할
것이다.
명시적 규칙 안의 타겟 이름이 인식된 접미사로 끝나지 않는다면 `$*'
는 그 규칙에 대해서 빈 문자열로 설정된다.
`$?' 는 변경한 종속물들에 대해서만 작업을 하고자 할 때, 명시적 규칙들 안에서도 유용하다. 예를 들어서 `lib' 라는 이름의 아카이브가 몇개의 오브젝트 파일들의 복사물들을 담고 있다고 가정해보자. 다음 규칙은 변경된 오브젝트 파일들만을 아카이브에다 넣을 것이다:
lib: foo.o bar.o lose.o win.o ar r lib $?
위에서 리스트된 변수들(자동 변수들)중에서,
네개는 단일 파일 이름들인 값들을 가지고
두개는 파일 이름들의 리스트들인 값들을 가진다. 이런 여섯개 변수들은
파일의 디렉토리 이름이나 디렉토리 내의 파일 이름과 같은 값을 추출하는
변종들을 가진다.
변종 변수들의 이름들은 각각 `D' 나 `F' 를
붙여서 이루어진다. 이런 변종들은 GNU make
에서 반쯤
구닥다리이다. 왜냐면 dir
과 notdir
함수들이 동일한
효과를 얻는데 사용될 수 있기 때문이다 (see section 파일 이름들을 위한 함수(Functions for File Names)). 그러나 `F' 변종들은 dir
함수의
결과에서는 항상 나타나는 마지막 슬래쉬를 모두 제거한다는 사실에
주목하자. 다음은 변종들의 테이블이다:
이런 자동 변수들에 대해서 얘기할 때 특별한 스타일의 관례를 사용한다는
것에 주목하자; objects
와 CFLAGS
와 같은 일반 변수들에
대해서 작성할 때 "변수 <
" 가 아니라
"`$<'의 값" 라고 쓴다. 이런 관례가 이런 특별한 경우에 좀 더
자연스럽게 보인다고 생각한다. 이것이 아주 깊은 중요성을 가진다고
추측하지 말자; `$<' 는 `$(CFLAGS)' 가 CFLAGS
라는
이름의 변수를 참조하는 것처럼, <
라는 변수를 참조하는
것이다. `$<' 자리에 `$(<)' 라는 변수를 쓸수도 있다.
타겟 패턴은 둘 중에 또는 둘다 빈 것일 수 있는, 접두사와 접미사 사이에 하나의 `%' 를 가진 것이다. 어떤 파일 이름이 중복없이, 접두사로 시작하고 접미어로 끝나면 패턴이 일치하는 것이다. 접두사와 접미사 사이의 텍스트는 줄기(stem) 이라고 불린다. 그래서 패턴 `%.o' 가 `test.o' 와 일치하면 줄기는 `test' 인 것이다. 패턴 규칙 종속물들은 `%' 문자에 줄기들을 대입해서 만들어진 실제 파일 이름들이다. 그래서 동일한 예제에서 종속물들 중의 하나가 `%.c' 로 작성되면 이것은 `test.c' 로 확장된다.
타겟 패턴이 슬래쉬를 갖지 않으면(그리고 보통 이것은 그렇지 않다), 파일 이름에서 디렉토리 이름들은 그 파일 이름에서, 타겟 접두사와 접미사와 비교되기전에, 제거된다. 파일 이름을 타겟 패턴과 비교한 후 디렉토리 이름들은, 이들 마지막에 있는 슬래쉬와 함께, 패턴 규칙의 종속물 패턴들과 그 파일 이름으로부터 만들어지는 종속물 파일에 더해진다. 디렉토리들은 사용할 묵시적 규칙을 찾을 목적으로만 무시된다. 그러나 그 규칙의 적용에서는 무시되지 않는다. 그래서 `e%t' 는 `src/eat' 과 일치하는 것이고 여기서 `src/a' 이 줄기이다. 종속물들이 파일 이름들이 되면 줄기로부터 디렉토리들이 그 앞에 덧붙여진다. 이때 줄기의 나머지가 `%' 에 대입된다. 종속물 패턴 `c%r' 를 가지고 줄기 `src/a' 는 파일 이름 `src/car' 를 제공한다.
패턴 규칙의 타겟이 단지 `%' 이라면 이것은 파일 이름이 무엇이든
이것과 일치하는 것이다. 우리는 이런 규칙을 임의의 것과도
일치하는(match-anything) 규칙이라고 부른다. 이들은 아주 유용하지만
make
가 그들을 생각하는 시간이 많이 든다. 왜냐면 이것은
타겟으로나 종속물로써 리스트된 각 파일 이름들에 대해서 모든 그런
규칙을 생각해야 하기 때문이다.
makefile 이 `foo.c' 를 언급했다고 하자. 이 타겟에 대해서
make
는 오브젝트 파일 `foo.c.o' 를 링크함으로써, 또는
`foo.c.c' 로부터 한번에 C 컴파일하고-링크함으로써, 또는
`foo.c.p' 로부터 파스칼 컴파일하고-링크함으로써, 그리고 기타 등등
많은 다른 가능성들을에 의해서 `foo.c' 를 만들려고 생각해야만 할
것이다.
이런 가능성들이, `foo.c' 이 C 소스 파일이고 실행 파일이 아니기
때문에, 다소 괴상망칙하다는 것을 우리는 안다. make
가 이런
가능성들을 생각하지 않는다면, `foo.c.o' 과 `foo.c.p' 과 같은
파일들이 존재하지 않을것이기 때문에 그런 가능성들을 궁극적으로 거부할
것이다. 그러나 이런 가능성들은 너무 많기 때문에 그것들을 생각해야
한다면 make
는 아주 느리게 작동할 것이다.
속도를 더 높이기 위해서 make
가 임의의것과도 일치하는 규칙들을
생각할 때 다양한 제약을 둔다. 적용될 수 있는 제약은 두개
있다. 임의의것과도 일치하는 규칙을 정의할 때마다, 그런
규칙에 대해서 하나 또는 다른 하나를 반드시 선택해야만 한다.
한가지 선택은 임의의것과도 일치하는 규칙을 더블 콜론으로 정의함으로써 terminal 로 마킹하는 것이다. 규칙이 terminal 이면 이것은, 그것의 종속물들이 실제로 존재하지 않는 한 적용되지 않는다. 다른 묵시적 규칙들로 만들어질 수 있는 종속물들은 좋은 것이 아니다. 다른 말로 하면 terminal 규칙을 넘어서 더이상의 연쇄 작용이 일어나지 않는다.
예를 들어서 RCS 와 SCCS 파일들로부터 소스들을 추출하는 내장된 묵시적
규칙들은 terminal 이다; 결과적으로 파일 `foo.c,v' 이 존재하지
않는다면 make
는 `foo.c,v.o' 나 `RCS/SCCS/s.foo.c,v'
로부터 중간 파일로써 그것을 마들려고 생각조차 하지 않을 것이다. RCS 와
SCCS 파일들은 일반적으로 최종 소스 파일들이다. 이들은 다른
파일들로부터 다시 만들어지면 안된다; 그러므로 make
는 그것들을
다시 만드는 방법들을 찾지 않음으로써 시간을 절약할 수 있다.
임의의것과 일치하는 규칙을 terminal 로 마킹하지 않으면, 이것은 비-terminal. 비-terminal 임의의것과 일치하는 규칙은 특정한 데이터 타입을 가리키는 파일 이름에 적용될 수 없다. 어떤 파일 이름은, 비-임의의것과 일치하는 묵시적 규칙 타겟이 그것과 일치할 경우, 특정 데이터 타입을 가리킨다.
예를 들어서 `foo.c' 는 패턴 규칙 `%.c : %.y' (Yacc 를
실행하는 규칙) 에 대한 타겟과 일치한다. 이 규칙이 실제로 적용가능한가
아닌가에 (파일 `foo.y' 이 존재할때만 발생한다) 대해서 생각할 필요
없이, 그것이 타겟이 일치한다는 사실로써 파일 `foo.c' 에 대한
비-terminal 임의의것과도 일치하는 규칙들 중의 아무거나를 생각하는 것을
막기에는 충분하다. 그래서 make
는 `foo.c' 를
`foo.c.o', `foo.c.c', `foo.c.p', 등으로부터 실행
파일로써 만들어볼려는 시도를 생각조차 않는다.
비-terminal 임의의것과 일치하는 규칙들이 특정한 데이터 타입들(실행 파일과 같은)을 담고 있는 파일들과을 만드는 데 사용된다는 것과, 인식된 접미사를 가지는 파일 이름들이 어떤 다른 특정한 데이터 타입(C 소스 파일과 같은)을 가리킨다는 것이 이런 제약의 동기이다.
특수한 내장된 더미 패턴 규칙들은 특정 파일 이름들을 인식해서 비-terminal 임의의것과 일치하는 규칙들이 생각되지 않도록 하기 위해서만 제공된다. 이런 더미 규칙들은 종속물들과 명령들을 가지지 않고 모든 다른 목적들에 대해서 무시된다. 예를 들어서 다음과 같은 내장된 묵시적 규칙은
%.p :
`foo.p' 과 같은 파스칼 소스 파일들이 특정한 타겟 패턴과 일치하므로 `foo.p.o' 나 `foo.p.c' 를 찾느라고 시간을 허비하지 못하도록 하기 위해서 존재한다.
`%.p' 를 위한 것과 같은 더미 패턴 규칙들은 접미사 규칙들에서의 사용을 위해서 유효하게 나열된 모든 접미사들에 대해서 만들어진다 (see section 구닥다리 접미사 규칙(Old-Fashioned Suffix Rules)).
내장 묵시적 규칙(또는 사용자가 정의한 것)을 동일한 타겟과 종속물들을 가지지만 명령들이 다른 새로운 패턴 규칙을 정의함으로써 오버라이드할 수 있다. 새로운 규칙이 정의될 때 내장 규칙이 대체된다. 새로운 규칙이 차지하는 묵시적 규칙들 시퀀스에서의 위치는 그 새로운 규칙을 작성한 위치에 의해서 결정된다.
내장 묵시적 규칙과 동일한 타겟과 종속물들을 가지지만 명령들은 없는 패턴 규칙을 정의함으로써 저 내장 묵시적 규칙을 취소할 수 있다. 예를 들어서 다음은 어셈블러를 실행하는 규칙을 취소할 것이다:
%.o : %.s
종속물들을 하나도 갖지 않는 제일-마지막(terminal) 임의의것과도 일치하는 패턴 규칙을 작성함으로써, 마지막(last-resort) 묵시적 규칙을 정의할 수 있다 (see section 임의의 것과도 일치하는 패턴 규칙(Match-Anything Pattern Rules)). 이것은 다른 패턴 규칙과 비슷하다; 이것은 임의의 타겟과도 일치할 것이다는 것이 이것이 특별한 유일한 것이다. 그래서 그런 규칙의 명령들은, 자신의 명령들을 가지지 않는 모든 타겟들과 종속물들에 대해서 그리고 다른 묵시적 규칙이 적용되지 않는 것들에 대해서 사용된다.
예를 들어서 makefile 을 테스트할 때 소스 파일들이 실제 데이터를 가지고 있는 것인가 신경쓰지 않고, 대신 그들이 존재하는가 안하는가만 신경쓸 수도 있다. 그렇다면 다음과 같이 할 수도 있다:
%:: touch $@
이것은 (종속물로써) 필요한 모든 소스 파일들이 자동으로 생성되도록 한다.
이것 대신 전혀 규칙들이 없는, 심지어 명령들을 지정하지 않는 규칙의,
타겟들에 대해서 사용되는 명령들을 정의할 수 있다. 이렇게 하기 위해서
.DEFAULT
타겟에 대한 규칙을 작성하면 된다. 그런 규칙의 명령들은
명시된 규칙의 타겟들로 나타나지 않는,
어떤 묵시적 규칙도 적용되지 않는, 종속물들에 대해서
사용된다. 일반적으로 작성하지 않으면 .DEFAULT
은 없다.
다음과 같이 .DEFAULT
를 명령이나 종속물들이 없이 사용한다면:
.DEFAULT:
.DEFAULT
에 대해서 이전에 정의된 명령들이 삭제된다. 그러면
make
는 .DEFAULT
를 전혀 정의하지 않은 것처럼 작동할
것이다.
어떤 타겟이 임의의것과도 일치하는 패턴이나 .DEFAULT
으로부터
명령들을 얻기를 원하지 않지만, 또한 어떤 명령도 그런 타겟에 대해서
실행되는 것을 원하지 않는다면, 이것에게 빈 명령들을 줄 수 있다
(see section 빈 명령 사용하기(Using Empty Commands)).
마지미가 규칙을 사용해서 다른 makefile 의 일부를 오버라이드할 수 있다. See section 다른 Makefile의 일부를 오버라이딩(Overriding Part of Another Makefile).
접미사 규칙(Suffix rules) 이란 make
에 대해서 묵시적
규칙들을 정의하는 오래된-스타일의 방법이다. 접미사 규칙들은 패턴
규칙들이 좀 더 일반적이고 좀 더 명료하기 때문에 사장되었다. 오래된
makefile 들과의 호환성을 위해서 GNU make
는 이것을
지원한다. 그들은 다음 두가지 종류가 있다:
더블-접미사(double-suffix) 와
단일-접미사(single-suffix).
더블-접미사 규칙은 두개의 접미사들로 정의된다: 타겟 접미사와 소스 접미사. 이것은 파일의 이름이 타겟 접미사로 끝나는 어떤 파일과도 일치한다. 대응하는 묵시적 종속물은 타겟 접미사를 소스 접미사로 바꿔서 만들어진다. 타겟과 소스 접미사들이 `.o' 와 `.c' 인 두-접미사 규칙 은 패턴 규칙 `%.o : %.c' 와 동일하다.
단일-접미사 규칙은 단일 접미사로 정의된다. 이것은 소스 접미사이다. 단일-접미사 규칙은 임의의 파일들과 일치하고 대응하는 묵시적 종속물 이름은 소스 접미사를 덧붙여서 만들어진다. 소스 접미삭 `.c' 인 단일-접시사 규칙은 패턴 규칙 `% : %.c' 와 동일하다.
접미사 규칙 정의들은 각 규칙의 타겟과, 정의된 (알려진) 접미사 리스트와
비교해서 인식된다. make
가 타겟이 알려진 접미사인 규칙을 보면
이 규칙은 단일-접미사 규칙으로 생각된다. make
가 타겟이 두개의
알려진 접미사들이 서로 붙은 형태인 규칙을 보면 이 규칙은 더블-접미사
규칙으로 취급된다.
예를 들어서 `.c' 와 `.o' 는 알려진 접미사 디폴트 리스트에 둘
다 있는 것이다. 그러므로 타겟이 `.c.o' 인 규칙을 정의하면
make
는 이것을 소스 접미사는 `.c' 이고 타겟 접미사는
`.o' 인 더블-접미사로 생각한다. 다음은 C 소스 파일을 컴파일하기
위한 규칙을 정의하는 오래된-스타일의 방법이다:
.c.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
접미사 규칙들은 그들 자신의 종속물을 전혀 가질수 없다. 그들이 있다면 그들은 접미사 규칙들로 생각되어지는 것이 아니라 이상 이름들을 가진 일반 파일들로 생각된다. 그래서 다음 규칙은:
.c.o: foo.h $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
`.c.o' 를 종속 파일 `foo.h' 로부터 만드는 방법을 말하는 것이 되버리고, 전혀 다음과 같은 패턴 규칙이 아니게 되버린다:
%.o: %.c foo.h $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
이것은 `.c' 파일들로부터 `.o' 파일들을 만드는 방법과 `foo.h' 에 의존하는 이 패턴 규칙을 사용해서 모든 `.o' 파일들을 만드는 방법을 말하는 것이다.
어떤 명령도 없는 접미사 규칙들도 또한 의미가 없다. 그들은 명령들을 가지지 않는 패턴 규칙들이 그러는 것처럼, 이전 규칙들을 지우지 않는다 (see section 묵시적 규칙 취소시키기(Canceling Implicit Rules)). 그들은 데이터베이스에 타겟으로 단순히 접미사나 합쳐친 한쌍의 접미사들을 넣는다.
알려진 접미사들은 단순하게 특수한 타겟 .SUFFIXES
의 종속물들의
이름이다. 사용자 자신의 접미사들을, 다음과 같이 더 많은 종속물들을
더하는 .SUFFIXES
규칙을 작성함으로써, 추가할 수 있다:
.SUFFIXES: .hack .win
이것은 `.hack' 과 `.win' 을 접미사 리스트 마지막에 더한다.
그것들에다 더하는 것 대신에 알려진 디폴트 접미사들을 제거하고자 한다면
종속물들이 전혀 없는 .SUFFIXES
를 작성하면 된다. 특수한 섭리에
의해서 이것은 .SUFFIXES
의 모든 존재하는 종속물들을
제거한다. 그리고 난후 사용자가 원하는 접미사들을 더하기 위해서 다른 규칙을
작성할 수 있다. 예를 들어서,
.SUFFIXES: # Delete the default suffixes .SUFFIXES: .c .o .h # Define our suffix list
`-r' 또는 `--no-builtin-rules' 플래그는 디폴트 접미사 리스트를 빈 것으로 만든다.
변수 SUFFIXES
는 make
가 임의의 makefile 들을 읽기 전에,
접미사 디폴트 리스트들이 정의된다. 특수 타겟 .SUFFIXES
에 대한
규칙으로 접미사들 리스트를 변경할 수 있지만 그것은 이 변수는 바꿀 수 없다.
다음은 make
가 어떤 타겟 t 에 대해서 묵시적 규칙을
검색하는데 사용하는 과정이다. 이 과정은 명령들이 없는 각 더블-콜론
규칙에 대해서, 명령이 없는 일반 규칙들의 각 타겟에 대해서, 그리고
어떤 규칙에도 타겟이 아닌 각 종속물에 대해서, 수행된다. 이것은 또한,
규칙들의 연쇄를 찾으면서 묵시적 규칙들로부터 오는 종속물들에 대해서,
재귀적으로 수행된다.
접미사 규칙들은 이 알고리즘에서 언급되지 않는다. 왜냐면 접미사 규칙들은 makefile 이 일단 읽히면 동일한 패턴 규칙들로 변환되기 때문이다.
`archive(member)' 형태의 아카이브 멤버 타겟에 대해서 다음 알고리즘이 두번 실행된다. 첫번째는 전체 타겟 이름 t 를 사용하고 두번째는 첫번째가 어떤 규칙도 찾지 못한다면 t 타겟으로써 `(member)' 를 사용한다.
.DEFAULT
에 대한 규칙이,
존재한다면, 적용된다. 이런 경우 t 에게 .DEFAULT
가 가지는
동일한 명령들을 준다. 그렇지 않다면 t 에 대한 명령들은 없는 것이
된다.
일단 적용할 규칙이 찾아지면, t 또는 n 과 일치하는 것과 다른 그 규칙의 각 타겟 패턴에 대해서, 그 패턴에 있는 `%' 는 s 로 교체되고 결과 파일 이름은, 타겟 파일 t를 다시 만들기 위해서 명령들이 실행될 때까지, 저장된다. 이런 명령들이 실행된 후 이들 저장된 파일들 각각은 데이터베이스로 들어가고 갱신된 것으로 그리고 그 파일 t과 같은 갱신 상태를 가지는 것으로 마킹된다.
패턴 규칙의 명령들이 t 에 대해서 실행될 때 자동변수들이 타겟과 종속물들에 대응하여 서정된다. See section 자동 변수들(Automatic Variables).
Go to the first, previous, next, last section, table of contents.