Makefile Basics

Ref

์ปดํŒŒ์ผ์„ ํ•  ๋•Œ, ์ƒํ™ฉ์— ๋”ฐ๋ผ ์˜ต์…˜์„ ๋ณ€๊ฒฝํ•˜๊ณ , ๋ช…๋ น์–ด๋ฅผ ํƒ€์ดํ•‘ ํ•˜๋Š” ์ผ์ด ์‰ฝ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ์ด ๋ณต์žกํ•ด์ง€๋ฉด ๋ณต์žกํ•ด์งˆ ์ˆ˜๋ก ์˜์กด์„ฑ์„ ๊ณ ๋ คํ•ด์„œ ์ปดํŒŒ์ผ ์ˆœ์„œ๋ฅผ ์ •ํ•˜๋Š” ๊ฒƒ์—๋Š” ํ•œ๊ณ„๋ฅผ ๋Š๋ผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋งค๋ฒˆํ•˜๋Š” ์ž‘์—…์„ ์ตœ๋Œ€ํ•œ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ Makefile์ด๋ผ๋Š” ํ˜•์‹์„ ์‚ฌ์šฉํ•˜๊ณ  make๋ผ๋Š” ๋ช…๋ น์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Installation

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

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
caution

๋ช…๋ น์–ด๋Š” 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์„ ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Automatic Variables(์ž๋™ ๋ณ€์ˆ˜)

  • $@: ํƒ€๊ฒŸ
  • $<: ์ฒซ ๋ฒˆ์งธ ์˜์กด์„ฑ
  • $?: ์ˆ˜์ •๋œ ์˜์กด์„ฑ
  • $^: ๋ชจ๋“  ์˜์กด์„ฑ
  • $*: ์ ‘๋ฏธ์–ด๋ฅผ ์ œ๊ฑฐํ•œ ํƒ€๊ฒŸ ๋ช…(์ธ์‹๋œ ์ ‘๋ฏธ์–ด๊ฐ€ ์•„๋‹Œ๊ฒฝ์šฐ ๊ณต๋ฐฑ ๋ฌธ์ž๋กœ ์ฒ˜๋ฆฌ๋จ)

์ž๋™ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Makefile์„ ์ˆ˜์ •ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

test.out: test.o
gcc -o test.out test.o
test.out: test.o
gcc -o $@ $^

$์˜ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์„ ์ •ํ™•ํžˆ ์•Œ์ง€ ๋ชปํ•œ๋‹ค๋ฉด ์‚ฌ์šฉ์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Pre-defined Macro

์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด Pre-defined Macro๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

make -p | vim -
  • 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.out: test.o
gcc -o $@ $^
test.o: test.c
gcc -c -Os -o $@ $^
CC = gcc
CFLAGS = -Os
LDFLAGS =
test.out: test.o
$(CC) $(LDFLAGS) -o $@ $^
test.o: test.c

๋งˆ์ง€๋ง‰ test.o: test.c๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ .c.o๊ฐ€ ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์˜๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— command๊ฐ€ ์—†์–ด๋„ ๋ฉ๋‹ˆ๋‹ค.

COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
OUTPUT_OPTION = -o $@
.c.o:
$(COMPILE.c) $(OUTPUT_OPTION) $<

clean

์ปดํŒŒ์ผ ๊ณผ์ •์—์„œ ์ƒ๊ธฐ๋Š” ํŒŒ์ผ์˜ ๊ฒฝ์šฐ ์ง€์›Œ์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ๋กœ clean์ด๋ผ๋Š” ํƒ€๊ฒŸ์„ ๋งŒ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

.PHONY: clean
clean: ; rm -f test.o test.out

.PHONY ํƒ€๊ฒŸ์˜ ์˜์กด์„ฑ์œผ๋กœ clean์„ ์„ค์ •ํ•˜๋ฉด, ์‹ค์ œ ํŒŒ์ผ์˜ ์œ ๋ฌด๋‚˜ ๋ณ€๊ฒฝ๊ณผ ๊ด€๊ณ„์—†์ด clean ํƒ€๊ฒŸ์˜ ์ปค๋งจ๋“œ๋ฅผ ํ•ญ์ƒ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Pattern Rules(ํŒจํ„ด)

%๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Makefile๊ณผ ๊ฐ™์€ ํด๋”์— ์žˆ๋Š” ํŒŒ์ผ ์ค‘ ํŒจํ„ด์ด ์žˆ๋Š” ๋‚ด์šฉ์„ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ Makefile์„ ์ˆ˜์ •ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

main.o: main.c
foo.o: foo.c
bar.o: bar.c
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<

vpath

  • vpath pattern directories: %.c, %.h ๋“ฑ์˜ pattern์„ ์ฐพ๊ธฐ ์œ„ํ•œ directories๋ฅผ ์„ค์ •
  • vpath pattern: pattern์„ ์ฐพ๊ธฐ ์œ„ํ•œ directories ๋ชฉ๋ก์„ ๋น„์›€
  • vpath: ๋ชจ๋“  directories ๋ชฉ๋ก์„ ๋น„์›€

์—ฌ๋Ÿฌ ํด๋”์— ์žˆ๋Š” ํŒŒ์ผ ์ค‘ ํŒจํ„ด์ด ์žˆ๋Š” ๋‚ด์šฉ์„ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

vpath๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Makefile์„ ์ˆ˜์ •ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

main.o: src/main.c
foo.o: lib/foo/foo.c
vpath %.c src lib/foo
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<

Function

x...์€ ๋„์–ด์“ฐ๊ธฐ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋‚˜์—ด๋œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ x๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ์—๋„ ๋„์–ด์“ฐ๊ธฐ๋กœ ๊ตฌ๋ถ„๋˜์–ด ๋‚˜์—ด๋ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด x...์€ x1 x2 x3๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

wildcard

$(wildcard pattern...)๋Š” Makefile๊ณผ ๊ฐ™์€ ํด๋”์— ์žˆ๋Š” ํŒŒ์ผ ์ค‘ pattern๋“ค์— ํ•ด๋‹นํ•˜๋Š” ํŒŒ์ผ ๋ช…์„ ๋‚˜์—ดํ•ฉ๋‹ˆ๋‹ค.

wildcard๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ํŒจํ„ด์œผ๋กœ %.c๊ฐ€ ์•„๋‹ˆ๋ผ *.c๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Makefile์„ ์ˆ˜์ •ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(ํด๋”์— main.o, foo.o, bar.o ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.)

OBJS = main.o foo.o bar.o
OBJS = $(wildcard *.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 ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.)

OBJS = main.o foo.o bar.o
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))

add suffix,prefix

  • $(addsuffix suffix,namesโ€ฆ)
  • $(addprefix prefix,namesโ€ฆ)

ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Makefile์„ ์ˆ˜์ •ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(ํด๋”์— main.c, foo.c, bar.c ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.)

OBJS = obj/main.o obj/foo.o obj/bar.o
SRCS = $(wildcard *.c)
OBJS = $(addprefix obj/,$(patsubst %.c,%.o,$(SRCS)))

foreach

$(foreach var,list,text)๋Š” list์˜ ์›์†Œ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ณ€์ˆ˜ var์— ํ• ๋‹นํ•˜์—ฌ text๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Makefile์„ ์ˆ˜์ •ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(ํด๋”์— main.c, foo.c, bar.c ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.)

OBJS = obj/main.o obj/foo.o obj/bar.o
SRCS = $(wildcard *.c)
OBJS = $(foreach src,$(SRCS),obj/$(patsubst %.c,%.o,$(src)))

call macro

  • macro = $(1) $(2) ...: call ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ถ€๋ฅผ ์ˆ˜ ์žˆ๋Š” macro ์ž…๋‹ˆ๋‹ค. $(1)์ด param1์ž…๋‹ˆ๋‹ค.
  • define macro = $(1) ... endif: ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์ณ macro๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • $(call macro,param1,param2,...)
  • $(eval macro): macro๋ฅผ ๋ฏธ๋ฆฌ ํ™•์ธํ•˜๊ณ  Makefile์˜ ๊ตฌ๋ฌธ์œผ๋กœ ์ •์˜ํ•˜์—ฌ ํ•ด๋‹น ๊ฒฐ๊ณผ๊ฐ€ makefile์˜ ์ฝ”๋“œ๋กœ ๋ถ„์„๋˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

callํ•จ์ˆ˜๋Š” ๋งคํฌ๋กœ์— ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ถ€๋ถ„๋งŒ ๋ฐ”๊ฟ”์„œ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

macro์™€ call์„ ์‚ฌ์šฉํ•˜์—ฌ ๋””๋ ‰ํ† ๋ฆฌ์˜ ํ•˜์œ„ ํ•ญ๋ชฉ์„ ๋ชจ๋‘ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” recursive ํ•จ์ˆ˜๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
test:
#ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ์™€ ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ์˜ ๋ชจ๋“  ๋””๋ ‰ํ† ๋ฆฌ์™€ ํŒŒ์ผ
@echo $(call rwildcard,,*);\
#src ๋””๋ ‰ํ† ๋ฆฌ์™€ src ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ์˜ ๋ชจ๋“  .c ํŒŒ์ผ
@echo $(call rwildcard,src,*.c)

call์€ ๋‹จ์ˆœํžˆ macro๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ํ™•์žฅ์‹œ์ผœ์ฃผ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ tab์ด ์žˆ์–ด๋„ makefile์ด ์ธ์‹์„ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์˜ ๊ฒฝ์šฐ ๊ฐ™์€ Makefile์ด๊ธฐ ๋•Œ๋ฌธ์— ์˜๋„ํ•˜์ง€ ์•Š์€ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

define asdf =
asdf:
@echo asdf
endef
$(call asdf)
asdf: @echo asdf

evalํ•จ์ˆ˜๋Š” macro๋ฅผ ๋ฏธ๋ฆฌ ํ™•์ธํ•˜๊ณ  makefile์˜ ๊ตฌ๋ฌธ์œผ๋กœ ์ •์˜ํ•ด ์ค๋‹ˆ๋‹ค.

์œ„์˜ ์˜ˆ๋ฅผ evalํ•จ์ˆ˜๋กœ ๋‹ค์‹œ ํ‘œํ˜„ํ•˜๋ฉด ์˜๋„ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

define asdf =
asdf:
@echo asdf
endef
$(eval $(call asdf))
asdf:
@echo asdf
caution

evalํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‚ด๋ถ€์— ์ž๋™ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ $๋ฅผ ํ•œ๋ฒˆ ๋” ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ($$@, $$< ๋“ฑ) evalํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‚ด๋ถ€ ๋‚ด์šฉ์ด evalํ•จ์ˆ˜์™€ Makefile์— ์˜ํ•ด 2๋ฒˆ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ $@->๊ณต๋ฐฑ->๊ณต๋ฐฑ, $$@->$@->target์ด ๋ฉ๋‹ˆ๋‹ค.

Last updated on