Go to the first, previous, next, last section, table of contents.


Makefiles 작성(Writing Makefiles)

make에게 makefile이라고 불리는 데이터베이스를 읽어서 그것으로부터 시스템을 재컴파일 하는 방법을 가르켜 주는 정보.

Makefile이 담고 있는 것(What Makefiles Contain)

makefile들은 다섯 가지 종류의 것들을 담고 있다: explicit rules, implicit rules, variable definitions, directives, 그리고 comments. 규칙, 변수, 그리고 지시자 등은 이 후 장들에서 설명될 것이다.

여러분의 Makefile에 줄 이름(What Name to Give Your Makefile)

make가 makefile을 찾을 때, 이것은 디폴트로 다음과 같은 이름들을 순서대로 찾으려고 한다: `GNUmakefile', `makefile' 그리고 `Makefile'.

일반적으로 여러분은 여러분의 makefile을 `makefile'이나 `Makefile'로 불러야 할 것이다. (우리는 `Makefile'을 권한다. 왜냐면 그것이 디렉토리 리스팅의 처음 근처에, 다른 `README'와 같은 중요한 파일들 바로 근처에, 우뚝 솟아 보이기 때문이다.) 맨처음 검사되는 파일 `GNUmakefile'은 대부분의 makefile들에 대해서 추천되지 않는 것이다. 여러분은 이 이름을 GNU make에 종속적인 makefile에 대해서만 사용하기 바란다. 그리고 이 이름은 다른 make에 의해서 이해되지 않을 것이다. 다른 make 프로그램들은 `makefile'`Makefile' 을 찾지만 `GNUmakefile'은 찾지 않는다.

make가 이런 이름들 중에 어떤 것도 찾지 못하면 어떤 makefile도 사용하지 않는다. 이런 경우 여러분은 명령 매개변수로 어떤 goal을 반드시 지정해야 하고 그러면 make는 그것을 단지 내장된 묵지적 규칙들만을 사용하여서 리메이크하는 방법을 찾아낼 것이다.See section 묵시적 규칙(Using Implicit Rules).

여러분이 makefile에 대해서 비표준 이름을 사용하고자 한다면 makefile 이름을 `-f'`--file'옵션을 사용해서 지정할 수 있다. 매개 변수들 `-f name'`--file=name'make에게 makefile로써 name이라는 파일을 읽도록 한다. 하나 이상의 `-f name'`--file=name'옵션을 사용하면 여러가지 makefile들을 지정할 수 있다. 모든 makefile들이 지정된 순서대로 연결된다. 디폴트 makefile 이름들, `GNUmakefile',`makefile' 그리고 `Makefile'는 여러분이 `-f name'`--file=name'을 지정하면 자동으로 체크되지 않는다.

다른 makefile 삽입(Including Other Makefiles)

include 지시어는 make가 현재 makefile을 읽는 것을 잠시 중단하고 계속하기 전에 하나 이상의 다른 makefile들을 읽도록 한다. 이 지시어는 다음과 같이 보이는 makefiel의 한 라인이다:

include filenames...

filenames can contain shell file name patterns.

그 라인의 여분의 공백들은 허용되고 무시되지만, 탭은 허용되지 않는다. (탭으로 그 라인이 시작하면 이것은 명령 라인으로 생각될 것이다.) include와 파일 이름들 사이에 그리고 파일 각각의 이름들 사이에 공백이 필요하다. `#'로 시작하는 주석이 라인의 마지막에 쓰여도 된다. 파일 이름들이 변수나 함수 레퍼런스를 담고 있다면 그들은 확장된다.See section 변수 사용 방법(How to Use Variables).

예를 들어서 여러분이 세 개의 `.mk' 파일들, `a.mk', `b.mk', 그리고 `c.mk'를 가지고 있고, $(bar)bish bash로 확장된다면 다음 표현은

include foo *.mk $(bar)

다음의 것과 동일하다.

include foo a.mk b.mk c.mk bish bash

makeinclude 지시어를 처리하고 있을 때, 그것은 makefile을 담고 있는 것을 읽는 것을 잠시 중지하고 리스트된 파일들을 순서대로 읽는다. 이것이 끝나면 make는 지시어가 있었던 makefile을 다시 읽는다.

여러가지 디렉토리들에 있는 개개의 makefile들에 의해서 처리되는 다수의 프로그램들이 변수 정의들(see section 변수 설정(Setting Variables))이나 패턴 규칙들(see section 패턴 규칙을 정의하고 재정하기(Defining and Redefining Pattern Rules))의 공통 집합을 필요로 할 때가, include 지시어들을 사용하는 한가지 경우이다.

소스 파일들로부터 dependencies를 자동으로 생성하고자 할 때가 다른 그러한 경우이다; dependencies는 주(主) makefile에 의해서 삽입되는 파일에 놓여질 수 있다. 다른 버전의 make와 같이 전통적으로 행해진 것처럼 주 makefile의 마지막에다 dependencies를 추가하는 것보다, 저렇게 하는 것이 훨씬 더 분명하다. See section 종속물들을 자동으로 생성하기(Generating Dependencies Automatically).

지정된 이름이 slash로 시작하지 않고 그 파일이 현재 디렉토리에 없으면 다른 여러 디렉토리들이 검색된다. 먼저, `-I' 또는 `--include-dir' 옵션으로 지정한 임의의 디렉토리들이 검색된다 (see section 옵션들의 요약(Summary of Options)). 그리고 나서 다음과 같은 디렉토리들이 이 순서로 (존재한다면) 검색된다: `prefix/include' (일반적으로 `/usr/local/include' (1)) `/usr/gnu/include', `/usr/local/include', `/usr/include'.

삽입된 makefile이 이런 디렉토리들중의 어느 곳에도 찾아질 수 없다면 경고 메시지가 나타나지만 이것은 즉각 치명적인 에러가 아니다; include를 포함하는 makefile의 처리가 계속된다. 일단 makefile들을 읽는 것이 끝나면 `make'는 갱신되어야 하는 것이나 존재하지 않는 것을 리메이크하려고 노력 할 것이다.See section Makefiles가 다시 만들어지는 과정(How Makefiles Are Remade). makefile을 리메이크하는 방법을 찾으려고 노력한 후에 그것이 실패한 경우에만 make는 makefile이 없는 것이 치명적인 에러라고 진단할 것이다.

make가 존재하지 않고 다시 만들어질 수 없는 makefile을 에러 메시지 없이 무시하도록 하고자 한다면 -include 지시어를 다음과 같이 include대신 사용하라:

-include filenames...

이것은 filenames에 있는 어떤 것이 존재하지 않더라도 에러가 없다는 것(경고조차도 없다)을 제외하고는 모든 면에서 include와 동일하게 작동한다. 다른 어떤 make 구현물들과 호환성을 위해서 -include'에 대한 다른 이름 sinclude이 제공된다.

MAKEFILES 변수(The Variable MAKEFILES)

MAKEFILES 환경변수 이 정의되어 있다면,는 그것의 값을, 다른 것들 이전에 읽어야 하는 추가의 makefile 이름들(공백 문자로 분리된) 리스트로써 생각한다. 이것은 include와 아주 비슷하게 작동한다: 여러 디렉토리들이 그런 파일들에 대해서 검색된다(see section 다른 makefile 삽입(Including Other Makefiles)) 나아가 디폴트 목표는 이런 makefile들 중의 하나로부터 절대 얻어지지 않으며 MAKEFILES에 리스트된 파일들이 없어도 에러가 아니다. If the environment variable MAKEFILES is defined, make

MAKEFILES은 `make'의 재귀적인 호출 사이의 통신에서 주로 사용된다(see section make의 재귀적 사용(Recursive Use of make)). make의 톱-레벨 호출 이전에 이 환경변수를 설정하는 것은 일반적으로 권장되지 않는 것이다. 왜냐면 바깥으로부터 makefile을 혼합하지 않는 것이 일반적으로 더 좋기 때문이다. 그러나 make를 특정 makefile 없이 실행할 때, MAKEFILES에 있는 makefile은 검색 패스를 정의하는 것과 같은(see section 종속물을 위한 디렉토리 검색(Searching Directories for Dependencies))좀 더 잘 작동하는 내장 암시 규칙들을 돕는 유용한 일을 할 수 있다.

어떤 사용자들은 로그인할 때 자동으로 환경변수 안에다 MAKEFILES를 설정하여 프로그램 makefile들이 이렇게 되는 것을 기대하도록 하는 유혹을 받는다. 이것은 아주 나쁜 생각이다. 왜냐면 그런 makefile들은 다른 사람에 의해서 실행된다면 실패할 것이기 때문이다. 명시적인 include디렉티브를 makefile 안에다 쓰는 것이 훨씬 더 좋다. See section 다른 makefile 삽입(Including Other Makefiles).

Makefiles가 다시 만들어지는 과정(How Makefiles Are Remade)

어떤 경우 makefile은 RCS나 SCCS 파일들과 같은 다른 파일들에 의해서 다시 만들어질수 있다. makefile은 다른 파일로부터 다시 만들어질 수 있다면 여러분은 아마도 make가, 읽고 있는 makefile의 최근 버전을 획득하기를 원할 것이다.

이 때문에 모든 makefile들을 읽은 후에 make는 각각의 것을 목표 타겟으로 생각할 것이고 그것을 업데이트하려고 시도할 것이다. makefile이 그것(바로 그 makefile 안에서 아니면 다른 것에서 찾아지는)을 업데이트하는 방법을 말하는 규칙을 가지고 있거나 또는 묵시 규칙이 그것에 적용되는 것이라면(see section 묵시적 규칙(Using Implicit Rules)), (필요하다면) 업데이트될 것이다. 모든 makefile들이 체크된 후에 임의의 것이 실제로 변경되었다면 make는 깨끗한 상태에서 다시 시작해서 모든 makefile들을 다시 읽는다. (그들 각각을 다시 업데이트하려고 시도하겠지만 일반적으로 이것은 그들을 다시 변경하지 않을 것이다. 왜냐면 그들이 이미 업데이트되었기 때문이다.)

makefile들이 명령들은 있지만 종속물들이 없는, 파일을 리메이크할 더블-콜론 규칙을 지정하였다면 그 파일은 항상 다시 만들어질 것이다(see section 더블-콜론 규칙(Double-Colon Rules)). makefile의 이런 경우 명령들은 있지만 종속물들이 없는 더블-콜론을 가진 makefile은 make가 실행할 때마다 다시 만들어질 것이다. 그리고 make가 시작하고 makefile을 다시 읽은 후 반복할 것이다. 이것은 그래서 무한 루프를 발생한다: make는 항상 makefile을 다시 만들것이고 다른 것은 전혀 하지 않을 것이다. 그래서 이것을 피하기 위해서 make는 종속물이 없는 더블-콜론 타켓들로 지정된 makefile들을 다시 만들려고 하지 않을 것이다.

`-f'`--file'옵션들을 사용해서 읽을 makefile을 지정하지 않았다면 make는 디폴트 makefile 이름들을 시도할 것이다; see section 여러분의 Makefile에 줄 이름(What Name to Give Your Makefile). `-f'`--file'옵션들로 명시적으로 요구된 makefile들과는 달리 make는 이런 makefile들이 존재하는지 모른다. 그러나 디폴트 makefile이 존재하지 않지만 make규칙들을 실행함으로써 생성될 수 있다면 여러분은 아마도 그 makefile이 사용될 수 있도록 실행될 규칙들을 원할 것이다.

그러므로 디폴트 makefile들 중 어떤 것도 존재하지 않는다면 make는 하나를 만들 때까지 또는 시도할 이름이 없을 때까지 그들이 검색되는 동일한 순서로 그들 중 하나를 만들려고 노력할 것이다(see section 여러분의 Makefile에 줄 이름(What Name to Give Your Makefile)) make가 makefile을 찾을 수 없거나 만들 수 없다는 것은 에러가 아님을 주목하자; makefile은 언제나 필요한 것은 아니다.

`-t'`--touch'옵션을 사용할 때 (see section 명령 실행 대신에...(Instead of Executing the Commands)),여러분은 어떤 타켓을 touch할 것인가를 결정하기 위해서 날짜가 지난 makefile을 사용하기를 원치 않을 것이다. 그래서 `-t' 옵션은 makefile들을 업데이트하는 효과가 없다; 그들은 실제로 `-t'가 지정되었다 하더라도 업데이트된다. 비슷하게, `-q' (또는 `--question')과 `-n' (또는 `--just-print') 옵션들은 makefile들의 업데이트를 금지하지 못한다. 왜냐면 out-of-date인 makefile은 다른 타겟들에 대해서 잘못된 결과를 낼 것이기 때문이다. 그래서 `make -f mfile -n foo'라고 하면 `mfile'을 업데이트하고 그것을 읽은 후 실행없이, `foo'와 그것의 종속물들을 업데이트하는 명령들을 디스플레이할 것이다. `foo'에 대해서 디스플레이된 명령들은 `mfile'의 업데이트된 내용안에서 지정된 것들이다.

그러나 때때로 여러분은 실제 makefile들의 갱신을 금지하고자 할런지도 모른다. 여러분은 이것을, makefile들을 명령라인에서 goal로 지정하고 동시에 그들을 makefile들로 지정해서, 할 수 있다. makefile 이름이 명시적으로 goal로써 지정될 때 `-t'과 기타 등등이 그것들에 적용된다.

그래서 `make -f mfile -n mfile foo'는 makefile인 `mfile'를 읽고서 실제로 명령들을 실행하지 않고 이것을 업데이트할 명령들을 디스플레이할 것이다. 그리고 나서 `foo'을 업데이트하는 데 필요한 명령들을 실제로는 실행하지 않고 디스플레이할 것이다. `foo'를 위한 명령들은 `mfile'의 현존하는 내용물에 의해서 지정된 것이 될 것이다.

다른 Makefile의 일부를 오버라이딩(Overriding Part of Another Makefile)

때때로 다른 makefile과 거의 대부분 동일한 makefile을 가지는 것이 유용하다. 여러분은 종종 `include' 지시어를 사용해서 다른 makefile안에다 makefile하나를 포함시킬 수 있으며 그래서 더 많은 타겟이나 변수 정의를 포함할 수 있다. 그러나 두 makefile들이 동일한 타겟에 대해서 다른 명령들을 제공한다면 make는 여러분이 이것을 실행하도록 하지 않을 것이다. 그러나 다른 방법이 있다.

담고 있는 makefile(다른 것을 포함하고자 하는 것)안에서 여러분은 담고 있는 makefile에 있는 정보로부터 임의의 타겟을 다시 만들기 위해서 make는 반드시 다른 makefile을 보아야 한다는 것을 말하는 match-anything 패턴 규칙을 사용할 수 있다. 패턴 규칙에 대한 좀 더 많은 정보를 원한다면 See section 패턴 규칙을 정의하고 재정하기(Defining and Redefining Pattern Rules)를 참조.

예를 들어서 타겟 `foo'(그리고 다른 타겟들)을 만드는 방법을 말하는 `Makefile'라고 불리는 makefile을 가지고 있다면 여러분은 다음과 같은 것을 담고 있는 `GNUmakefile'라는 이름의 makefile을 작성할 수 있다:

foo:
        frobnicate > foo

%: force
        @$(MAKE) -f Makefile $@
force: ;

`make foo'라고 하면, make`GNUmakefile'을 찾아서 그것을 읽고, `foo'를 만들기 위해서는 `frobnicate > foo'라는 명령을 실행해야 한다는 것을 알게 될 것이다. `make bar'라고 하면 make`GNUmakefile'에서 `bar'를 만드는 방법을 찾을 수 없을 것이다. 그래서 패턴 규칙으로부터 찾은 명령들을 사용할 것이다: `make -f Makefile bar'. `Makefile'`bar'를 업데이트하는 규칙을 제공한다면 make는 그 규칙을 적용할 것이다. 그리고 비슷하게 `GNUmakefile'가 어떻게 만들것인가를 말하지 않는 다른 타겟들도 이런 것이 적용된다.

이것이 작동하는 방법은 패턴 규칙이 `%'와 같은 패턴을 가지고 있어서 임의의 타겟 어떤 것이든 매치된다는 것이다. 이 규칙은 `force'라는 종속물을 가지고 있도록 지정하고 있으며 이것은 타겟 파일이 이미 존재하더라도 명령들이 실행되도록 보장하기 위한 것이다. 우리는 make`force' 타겟을 빌드하기 위한 묵시적 규칙을 찾지 못하도록 금지하는, 빈 명령들을 주었다---그렇게 하지 않으면 `force' 자신에다 동일한 match-anything 규칙을 적용해서 종속물 루프를 만들것이다.


Go to the first, previous, next, last section, table of contents.