출처: http://blog.daum.net/english_100/11
7. Makefile의 조건분기
7.1 조건 분기의 예
다음 예는 CC 변수가 'gcc'인지 안닌지에 따라 어떤 라이브러리를 링크할 것인가를 결정하는 조건문 예이다.
libs_for_gcc = -lgnu
normal_libs =
foo : $(objects)
ifeq ($(CC),gcc)
$(CC) -o $(objects) $(libs_for_gcc)
else
$(CC) -o $(objects) $(normal_libs)
endif
이 예에는 ifeq, else, endif 등 세가지 지시자가 쓰였다.
ifeq 지시자는 조건문의 시작으로 조건을 명시한다. 두 인자가 쓰이는데 콤마로 구분되고 소괄호로 싸여있고, 각 인자의 위치에서 변수 치환 및 펼침이 이루어진다. 두 인자가 서로 매치될때 ifeq문이 실행되며 그렇지 않으면 무시된다.
else 지시자는 조건문이 성립되지 않았을 때 실행될 부분을 명기하며 조건문에서 항상 존재할 필요는 없다.
endif 지시자는 조건문의 끝으로서 모든 조건문은 이 지시자로 끝내야 한다.
위 예문은 다음과 같이 기술할 수도 있다.
libs_for_gcc = -lgnu
normal_libs =
ifeq ($(CC),gcc)
libs = $(libs_for_gcc)
else
libs = $(normal_libs)
endif
foo : $(objects)
$(CC) -o foo $(objects) $(libs)
7.2 조건문 문법
else 가 없는 단순 조건문 문법은 다음과 같다 :
conditional-directive
text-if-true
endif
text-if-true 는 조건문이 참일때 수행될 makefile의 어떤 행이든 가능하다. 하진만 조건문이 거짓인 경우 수행될 문장이 존재하지 않는다.
복잡 조건문의 문법은 다음과 같다 :
conditional-directive
text-if-true
else
test-if-false
endif
또는
conditional-directive
text-if-one-is-true
else conditional-directive
test-if-true
else
test-if-false
endif
conditional-directive 은 네가지 형태의 다른 문법을 갖는데 다음과 같다.
ifeq (arg1, arg2)
ifeq 'arg1' 'arg2'
ifeq "arg1" "arg2'
ifeq "arg1" 'arg2'
ifeq 'arg1' "arg2'
ifneq (arg1, arg2)
ifneq 'arg1' 'arg2'
ifneq "arg1" "arg2'
ifneq "arg1" 'arg2'
ifneq 'arg1' "arg2'
ifdef variable-name
ifdef 지시자는 단지 변수가 값을 갖고있는지 아닌지만을 검사하지 펼침값이 빈문자인지 아닌지를 검사하지 않는다. 즉 'foo =' 형태를 제외하고 모든 형태의 변수 정의는 ifdef에 대해 참을 반환한다. 예를 들어 :
bar =
foo = $(bar)
ifdef foo
frobozz =yes
else
frobozz = no
endfi
frobozz의 결과 값은 'yes' 이고
foo =
ifdef foo
frobozz =yes
else
frobozz = no
endif
의 결과는 'no'이다.
ifndef variable-name
변수가 빈문자이면 이 지시자는 참을 반환한다.
조건문 지시자의 앞쪽에는 탭문자를 제외한 모든 공백문자가 무시된다. 하지만 그 뒷부분에서는 탭과 공백문자가 자유로이 이용될 수 있다.
make는 makefile을 읽어들일때 조건문을 평가한다. 그러므로 조건문 검사시에 자동변수를 사용할 수 없다. 왜냐면 그것들은 recipe가 실행되기까지는 정의되지 않기 때문이다.
엄청나게 혼돈스런 사태를 방지하기위해 조건문이 한 makefile에서 시작해서 다른 makefile에서 끝나게 하는 것은 용인되지 않는다. 그러나 조건문안에 include 지시자를 사용하는것은 가능하다.
7.3 명령문 옵션을 검사하는 조건문
MAKEFLAGS 변수와 findstring 함수를 이용해 '-t' 같은 make의 명령행 옵션들을 검사할 수있다. 이는 touch 명령이 파일을 최신 상태로 유지하는데 충분치 않을 때 유용하다. 아카이브 파일을 최신으로 만들기 위해 'ranlib -t'를 어떻게 사용할 것인가를 결정하는 예를 보자 :
archive.a : ...
ifneq (, $(findstring t, $(MAKEFLAGS)))
+touch archive.a
+ranlib -t archive.a
else
ranlib archive.a
endif
'+' 접두문자는 그 recipe를 'recursive'로 지정함으로써 '-t' 플래그가 존재함에도 불구하고 recipe를 실행할 것이다.