Makefile 작성하기
보통 리눅스에서 프로그램을 작성하다 보면 여러가지 이유로 인해 makefile의 작성을 하게 됩니다.
- 그렇다고 해서 리눅스만의 전유물은 아닙니다. VS의 경우 nmake로 makefile을 지원합니다.
makefile의 규격은 변수와 타겟들로 이루어집니다. 타겟은 다음과 같은 형태를 가집니다.
(타겟이름) : (종속타겟1) … (종속타겟N)
(쉘 명령)
첫째줄에는 이 타겟의 이름을 적고 : 를 적은 뒤, 이 타겟을 처리하기 위해 필요한 종속 타겟들을 명시합니다. 둘째줄에는 종속타겟에 대한 조건이 만족되었을때 처리할 내역을 지정합니다. (이 라인은 쉘이 받아들여 처리합니다.) 주의할 것은 둘째줄 처음의 띄워쓰기는 TAB을 의미합니다. whitespace가 아닙니다. (웹에서 입력하는 특성상 whitespace를 사용했습니다. 실제는 탭을 사용해 주세요.)
예를 들면,
program : sub1.o sub2.o
gcc -o program sub1.o sub2.o
sub1.o :
gcc -c sub1.c
sub2.o :
gcc -c sub2.c
와 같습니다.
쉘에서 make program을 사용하면 program타겟을 만들어 내려고 할 것이며, program은 sub1.o와 sub2.o타겟에 종속성이 있습니다. 따라서, sub1.o와 sub2.o를 처리하고 나서 program타겟을 처리할 것입니다.
흔히 공통적으로 정의하는 타겟은 all과 clean이 있습니다.
all의 경우, 이 makefile에 있는 프로그램들을 전부 컴파일 하기 위해서 만듭니다. 단순히 하나의 프로젝트일 경우, 위에서 설명한 부분중 program타겟의 이름을 all로만 바꾸어도 상관없습니다. 여러개의 프로젝트일경우, all에 program1 program2 같은 형태로 종속타겟을 만들면 됩니다. 이 makefile에 어떤 타겟이 있는지, 그리고 어떤 타겟이 핵심 프로그램인지 직접 열어보고 확인하기 전까지는 알 수 없을것입니다만, 우리는 all이라는 공통 타겟을 하나 만들어줌으로써 그러한 염려를 덜 수 있게 됩니다.
clean의 경우, 이 makefile로 만들어낸 프로그램 혹은 중간 산출물들을 제거하기 위해서 만듭니다. 보통의 경우
clean :
-rm *.o
와 같은 형태가 됩니다. 위의 all과 마찬가지로 이 makefile과 소스코드를 받아든 사람은 이 파일이 어떤것들을 만들어내는지 전부 파악하기 어렵습니다. 따라서 편의를 위해 만들어 줍니다. (물론 자신도 복잡한 작업폴더를 정리하는데 편리할 것입니다.)
makefile은 해당 파일을 처리하는동안 유효한, 매크로를 만들어 낼 수 있습니다.
(매크로이름) = (내역)
CC = gcc
이렇게 만들어진 변수는 $(매크로이름) 이 위치한곳에 치환되게 됩니다. 예를 들어,
CC = gcc
sub1.o :
$(CC) -c sub1.c
와 같은 형태입니다.
이 외에 $* $@ $< $?와 같은 내부 매크로나, 의존성 설정등 복잡한 기능들을 지원합니다.