4. variable and macros
Program Lang./Makefile 2013. 5. 9. 09:011. Variables (변수)
makefile에서 사용자 변수를 지정할 수도 있고 환경변수나 make 내부 변수를 사용할 수 있다.
1.1. 변수 사용 규칙
makefile은 대소문자를 구분한다. 일반적으로 환경변수나 make 내부 변수를 재정의하고자 할 경우에는
대문자를 사용한다. makefile 내에 사용자 정의 변수를 선언하고자 하는 경우에는 소문자를 사용하는 것이 일반적이다.
CC := gcc
MKDIR := mkdir -p
#internal variable 정의
source = *.c
objects = $(subst .c,.o,$(source))
1.2. 변수 유형 (Variable Types)
변수의 유형은 크게 simply expanded와 recursively expanded 변수로 분류한다.
- simply expaned variable (:=)
- := 할당자를 사용한다. 할당자 오른쪽 내용은 해당 라인을 읽음과 동시에 확장된다.
- recursively expanded variable (=)
- = 할당자를 사용한다. 할당자 오른쪽에 정의된 내용은 실제 변수가 사용되기 전까지 확장을 연기한다.
MAKE_DEPEND := $(CC) -M # simply expanded variable
MAKE_DEPEND = $(CC) -M # recursively expanded variable
위의 예제에서 simply expaned 변수에서 CC가 정의되지 않을 경우, MAKDE_DEPEND는 <space> -M으로 확장한다.
space는 아무 데이터가 없다는 뜻이다. 하지만 recursively expanded 변수에서는 변수를 읽을 당시에는 선언되지
않았더라도 변수를 실제 사용하기 전에 선언되었다면 정상적으로 gcc -M으로 확장할 것이다.
추가적으로 변수를 할당하는 방식에 따라 두 가지 할당 방식이 있다.
- conditional variable assignment operator (?=)
- 왼쪽 변수에 초기값이 설정되어 있지 않을 경우에만 오른쪽에 할당된 값을 할당한다.
- append assigment operator (+=)
- 이 할당자는 기존 할당내용에 추가적으로 내용을 할당한다
2. 매크로 (Macro)
변수가 한라인 정의를 하는 구조라면 매크로는 여러줄로 명령어나 해야할 일을 정의할 수 있다.
매크로의 시작은 define이라는 지정자를 통해서 이루어진다. 자세한 내용은 생략하고 사용예만
소개하고 마무리한다.
define free-space
$(PRINTF) "Free disk space"
$(DF) . | $(AWK) 'NR == 2 {print $$4}'
endef # end of define 매크로 정의
3. 변수 및 매크로 확장 규칙
위에서 변수의 유형과 할당 방식에 따라서 확장 규칙이 다양하다. 언제 변수와 매크로 또는 지시자들이 확장되는지를
요약한다.
make는 두번에 걸쳐서 makefile을 스캔한다. 첫번째는 변수와 매크로 또는 include 지시에 명시된 makefile에 대해서
모든 변수와 매크로를 make 내부적으로 데이터베이스화하고 저장한다.
두번째 스캔에서는 실제 업데이트되어야 할 Target과 Prerequisite를 확인하고 command를 수행한다.
아래 표는 변수 및 매크로가 언제 확장되거나 확장을 지연하는지에 대해서 요약하였다.
또한 예제를 통해서 이를 확인해 본다.
Definition |
Expansion of a |
Expansion of b |
a = b |
Immediate |
Deferred (recursively expanded variable) |
a ?= b |
Immediate |
Deferred |
a := b |
Immediate |
Deferred |
a += b |
Immediate |
Deferred or Immediate |
define a |
Immediate |
Deferred |
b... |
|
Deferred |
b... |
|
Deferred |
b... |
|
Deferred |
endef |
|
Deferred |
BIN, PRINTF, DF와 AWK의 정의가 뒤에 나오지만 Makefile을 실행하면 정상적으로 동작한다.
이는 매크로가 실제 사용될 때까지 모든 변수에 대한 정의는 연기되고 실제 사용될 때 확장되기 때문이다.
각 변수는 simply expanded로 구성되어 있는데 recursively expanded 변수로 정의해도 동작은 정상적이다.
#***********************************************************************# # ---------------------------------------------------------------------- # Copyright(c) 2012-2013 by hee-soon kim # # All rights are reserved # # ----------------------------------------------------------------------# # # FILE NAME : Makefile # VERSION : 1.0 # AUTHOR : heesoon,kim(김희순), chipmaker.tistory.com) # DATE : 2012/12/21 # #***********************************************************************# OUTPUT_DIR := /tmp $(OUTPUT_DIR)/very_big_file: $(free-space) define free-space $(PRINTF) "Free disk space" $(DF) . | $(AWK) 'NR == 2 {print $$4}' endef BIN := /usr/bin PRINTF := $(BIN)/printf DF := $(BIN)/df AWK := $(BIN)/awk
4. Target Specific Variable
변수의 효력이 특정 타겟에만 유효하도록 지정하고 싶을 경우에 사용하는 방식이다.
예제를 통해서 알아본다. 아래 코드를 보면 어떤식으로 정의하는지 이해할 수 있을 것이다.
$(COMPILE.c) -DUSE_NEW_MALLOC=1 $(OUTPUT_OPTION) $<
[Target Specific Variable]로 변경
gui.o: CPPFLAGS += -DUSE_NEW_MALLOC=1
gui.o : gui.h
$(COMPILE.c) $(OUTPUT_OPTION) $<
5. 변수의 정의는 어디서 가능한가?
- File
- makefile 내에서 아니면 include 지시자에 의해 포함된 다른 makefile로부터 가능하다.
- Command Line
- make를 실행하는 쉘명령어 프롬프트상에서 가능하며 여기서 지정한 값은 기존 파일에서 지정한 값을
override한다. 이를 금하고 싶으면 override 지시자를 변수앞에 지정한다.
- Enviroment
- 쉘의 환경변수를 변수로 사용할 수 있으며, 다른 것으로 선언할 수 있다.
6. export or unexport 지시자
현재 makefile에서 선언된 변수를 다른 makefile에서도 사용가능하도록 하고자할 때 많이 사용한다.
이 지시자는 export로 지정한 변수를 환경변수에 등록하여 모든 makefile에서 참조하도록 할 수 있다.
중요한 내용이고 makefile은 단순한 구조를 갖는 것이 아니고 tree 구조의 복잡한 구조를 가질 수 있다.
이 때 export의 사용은 매우 유용하다.
7. Automatic Variables
내부적으로 정의되어 command script에서 Target이나 Prerequisite에 대한 기술을 반복하는 것을
쉽게 해당 변수로 대체할 수 있다.
Variable |
설명 |
$@ |
Target을 나타내는 파일 이름 |
$% |
현재 Target이 라이블러리 일때, .o파일에 대응하는 이름, gnu makefile에서는 사용하지 않음 |
$< |
첫번째 Prerequisite (확장자 규칙에서 사용가능) |
$? |
현재 Target보다 최근에 변경된 Prerequisite List를 정의 (확장자 규칙에서 사용불가) |
$^ |
모든 Prerequisite에 대한 목록 (중복 목록을 출력할 수 있다, 확장자 규칙에서 사용불가) |
$+ |
$^과 유사하다. 중복을 출력하지 않는다. |
$* |
Target 파일이름에서 확장자를 제외한 파일이름을 표시 |
8. Standard make Variables
make는 자신의 상태를 관리하거나 보여주기위해서 아래와 같은 표준 변수를 내부적으로 관리한다.
몇가지 변수는 큰 makefile를 만들 때 유용하다.
Variables |
설명 |
MAKE_VERSION |
make의 버전정보를 가지고 있다. |
CURDIR |
현재 작업 디렉토리 표시 (--directory (-C) 옵션을 사용하지 않을 경우) |
MAKEFILE_LIST |
make가 빌드를 위해 읽은 makefile list 표시 |
MAKECMDGOALS |
command line상에서 지정한 target를 표시 |
.VARIABLES |
makefile을 읽는 동안 정의된 변수 목록을 출력 |
'Program Lang. > Makefile' 카테고리의 다른 글
1. basic makefile structure syntax (0) | 2013.05.11 |
---|---|
3. VPATH(vpath), conditional and include 지시자 (0) | 2013.05.09 |
9. makefile structure for large project (0) | 2012.12.27 |
7. Automatic Dependency Generation (0) | 2012.12.26 |
2. Wildcard, Phony Target, Empty Target Usage (0) | 2012.12.08 |