Makefile Basics
Ref
- https://wiki.kldp.org/KoreanDoc/html/GNU-Make/GNU-Make.html
- https://www.gnu.org/software/make/manual/make.html
컴파일을 할 때, 상황에 따라 옵션을 변경하고, 명령어를 타이핑 하는 일이 쉽지는 않습니다. 시스템이 복잡해지면 복잡해질 수록 의존성을 고려해서 컴파일 순서를 정하는 것에는 한계를 느끼게 됩니다.
매번하는 작업을 최대한 효율적으로 관리하고 실행하기 위해서 Makefile이라는 형식을 사용하고 make라는 명령을 사용합니다.
설치
macOS
xcode command line tools에 포함되어 있습니다.
Linux(debian)
sudo apt install -y make
Windows
Download: http://gnuwin32.sourceforge.net/packages/make.htm
<path>/bin을 환경 변수의 Path에 등록합니다. 별도 수정 없이 설치했다면 C:\Program Files (x86)\GnuWin32\bin입니다.
Makefile
Convention
-
Targets
- 소문자
- 띄어쓰기를 하지 않거나
-
로 대체
-
variables
- 띄어쓰기를 하지 않거나
_
로 대체
- 띄어쓰기를 하지 않거나
Format
기본적인 Makefile의 형식은 아래와 같습니다.
# comment
VAR = VALUE
target1: dependency1
command1
dependency1: dependency2 dependency3
command2
command3
command4
- Macro: 매크로, 반복적으로 사용되는 내용
- Target: 타겟, 하위 명령이 수행되어 나온 결과물
- Dependency: 의존성, Target이 만들어지기 위해 필요한 입력
- Command: 명령어, Target을 만들기 위해 수행되는 명령어
처음에 Macro를 선언합니다. 매크로 선언 중 가장 기본은 A = B입니다.
길어서 줄을 나누고 싶으면 마지막에 \ 를 붙여야합니다. A = B가 선언되어 있다면 **$(A)**는 make가 실행될때 B로 치환되어 실행됩니다.
Dependency는 없어도 되고, 하나 또는 여러개를 가지고 있어도 됩니다. 위의 예처럼 dependency1이 타겟으로 선언된 경우, target1의 결과를 얻기 전에 먼저 dependency1(타겟)이 실행됩니다.
이를 이용하면 순차적인 일을 진행할 수 있습니다. 예를 들어 소스 파일(.c)을 실행 파일(.out)로 만들 때, 중간에 오브젝트 파일(.o)이 만들어진다고 하면 test.c -> test.o -> test.out 순서로 생성되어야 합니다. 이는 아래와 같이 작성될 수 있습니다.
test.out: test.o
gcc -o test.out test.o
test.o: test.c
gcc -Os -c -o test.o test.c
명령어는 Tab으로 시작되어야 합니다. editor를 사용하다보면 자동으로 공백문자로 변환해주는 기능을 사용하는 경우가 있습니다. 그런 경우 탭이 공백문자로 바뀌어서 make 실행시 오류가 발생합니다.
작성된 Makefile을 실행시켜보면 아래와 같은 결과를 얻을 수 있습니다.
$ make
gcc -c -Os -o test.o test.c
gcc -o test.out test.o
Command
make [target] [VAR=VALUE]
target이 없으면 Makefile의 가장 첫번째 target을 실행합니다. 일반적으로 가장 첫번째 target으로 all을 사용합니다.
VAR=VALUE를 추가적으로 정의해서 Makefile을 실행할 수도 있습니다.