makefile Tutorials(2)

Make Rules and Targets

기본 내용은 make 공식 문서(링크)를 참조하여 작성하였습니다.

make는 기본적으로 Makefile 또는 makefile이라는 이름의 파일이 존재해야 합니다. makefile의 구조는

targets : prerequisites
        recipe

이거나

targets : prerequisites ; recipe
        recipe

의 형태입니다.

여기서 각 명칭의 이름은 아래와 같습니다.

  • targets: 빌드 대상 이름입니다. 최종적으로 생성하는 파일명을 작성합니다.
  • prerequisites: Dependency라고 생각하면 됩니다. target을 생성 할 때 의존하는 파일의 목록을 작성합니다. 여기에 나열된 대상을 먼저 컴파일 하고 target을 생성합니다.
  • recipie: 빌드를 실행하는 명령을 작성합니다. 여러 줄로 작성이 가능하고, TAB으로 시작해야만 합니다.

예로 아래와 같이 작성하면 됩니다.

foo.o : foo.c defs.h       # module for twiddling the frobs
        gcc -c -g foo.c

이때 주의해아 할 점이 있습니다. 의존성을 명시적으로 명확하게 작성해야 한다는 겁니다. 예를 들어,

some_program: main.o foo.o bar.o
    gcc -o some_program main.o foo.o bar.o

과 같이 작성하는 경우 정상적으로 컴파일은 되지만 Incremental Build를 위한 의존성 검사에서 파일의 변경을 감지할 수 없습니다. make는 버전 관리 툴인 git과 같이 소스의 변경점을 파악하지 않고 마지막 수정 시간만 확인하기 때문입니다. 따라서 중간 산물인 Object 파일의 의존성까지 같이 작성해주어야 합니다.

some_program: main.o foo.o bar.o
    gcc -o some_program main.o foo.o bar.o

main.o: foo.h bar.h main.c
foo.o: foo.h foo.c
bar.o: bar.h bar.c

마지막의 세 줄은 명렁어 부분이 생략되어 있지만 make 내부 rule에 의해 컴파일이 수행됩니다.

macro

공식 문서에는 make 버전에 따라 variable, 또는 macro 라는 용어를 사용한다고 명시되어 있습니다. 여기서는 macro 라는 용어를 사용하겠습니다.

macro는 쉽게 말해 변수를 선언하는 것입니다. macro 선언과 사용법은 쉘 스크립트와 유사합니다. make 에서도 기본적으로 지원하는 내장 변수(CFLAGS)나 자동 변수($@, $< 등)도 있습니다.

macro 명명 규칙은 대부분 언어에서 지원하는 방식과 동일합니다. 이름에 ‘:’, ‘#’, ‘=’가 들어가면 안되고 case-sensitive 하는 등, 일반적인 규칙을 따라주면 됩니다. 여기서 주의할점은 ‘.’ 로 시작하는 변수명은 future version의 make 에서 특별한 의미를 부여할 수 있다는 점만 기억합시다.

변수명은 다음과 같이 편하게 사용하면 됩니다.

foo = $(bar)
bar = $(ugh)
ugh = Huh?

all:
    echo $(foo)

여기서 $(macro_name)은 해당 변수의 값을 치환합니다.

CFLAGS = $(include_dirs) -O
include_dirs = -Ifoo -Ibar

와 같이 사용도 가능합니다.

내장 변수

make에서 자주 사용하는 내장 변수는 아래와 같습니다.

  • CC: 컴파일러
  • CFLAGS: 컴파일 옵션
  • OBJS: 중간 산물 Object 파일 목록
  • TARGET: 빌드 대상(실행 파일) 이름
  • LDFLAGS: 링커 옵션
  • LDLIBS: 링크 라이브러리

make 내장 변수를 확인하려면 아래와 같은 명령어를 사용합니다.

$ make -p

자동 변수(Automatic Variables)

자동 변수는 context에 맞게 치환됩니다. make에서 지원하는 자동 변수는 아래와 같습니다.

  • $@: 현재 Target 이름
  • $^: 현재 Target이 의존하는 대상들의 전체 목록
  • $?: 현재 Target이 의존하는 대상들 중 변경된 것들의 목록

Substitution Reference

Substitution Reference는 변수 값 치환 기능을 제공합니다. 예를 들어,

foo := a.o b.o l.a c.o
bar := $(foo:.o=.c)

라는 코드가 있을 때 bar 변수는 a.c b.c l.a c. 으로 대체됩니다. Substitution Reference는 patsubst(pattern substitute)의 간략화된 버전입니다. patsubst는 make가 내부적으로 제공하는 함수 중 하나입니다.

make에서 제공하는 자세한 기타 함수는 공식 문서에서 제공합니다.

Substitution Reference(링크)