본문 바로가기

메모장/리눅스

[Linux] Make 와 Makefile, Makefile 만들기

리눅스 쉘 환경에서 코딩을 하다보면 make 명령어를 이용하여 컴파일을 하는 경우가 많으실 겁니다.
makefile만 만들어 놓으면 귀찮은 컴파일 과정을 명령어 하나로 실행할 수 있기 때문인데, 어떻게 이게 가능할 까요?
make와 makefile에 대해서 알아보겠습니다.

1. Make란 무엇인가?

  • make 명령어는 Unix/Linux 시스템에 포함되어 있는 명령어. (Windows에도 make라는 똑같은 기능의 명령어가 있습니다.)
  • makefile이라는 파일을 참조하여 컴파일러에 명령을 전달하며, makefile에 기술된 Shell명령어들이 순차적으로 실행될 수 있게 한다.
  • 파일관리 유틸리티 소프트웨어이다.

make명령어는 makefile(기술파일)에 프로그래머 또는 사용자가 기술해 놓은 명령어를 컴파일러에게 순차적으로 실행하도록 명령합니다.
따라서 gcc 명령어등의 컴파일러 명령어를 makefile에 기술해 놓으면 우리는 make명령어만 사용해서 여러단계의 컴파일 과정을 한번에 진행할 수 있게 됩니다.

 

2. Makefile은 무엇인가?

  • Make 명령어로 실행할 명령들을 기술해 놓은 파일.
  • 목적파일과 재료파일, 명령어와 매크로가 기술되어 있다.

위에서도 언급했듯이 makefile을 make명령어가 컴파일러에 어떤 명령을 보낼 것인가에 대한 내용이 담겨있는 파일입니다.
makefile에 무엇을 기술하느냐에 따라서 make 명령어는 컴파일을 할 수도 파일이나 폴더를 생성할 수도, 지울 수도 있습니다.

 

3. Makefile의 구조

make 파일의 기본 구조입니다.

-목적파일(Target) : 명령어가 수행되어 나온 결과를 저장할 파일 

-의존성(Dependency) : 목적파일을 만들기 위해 필요한 재료 

-명령어(Command) : 실행 되어야 할 명령어들 

-매크로(macro) : 코드를 단순화 시키기 위한 방법

 

1. 매크로 정의 (변수 정의)

CC = gcc

매크로를 참조 할 때는 소괄호나 중괄호를 둘러써고 앞에 '$'를 붙입니다.
위 구문에 의해서 해당 makefile내부의 "$(CC)"라는 문자열은 gcc 명령어를 뜻하게 됩니다.
매크로는 반드시 치환 위치보다 먼저 선언되어야 합니다.

사용자가 정의한 매크로 이외에도 make에서 지원하는 내부매크로(자동 변수) 도 존재합니다.

  • $@ : 현재 타겟의 이름
  • $* : 현재 타겟의 이름에서 확장자만 제거
  • $^ : 현재 타겟의 종속 항목의 리스트 (현제 타겟이 의존하는 파일들)
  • $? : 현재 타겟의 종속 항목중 변경된 것들의 목록
  • $< : 의존 파일중 첫 번째 파일

더 많은 자동 변수들은 아래 링크에서 확인 가능합니다.

www.gnu.org/software/make/manual/html_node/Automatic-Variables.html
 

Automatic Variables (GNU make)

The names of all the prerequisites, with spaces between them. For prerequisites which are archive members, only the named member is used (see Archives). A target has only one prerequisite on each other file it depends on, no matter how many times each file

www.gnu.org

 

 

2.타겟절

target1 : dependency1 dependency2
	command1
	command2

위 구문에서 target1은 해당 절의 이름을 나타냅니다.
후에 make명령어를 실행시킬 때, 'make target1' 를 실행시킨다면, 해당 절의 명령어들이 실행됩니다.

dependency1, dependency2는 target1을 실행하는데 필요한 재료파일들 입니다. target1을 실행시키는데 필수 불가결한 파일들로, 해당 디렉토리에서 그 파일들을 찾을 수 없다면 make 명령어는 자동으로 makefile 내부에서 목적파일로 dependency1, dependency2를 생성시키는 명령어를 찾아 수행합니다.

command1, command2는 명령어 입니다. 'make target1' 명령어를 실행시키면, 컴파일러는 comman1, command2를 순차적으로 실행시킵니다.

 

3. 예시

CC = gcc

prog : main.o foo.o
	&(CC) -o $@ main.o foo.o
// $ make prog
// == gcc -o prog main.o foo.o

%.o : %.c
	&(CC) -c -o $@ ${CFLAG} $<
// $ make CFLAG="-g"
// $ make myProg.o
// == gcc -c -o myProg.o -g myProg.c

clean :
	rm -f prog main.o foo.o

위 처럼 작성한 후 파일 이름을 makefile로 저장합니다.

%는 인풋값에 따라 달라집니다. 만약 input으로 'main.o'가 주어진다면 %는 .o를 뺀 'main'이 됩니다.

이제 main.c와 foo.c를 작성한후 Shell에 "make prog" 명령어를 치면 'prog', 'main.o', 'foo.o' 파일이 생성됩니다.

 

4. 정리

make 명령어를 사용하는 경우 다음과 같은 장점이 있습니다.

  • 일일이 명령어를 치지 않고도 여려줄의 명령어를 실행시킬 수 있음. (대표적으로 컴파일 gcc명령어)
  • 파일들의 관계를 쉽게 파악할 수 있음.
  • 입력된 명령어를 자동으로 실행시켜주므로 오타로 인한 실수를 줄여줌