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๋ผ๋ ๋ช ๋ น์ ์ฌ์ฉํฉ๋๋ค.
#
Installation#
macOSxcode command line tools์ ํฌํจ๋์ด ์์ต๋๋ค.
#
Linux(debian)#
WindowsDownload: http://gnuwin32.sourceforge.net/packages/make.htm
<path>/bin์ ํ๊ฒฝ ๋ณ์์ Path์ ๋ฑ๋กํฉ๋๋ค. ๋ณ๋ ์์ ์์ด ์ค์นํ๋ค๋ฉด C:\Program Files (x86)\GnuWin32\bin์ ๋๋ค.
#
Makefile#
Format๊ธฐ๋ณธ์ ์ธ Makefile์ ํ์์ ์๋์ ๊ฐ์ต๋๋ค.
- 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 ์์๋ก ์์ฑ๋์ด์ผ ํฉ๋๋ค. ์ด๋ ์๋์ ๊ฐ์ด ์์ฑ๋ ์ ์์ต๋๋ค.
caution
๋ช ๋ น์ด๋ Tab์ผ๋ก ์์๋์ด์ผ ํฉ๋๋ค. editor๋ฅผ ์ฌ์ฉํ๋ค๋ณด๋ฉด ์๋์ผ๋ก ๊ณต๋ฐฑ๋ฌธ์๋ก ๋ณํํด์ฃผ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ๊ทธ๋ฐ ๊ฒฝ์ฐ ํญ์ด ๊ณต๋ฐฑ๋ฌธ์๋ก ๋ฐ๋์ด์ make ์คํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
์์ฑ๋ Makefile์ ์คํ์์ผ๋ณด๋ฉด ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
#
Commandtarget์ด ์์ผ๋ฉด Makefile์ ๊ฐ์ฅ ์ฒซ๋ฒ์งธ target์ ์คํํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๊ฐ์ฅ ์ฒซ๋ฒ์งธ target์ผ๋ก all์ ์ฌ์ฉํฉ๋๋ค.
VAR=VALUE๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ์ ์ํด์ Makefile์ ์คํํ ์๋ ์์ต๋๋ค.
#
Automatic Variables(์๋ ๋ณ์)$@
: ํ๊ฒ$<
: ์ฒซ ๋ฒ์งธ ์์กด์ฑ$?
: ์์ ๋ ์์กด์ฑ$^
: ๋ชจ๋ ์์กด์ฑ$*
: ์ ๋ฏธ์ด๋ฅผ ์ ๊ฑฐํ ํ๊ฒ ๋ช (์ธ์๋ ์ ๋ฏธ์ด๊ฐ ์๋๊ฒฝ์ฐ ๊ณต๋ฐฑ ๋ฌธ์๋ก ์ฒ๋ฆฌ๋จ)
์๋ ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ Makefile์ ์์ ํ๋ฉด ์๋์ ๊ฐ์ด ์์ ํ ์ ์์ต๋๋ค.
$
์ ์ฌ์ฉ๋ฐฉ๋ฒ์ ์ ํํ ์์ง ๋ชปํ๋ค๋ฉด ์ฌ์ฉ์ ํผํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
#
Pre-defined Macro์๋ ๋ช ๋ น์ด๋ฅผ ํตํด Pre-defined Macro๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
- CC: ์ปดํ์ผ๋ฌ, ๊ธฐ๋ณธ์ ์ผ๋ก CC=cc, ์ํฉ์ ๋ฐ๋ผ ์ค๋ฒ๋ผ์ด๋ฉํ์ฌ ์ฌ์ฉ
- CFLAGS: ์ปดํ์ผ ์ต์ , ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์๋ ์๋์ด ์์ง๋ง ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉ
- LDFLAGS: ๋ง์ปค ์ต์ , ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์๋ ์๋์ด ์์ง๋ง ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉ
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
๋ ๋ด๋ถ์ ์ผ๋ก ์ ์๋์ด ์์ต๋๋ค. CC๋ฅผ ์ ์ธํ ๋๋จธ์ง ๋งคํฌ๋ก๋ ๋ด๋ถ์ ์ผ๋ก ์ ์๋์ด ์์ง ์์์ ์ค์ ๋งคํฌ๋ก๊ฐ ์ ์ฉ๋ ๋๋ COMPILE.c = $(CC) -c
๋ก ์ ์ฉ๋ฉ๋๋ค.
์ฌ์ฉ์๊ฐ CFLAGS๋ฅผ ์ ์ํ๋ฉด COMPILE.c = $(CC) $(CFLAGS) -c
๊ฐ ์ ์ฉ ๋ฉ๋๋ค.
๋งคํฌ๋ก์ ๋ด๋ถ ๋งคํฌ๋ก๋ฅผ ์ฌ์ฉํ์ฌ Makefile์ ์์ ํ๋ฉด ์๋์ ๊ฐ์ด ์์ ํ ์ ์์ต๋๋ค.
๋ง์ง๋ง test.o: test.c
๋ ๋ด๋ถ์ ์ผ๋ก .c.o๊ฐ ์๋์ ๊ฐ์ด ์ ์๋์ด ์๊ธฐ ๋๋ฌธ์ command๊ฐ ์์ด๋ ๋ฉ๋๋ค.
#
clean์ปดํ์ผ ๊ณผ์ ์์ ์๊ธฐ๋ ํ์ผ์ ๊ฒฝ์ฐ ์ง์์ผ ํ๋ ๊ฒฝ์ฐ๋ ์์ต๋๋ค. ์ฃผ๋ก clean์ด๋ผ๋ ํ๊ฒ์ ๋ง๋ค์ด ์๋์ ๊ฐ์ด ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
.PHONY ํ๊ฒ์ ์์กด์ฑ์ผ๋ก clean์ ์ค์ ํ๋ฉด, ์ค์ ํ์ผ์ ์ ๋ฌด๋ ๋ณ๊ฒฝ๊ณผ ๊ด๊ณ์์ด clean ํ๊ฒ์ ์ปค๋งจ๋๋ฅผ ํญ์ ์คํ์ํฌ ์ ์์ต๋๋ค.
#
Pattern Rules(ํจํด)%
๋ฅผ ์ฌ์ฉํ๋ฉด Makefile๊ณผ ๊ฐ์ ํด๋์ ์๋ ํ์ผ ์ค ํจํด์ด ์๋ ๋ด์ฉ์ ์ฝ๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
ํจํด์ ์ฌ์ฉํ์ฌ Makefile์ ์์ ํ๋ฉด ์๋์ ๊ฐ์ด ์์ ํ ์ ์์ต๋๋ค.
#
vpathvpath pattern directories
: %.c, %.h ๋ฑ์ pattern์ ์ฐพ๊ธฐ ์ํ directories๋ฅผ ์ค์ vpath pattern
: pattern์ ์ฐพ๊ธฐ ์ํ directories ๋ชฉ๋ก์ ๋น์vpath
: ๋ชจ๋ directories ๋ชฉ๋ก์ ๋น์
์ฌ๋ฌ ํด๋์ ์๋ ํ์ผ ์ค ํจํด์ด ์๋ ๋ด์ฉ์ ์ฝ๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
vpath๋ฅผ ์ฌ์ฉํ์ฌ Makefile์ ์์ ํ๋ฉด ์๋์ ๊ฐ์ด ์์ ํ ์ ์์ต๋๋ค.
#
Functionx...์ ๋์ด์ฐ๊ธฐ๋ก ๊ตฌ๋ถํ์ฌ ๋์ด๋ ์ฌ๋ฌ ๊ฐ์ x๋ฅผ ์๋ฏธํฉ๋๋ค. ํจ์์ ๊ฒฐ๊ณผ๊ฐ ์ฌ๋ฌ ๊ฐ์ธ ๊ฒฝ์ฐ์๋ ๋์ด์ฐ๊ธฐ๋ก ๊ตฌ๋ถ๋์ด ๋์ด๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด x...์ x1 x2 x3๊ฐ ๋ ์ ์์ต๋๋ค.
#
wildcard$(wildcard pattern...)
๋ Makefile๊ณผ ๊ฐ์ ํด๋์ ์๋ ํ์ผ ์ค pattern๋ค์ ํด๋นํ๋ ํ์ผ ๋ช
์ ๋์ดํฉ๋๋ค.
wildcard๋ฅผ ์ฌ์ฉํ ๋, ํจํด์ผ๋ก %.c๊ฐ ์๋๋ผ *.c๋ฅผ ์ฌ์ฉํฉ๋๋ค.
ํจ์๋ฅผ ์ฌ์ฉํ์ฌ Makefile์ ์์ ํ๋ฉด ์๋์ ๊ฐ์ด ์์ ํ ์ ์์ต๋๋ค.
(ํด๋์ main.o, foo.o, bar.o ๊ฐ ์๋ ๊ฒฝ์ฐ์ ๋๋ค.)
#
(pat)subst$(subst from,to,text)
: text์์ from์ ์ฐพ์ to๋ก ๋ฐ๊ฟ๋๋ค.$(patsubst pattern,replacement,text)
: text์์ pattern์ ์ฐพ์ replacement๋ก ๋ฐ๊ฟ๋๋ค.$(Macro:pattern=replacement)
==$(patsubst pattern,replacement,$(Macro))
ํจ์๋ฅผ ์ฌ์ฉํ์ฌ Makefile์ ์์ ํ๋ฉด ์๋์ ๊ฐ์ด ์์ ํ ์ ์์ต๋๋ค.
(ํด๋์ main.c, foo.c, bar.c ๊ฐ ์๋ ๊ฒฝ์ฐ์ ๋๋ค.)
#
add suffix,prefix$(addsuffix suffix,namesโฆ)
$(addprefix prefix,namesโฆ)
ํจ์๋ฅผ ์ฌ์ฉํ์ฌ Makefile์ ์์ ํ๋ฉด ์๋์ ๊ฐ์ด ์์ ํ ์ ์์ต๋๋ค.
(ํด๋์ main.c, foo.c, bar.c ๊ฐ ์๋ ๊ฒฝ์ฐ์ ๋๋ค.)
#
foreach$(foreach var,list,text)
๋ list์ ์์๋ฅผ ์์ฐจ์ ์ผ๋ก ๋ณ์ var์ ํ ๋นํ์ฌ text๋ฅผ ๋ฐ๋ณตํ๋ ํจ์์
๋๋ค.
ํจ์๋ฅผ ์ฌ์ฉํ์ฌ Makefile์ ์์ ํ๋ฉด ์๋์ ๊ฐ์ด ์์ ํ ์ ์์ต๋๋ค.
(ํด๋์ main.c, foo.c, bar.c ๊ฐ ์๋ ๊ฒฝ์ฐ์ ๋๋ค.)
#
call macromacro = $(1) $(2) ...
: call ํจ์๋ฅผ ํตํด ๋ถ๋ฅผ ์ ์๋ macro ์ ๋๋ค. $(1)์ด param1์ ๋๋ค.define macro = $(1) ... endif
: ์ฌ๋ฌ ์ค์ ๊ฑธ์ณ macro๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.$(call macro,param1,param2,...)
$(eval macro)
: macro๋ฅผ ๋ฏธ๋ฆฌ ํ์ธํ๊ณ Makefile์ ๊ตฌ๋ฌธ์ผ๋ก ์ ์ํ์ฌ ํด๋น ๊ฒฐ๊ณผ๊ฐ makefile์ ์ฝ๋๋ก ๋ถ์๋๊ฒ ๋ง๋ญ๋๋ค.
callํจ์๋ ๋งคํฌ๋ก์ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํ์ฌ ๋ถ๋ถ๋ง ๋ฐ๊ฟ์ ์ธ ์ ์๊ฒ ํด์ค๋๋ค.
macro์ call์ ์ฌ์ฉํ์ฌ ๋๋ ํ ๋ฆฌ์ ํ์ ํญ๋ชฉ์ ๋ชจ๋ ์ฐพ์ ์ ์๋ recursive ํจ์๋ฅผ ์๋์ ๊ฐ์ด ๋ง๋ค ์ ์์ต๋๋ค.
call์ ๋จ์ํ macro๋ฅผ ํธ์ถํ๊ณ ๋ณ์์ ๊ฐ์ ํ์ฅ์์ผ์ฃผ๋ ํจ์์ ๋๋ค. ๋ฐ๋ผ์ tab์ด ์์ด๋ makefile์ด ์ธ์์ ํ์ง ๋ชปํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์๋์ ๊ฒฝ์ฐ ๊ฐ์ Makefile์ด๊ธฐ ๋๋ฌธ์ ์๋ํ์ง ์์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
evalํจ์๋ macro๋ฅผ ๋ฏธ๋ฆฌ ํ์ธํ๊ณ makefile์ ๊ตฌ๋ฌธ์ผ๋ก ์ ์ํด ์ค๋๋ค.
์์ ์๋ฅผ evalํจ์๋ก ๋ค์ ํํํ๋ฉด ์๋ํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
caution
evalํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ด๋ถ์ ์๋ ๋ณ์๋ฅผ ์ฌ์ฉํ ๋ $
๋ฅผ ํ๋ฒ ๋ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ($$@
, $$<
๋ฑ) evalํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ด๋ถ ๋ด์ฉ์ด evalํจ์์ Makefile์ ์ํด 2๋ฒ ํ์ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ $@
->๊ณต๋ฐฑ->๊ณต๋ฐฑ, $$@
->$@
->target์ด ๋ฉ๋๋ค.