김 병 곤
gom1999@hotmail.com
makefile의 구조 및 이용방법
목 차
About Makefile......................................................................................... 3
makefile 의 구조....................................................................................... 4
1) Target Line...................................................................................4
2) Shell Command Line.................................................................... 4
3) Macro Line................................................................................... 5
4) Include Line..................................................................................5
Dependent................................................................................................. 6
make Options............................................................................................ 7
Inference Rules.......................................................................................10
Built-In Targets..................................................................................... 11
Built-In Macros...................................................................................... 12
참고자료...................................................................................................14
- 3 -
AAbboouutt Maakkeeffiillee
프로그램을 Comiple/Link 할 때, 간단한 어플리케이션은 cc와 같은 컴파일러를 직접 써서 컴
파일/링크를 할 수 있지만, 일반적으로 복잡한 어플리케이션을 유지보수하기 위해서는 make 명령
과 makefile을 사용한다.
make는 일련의 프로그램들을 관리/갱신/재생성 하는 데 사용할 수 있는 툴이다. make는
makefile에 지정된 일련의 명령(Batch Job)을 수행해준다.
어플리케이션을 유지/관리하기 위한 복잡한 로직은 makefile에 들어있다. 따라서 유지보수 담
당자는 makefile 안에 구현된 어플리케이션 생성로직을 정확히 이해하고, 필요시 이를 유지보수
할 수 있어야 한다.
- 4 -
maakkeeffiillee 의 구조
11)) TTaarrggeett LLiinnee
작업 대상을 가리킨다. 일련의 명령들이 뒤에 따라온다.
Target Line은 콜론(:) 또는 이중콜론(::)으로 끝나야 하고, Target 명은 공백으로 분리하여
여러이름을 동시에 지정할 수 있다.
즉, 아래는 Target Line 에 Target명으로 clean, del, clear와 같이 3개의 이름이 지정되었으
며, 셸 프롬프트 상에서 make clean 또는 make del, make clear 명령은 모두 똑같이 rm 명
령을 실행하게 된다.
makefile 예)
clean del clear :
rm -f *.obj *.o *.lis
실행 예)
$ make clean
( = make del = make clear )
※ 타겟중에 이미 만들어져 선택적으로 사용할 수 있는 타겟들이 있으며, 이를 Built-In 타겟
이라고 한다. 이는 아래 Built-In Targets 섹션에서 다룬다.
22)) SShheellll Coommaanndd LLiinnee
실제 수행될 작업이 기술된다. 즉, Shell Command가 기술되는 라인을 말한다.
Target Line 다음에 기술되고, 라인의 첫 컬럼은 반드시 Tab문자이어야 한다.
하나의 셸 커맨드가 길어서 여러 라인으로 기술할 때는 라인마지막 컬럼에 백슬래시(\)를 붙
여주어야 한다.
※ Target Line 과 Shell Command Line 을 합쳐서 보통 Rule 이라고 부른다.
Target Line : Target명으로 clean, del, clear 를 정의했다.
콜론(:) 다음에 file이나 매크로가 올 수 있고, 이는 이 타겟을
실행하기 위해서는 지정된 file이나 매크로에 지정된 파일이 존
재해야 함을 나타낸다. 이를 가리켜 dependency 라고 한다.
Shell Command Line : 실제 수행될 작업이 기술된다.
앞에 Tab 문자가 꼭 있어야 한다.
Target 명을 3개를 지정하였고, 각각의 지정된 Target명은 결
국 같은 타겟들이다.
- 5 -
33)) Maaccrroo LLiinnee
C 언어의 define 문과 비슷하다.
등호(=) 를 사용해서 지정되고, 지정된 매크로를 사용할 때는 $(매크로명) 과 같이 사용된다.
makefile 예)
OBJS = file1.o file2.o file3.o
test :
echo $(OBJS:.o=.c)
실행 예)
$ make test
echo file1.c file2.c file3.c
file1.c file2.c file3.c
※ Macro는 커맨드상에서 다음과 같이 지정할 수도 있다.
$ make OBJS=file4.o test
.profile 이나 Shell 상에서의 export 명령 등으로 지정된 환경변수는 makefile안에서 지정되
는 매크로와 같은 역할을 한다. SHELL 변수를 제외한 모든 환경변수는 makefile안에서 재정
의될 수 있다. 단, makefile에서 지정된 매크로는 make명령에서만 유효하고, 일반 Shell 환경
을 변경시키지는 않는다.
44)) IInncclluuddee LLiinnee
makefile 안에 다른 makefile을 포함시킬때 사용한다.
include line은 라인의 첫컬럼에 "include"라는 문자열로 시작된다.
OBJS 매크로를 지정했다.
test Target을 지정했고, 여기서는 echo 명령을 수행하
도록 되어있다. OBJS 매크로의 값을 출력하는데, 그전
에 .o 문자열을 .c 문자열로 치환하도록 하였다.
test Rule을 실행하면, 먼저 명령을 그대로 표시하고,
다음에 실행결과를 표시한다. 매크로는 이미 명령이 표
시될 때부터 적용되었음을 알 수 있다.
- 6 -
DDeeppeennddeenntt
지정된 타겟을 처리하기에 앞서 선행되어 처리되어야할 타겟을 지정하는 것을 Dependent(종속관계)
라고 한다.
makefile 예)
pgm: a.o b.o
cc a.o b.o -o pgm
실행 예)
$ make -n pgm
cc +DA2.0W +DS2.0 -Ac -I. -I/sys0.d/oracle/precomp/public -c a.c
cc +DA2.0W +DS2.0 -Ac -I. -I/sys0.d/oracle/precomp/public -c b.c
cc a.o b.o -o pgm
Dependent 를 반드시 사용해야 하는 것은 아니다. 위의 예를 다음과 같이 Rule을 한번에 정의해도
결과는 마찬가지가 된다.
makefile 예)
pgm:
cc $(CFLAGS) -c a.c
cc $(CFLAGS) -c b.c
cc a.o b.o -o pgm
Dependent 를 사용하는 이유는 일종의 모듈화로 볼 수 있다. *.c 에서 *.o 를 만드는 컴파일 과정
은 보통의 경우에 항상 공통적인 부분이므로 이를 매번 실행파일을 만드는 Rule에 일일이 나열할
게 아니라 .c.o Rule로 따로 빼고 Dependent 만 설정해주면 되는 것이다.
pgm 타겟을 실행하기 위해서는 a.o b.o 가 있어야 한다는
Dependent가 설정되어 있다.
a.o b.o 를 만들기 위한 Rule 이 makefile 안에 별도로 지정
되어 있지 않다면, .c.o Rule이 기본적으로 실행된다. .c.o
는 기본적으로 내장되어 있는 Inference Rule 이다.
-n 옵션을 주어 실제로 실행될 명령들을 디스플레이하였다.
설정된 depedent에 따라 먼저 a.o를 만들기 위해 .c.o Rule
이 실행되어 a.c를 a.o 로 컴파일하고, 두번째로 b.c를 b.o로
컴파일한다. 마지막으로 생성된 a.o 와 b.o 를 가지고 pgm
실행파일을 만들고 있다.
- 7 -
maakkee OOppttiioonnss
make 명령을 실행시 사용할 수 있는 옵션을 설명한다.
-d
make 커맨드를 디버깅하기 위해서 여러가지 디버그 정보를 출력한다.
makefile 에서 정의된 매크로 등의 정보가 출력된다.
-e {매크로}
makefile 내에서 정의된 매크로를 대체한다.
예를 들어 make -e LANG=english .... 은 makefile에서 정의된 LANG 값을 english로
바꿔치기해서 실행한다.
-f {makefile}
지정된 makefile을 사용하도록 한다.
사용예) make -f demo_proc.mk sample1
-i
실행된 커맨드에서 에러가 났어도 무시하고 다음 명령을 계속 실행하도록 한다.
makefile안에 .IGNORE 타겟이 지정되어 있으면 -i 옵션과 같은 역할을 한다.
-n
실행하지 않고 명령을 디스플레이만 한다.
단, 명령앞에 +문자가 붙어있거나 명령라인에 $(MAKE) 문자열을 포함하고 있는 경우
는 이 옵션에 상관없이 실행된다.
-p
전체 매크로 정의와 타겟 정보를 출력한다.
- 8 -
-P
한번에 한 타겟이상을 병렬로 실행한다.
단, 아래와 같이 병렬실행이 가능한 경우에 해당한다.
makefile 예)
OBJS = a.o b.o
pgm: $(OBJS)
cc $(OBJS) -o pgm
a.o: incl.h a.c
cc -c a.c
b.o: incl.h b.c
cc -c b.c
실행 예)
$ export PARALLEL=2
$ make -P pgm
※ Parallel 실행을 방지하고자 하는 경우엔 .MUTEX 타겟을 아래와 같이 지정해주면
된다. 이것은 a.o 와 b.o 를 순차적으로 처리하겠다는 의미이다.
.MUTEX : a.o b.o
-q
현재 make 대상파일이 최신인지 아니면 make를 다시 해야되는 건지 체크한다.
최신이면 0을, 아니면 0이 아닌 값을 리턴한다.
-r
Suffix List를 Clear 하고, 내장된 Rule을 사용하지 않도록 지정한다.
예를 들어, 현재 디렉토리에 test1.c 파일이 있고, make test1 을 실행하면 .c Rule을
makefile에 지정하지 않았어도, 기본적으로 내장된 .c Inference Rule이 실행되어 컴파
일이 되지만, make -r test1 을 실행하면 이 내장된 Rule이 사용하지 않기 때문에 에
러가 난다.
-s
Rule을 실행할 때 command를 보여주지 않고 그냥 실행만 한다.
makefile내에 .SILENT 타겟이 지정되어 있으면 -s 옵션과 같은 역할을 한다.
pgm 타겟을 실행하기 위해서는 $(OBJS) 와 종속관계가
있음을 나타낸다. 따라서 pgm 타겟을 실행하기 전에
a.o 와 b.o 파일이 있는지 체크하고 없으면, 먼저 a.o
와 b.o 타겟을 먼저 실행해서 파일을 만든 다음에 pgm
타겟을 실행한다. 이때 a.o 와 b.o 는 병렬로 진행할
수 있기 때문에 -P를 사용한 것이다.
OBJS 매크로는 pgm 타겟보다 먼저 나와야 한다. 뒤에
나오면 값만 치환하고 만다.
환경변수에 다음과 같이 Parallel 프로세스를 몇개 띄
워서 작업할 것인지를 지정해 주어야 한다.
- 9 -
-S
Rule을 실행중 특정 command에서 에러가 발생하면 거기에서 실행을 중지하도록 지정
한다.
-t
Shell 커멘트상의 touch 명령과 같다.
-u
최신여부에 상관없이 무조건 타겟을 재생성한다.
최신의 타겟을 다시 실행하는 경우 아래와 같은 메시지가 뜨는데, -u 옵션을 써서 무조
건 실행하도록 지정할 수 있다.
$ make test1
`test1' is up to date.
-w
Warning 메세지를 표시하지 않는다. 단, 에러메세지는 이 옵션에 상관없이 계속 출력된
다.
- 10 -
IInnffeerreennccee RRuulleess
Inference Rule (= Implicit Rule) : 첫문자가 도트(.)로 시작하는 타겟을 가진 경우를 말한다.
Target Rule (= Explicit Rule) : 그 외 타겟을 말한다.
Inference Rule 은 실행시 해당 확장자를 가진 파일이 존재하는지 먼저 체크한다.
makefile 예)
.pc:
$(PRC) $(PRCFLAGS) iname=$*.pc
$(CC) $(CFLAGS) -c $*.c
$(LINK) $(CFLAGS) -o $* $*.o $(ORALIBES)
rm -f *.c *.o *.lis
실행 예)
$ make test1
Inference Rule에는 다음과 같이 두가지 Suffix Rule이 있다.
Single Suffix Rules : .c .pc .o 등...
예) .pc : xxx.pc 파일을 찾아서 처리해주는 Rule이다.
Double Suffix Rules : .c.o .pc.c 등...
예) .c.o : xxx.c 파일을 찾아서 xxx.o 를 만들어주는 Rule이다.
※ Inferece Rule 은 디폴트로 이미 정의되어 있는 것들이 많이 있다. 이것들을 보려면
make -p 로 조회해 볼 수 있다.
※ 타겟명앞에 도트(.)만 붙인다고 모든 Inference Rule이 실행되는 것은 아니고, SUFFIXES
에 포함이 되어있어야 한다. 기존 SUFFIXES를 보려면 make -p 로 조회해서 .SUFFIXES
부문을 보면 된다. 여기에 새로운 Inference Rule을 추가하고 싶으면, makefile안에
.SUFFIXES built-in 타겟을 사용하면 된다.
.pc 로 끝나는 파일들을 처리하는 Inferece Rule 이다.
test1.pc 파일이 반드시 존재해야 한다.
test1.pc 파일을 test1 으로 만들어준다.
- 11 -
BBuuiilltt--IInn TTaarrggeettss
타겟들중에는 사용자가 만들어서 사용하는 타겟외에도 이미 만들어져 필요에따라 선택적으로
사용할 수 있는 타겟들이 있다. 이런 타겟들을 Built-In 타겟이라고 부르고, 아래와 같은 것들
이 있다.
.DEFAULT:
말그대로 디폴트 타겟이다.
makefile안에 특별히 지정된 타겟이 없어 적절한 Rule을 찾을 수 없는 경우에 .DEFAULT
타겟이 이용된다.
.PRECIOUS:
QUIT, INTERRUPT, TERMINATE, or HANGUP 등의 시그널을 받았을때, 이 타겟의
Dependent로 설정된 파일들은 지워지지 않도록 한다.
.SILENT:
make option 중의 -s 옵션과 같다.
Rule을 실행할 때 command를 보여주지 않고 그냥 실행만 한다.
.IGNORE:
make option 중의 -i 옵션과 같다.
실행된 커맨드에서 에러가 났어도 무시하고 다음 명령을 계속 실행하도록 한다.
.SUFFIXES:
Inference Rule에 지정된 Dependent들을 추가한다.
예)
.SUFFIXES: .pc .x1
.MUTEX:
make -P 옵션으로 병렬처리를 할때, 여기에 지정된 타겟들은 병렬처리를 하지 않도록 지
정한다.
.pc와 .x1 타겟에 대한 Inference Rule을 사용하겠다는
의미이다. 이와같이 지정해주지 않으면 .pc와 .x1 타겟
에 대한 Inference Rule은 동작하지 않는다.
- 12 -
BBuuiilltt--IInn Maaccrrooss
Rule을 작성할 때 유용하게 사용할 수 있는 내부적인 매크로가 있다.
$@
현재 타겟의 타겟명을 가리킨다.
$%
현재 타겟이 Archive Library 멤버인 경우만 해당된다.
이때, $@는 라이브러리명을 가리키고, $%는 라이브러리내의 오브젝트명을 가리킨다.
$?
현재 타겟에 지정된 dependents 를 가리킨다.
$<
Inference Rule에서만 사용된다.
Inference Rule에서 타겟의 Suffix와 매칭되는 소스파일명을 가리킨다.
$*
$< 에서 Suffix를 제거한 파일명만 가리킨다.
VPATH=path1:path2...
Dependent를 찾기위한 패스를 지정한다.
먼저, 현재 디렉토리를 찾아서 매칭되는 게 없으면 path1, path2 를 차례로 찾는다.
※ 추가로 F 와 D 옵션이 있다. 이들은 위 5개의 매크로들과 함께 쓰이며, F는 파일명을, D는
디렉토리를 각각 의미한다. 예를들어, $(@F)는 현재 타겟명 중에서 파일명만을 가리키고,
$(@D)는 현재 타겟명 중에서 디렉토리명을 가리킨다.
- 13 -
SSiimppllee Maakkeeffiillee
오라클 응용프로그램을 컴파일할 때 사용하는 makefile을 단순화 시켰다.
#
# Variables of ORACLE
#
ORACLE_SID=KCSDB64
ORACLE_HOME=/sys0.d/oracle
NLS_LANG=American_America.KO16KSC5601
ORALIBES=-L/sys0.d/oracle/lib64/ -lclntst8 `cat /sys0.d/oracle/lib64/ldflags` `cat /sys0.d/oracle/lib64/sysliblist`
-lm -lpthread
#
# Oracle Include & Bin directory
#
PROINCDIR=$(ORACLE_HOME)/precomp/public
ORABINDIR=$(ORACLE_HOME)/bin
#
# Precompiler flags & C Compiler flags
#
PRCFLAGS=include=$(PROINCDIR) ireclen=132 oreclen=132 select_error=yes release_cursor=yes hold_cursor=no dbms=v8
CFLAGS=+DA2.0W +DS2.0 -Ac -I. -I$(PROINCDIR)
#
# Precompiler, C compiler, Link program
#
PRC=$(ORABINDIR)/proc
CC=cc
LINK=cc
#
.SUFFIXES: .pc .c .o
#
# Rule for creating server files from source or object files
#
.pc.c:
$(PRC) $(PRCFLAGS) iname=$*.pc
.c.o:
$(CC) $(CFLAGS) -c $*.c
.o:
$(LINK) $(CFLAGS) -o $* $*.o $(ORALIBES)
.pc:
$(PRC) $(PRCFLAGS) iname=$*.pc
$(CC) $(CFLAGS) -c $*.c
$(LINK) $(CFLAGS) -o $* $*.o $(ORALIBES)
rm -f *.c *.o *.lis
.c:
$(CC) $(CFLAGS) -c $*.c
$(LINK) $(CFLAGS) -o $* $*.o $(ORALIBES)
rm -f *.o *.lis
#
# Rule for cleaning out generated files
#
clean del clear:
rm -f *.c *.obj *.o *.lis *.cod *.cud
Oracle Library 를 지정한다.
여기에는 Shared Library와 Static Library가 섞여 있으며,
같은 라이브러리가 중복되어 나와도 한번만 링크된다.
Oracle 접속 환경을 세팅한다.
Pro*C Include 디렉토리와 proc를 찾기위한 패스를 지정한다.
proc 와 cc 컴파일러에서 사용할 옵션들을 각각 지정한다.
proc 는 *.pc 파일을 *.c로 만들어주는 Pre-Compiler 이다.
cc 는 *.c 파일을 Compile/Link 하여 실행파일을 만들어준다.
Double Suffix Rule 이다.
.pc 파일을 찾아서 .c로 만들어주는 Rule 이다.
그러나 아래 .pc Rule 에서 dependent를 사용하지 않고
바로 .pc에서부터 실행파일까지 한번에 만들도록 되어있기
때문에 실제로 여기서는 사용되지 않는다.
Single Suffix Rule 이다.
.pc 파일을 찾아서 실행파일을 만들어주는 Rule 이다.
다음과 같이 실행되도록 되어있다.
프리컴파일(proc) -> 컴파일(cc) -> 링크(cc) -> 임시파일
삭제
$ make clean 명령으로 임시파일들을 모두 삭제해준다.
clean 대신 del 이나 clear 로 쓸 수 있다.
SUFFIXES 를 지정한다.
지정된 Inference Rule이 실행가능하도록 지정하는 역할을
한다. .c.o는 기본적으로 지정되어 있으므로 따로 지정할
필요가 없지만 .pc.c 는 여기에 지정되지 않으면 사용할
수 없다.
- 14 -
참고자료
♨ HP Online Manual ( http://docs.hp.com )