makefile - KimTaebin-ai/study_posts GitHub Wiki
makefile ์ด๋ ๋น๋๋ฅผ ๋์์ฃผ๋ ์คํฌ๋ฆฝํธ ํ์ผ์ด๋ค.
linux ํ๊ฒฝ์ ์๋ ์์ค์ฝ๋ ํ๋ก๊ทธ๋จ๋ค์ ์คํํ ๋ make
๋ผ๋ ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ๋ฉด Makefile์ ์์ฑ๋ ์คํฌ๋ฆฝํธ ์์๋๋ก ๋น๋๋ฅผ ์ํํ๋ค.
(makefile์ ๋ค์ด๊ฐ๊ธฐ ์ gcc ๋น๋์ ๋ํด์ ์ดํดํ๊ณ ๋์ด๊ฐ๋ ๊ฒ์ด ์ข๋ค.) gcc ๋น๋
a.exe / a.out ์ ์์คํ์ผ์ ๊ฐ๊ฐ ์ปดํ์ผํ์ฌ .o ๋ผ๋ ๋ชฉ์ ํ์ผ์ ์์ฑํ๊ณ ๋ง๋ค์ด์ง ๋ชฉ์ ํ์ผ๋ค์ ํ ๊ณณ์ผ๋ก ๋ฌถ๋ ๋งํน ๊ณผ์ ์ ํตํด ๋ง๋ค์ด์ง๋ค.
gcc -c -o main.o main.c
์ ๋ช
๋ น์ด๋ gcc์ -cํ๋๊ทธ๋ฅผ ๋ถ์ฌ์ ์ปดํ์ผ๋ง ์คํํ ์ ์๋ค. ์ฆ, main.o ํ์ผ์ ๋น๋ํ๋ ๊ฒ-c ํ๋๊ทธ๋ฅผ ํตํด ๋ชฉ์ ํ์ผ์ ์์ฑํ๋ฉด main๊ณผ ๊ฐ์ ์ด๋ฆ์ผ๋ก .o๊ฐ ์๊ธฐ์ง๋ง ์ด๋ฆ์ ๊ผญ ์ง์ ํด์ฃผ์
gcc -o a.out main.o
๋ช ๋ น์ gcc์ง๋ง gcc๋ด๋ถ์ ์ผ๋ก ๋ง์ปค๋ฅผ ์คํํ์ฌ ์คํํ์ผ์ ์์ฑํ๋ค (-o ํ๋๊ทธ๋ ์ด๋ฆ ๋ณ๊ฒฝ)
Incremental build
Incremental build์ makefile์ ๋๋ํ๊ฒ ์์กด์ฑ์ด ์๋ ๋์๋ค๋ง์ ์ถ๋ ค์ ๋ค์ ๋น๋๊ฐ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋ฉ์น๊ฐ ํฐ ์์ ์ ๊ฒฝ์ฐ ๋งค์ฐ ์ ์ฉํ๋ค!!
Rule block ์ ๊ตฌ์กฐ
<Target> : <Dependencies>
<Recipe>
- target: ๋น๋ ๋์ ์ด๋ฆ์ ์๋ฏธํ๋ค. ํต์์ ์ผ๋ก ์ต์ข ์ ์ผ๋ก ์์ฑํด๋ด๋ ํ์ผ๋ช ์ ์ด๋ค๊ณ ํ๋ค.
- dependencies: target์ด ์์กดํ๋ target์ด๋ ํ์ผ๋ชฉ๋ก target์ ๋ง๋ค๊ธฐ์ ๋จผ์ ๋ง๋ค๊ณ ๋น๋ ๋์(target)์ ์์ฑ
- recipe: ๋น๋ ๋์์ ์์ฑํ๋ ๋ช ๋ น. ์ฌ๋ฌ์ค๋ก ์์ฑ์ด ๊ฐ๋ฅํ๊ณ ๋ฐ๋์ tap์ผ๋ก ๊ตฌ๋ถํด์ผํ๋ค.
- ๋ด์ฅ ๊ท์น
Makefile์์๋ ์์ฃผ ์ฌ์ฉ๋๋ ๋น๋ ๊ท์น๋ค์ ๊ตณ์ด ๊ธฐ์ ํ์ง ์์๋ ์๋์ผ๋ก ์ฒ๋ฆฌํด์ค๋ค..! (์์คํ์ผ์ ์ปดํ์ผํ์ฌ ๋ชฉ์ ํ์ผ๋ก ๋ง๋๋ ๊ท์น)
ํ์ง๋ง target์ ๋ํ ํค๋ํ์ผ์ ์ถ์ ํ์ง ์๊ธฐ ๋๋ฌธ์ dependencies๊น์ง๋ ๋ช ์ํด์ค์ผ ํ๋ค.(ํค๋ํ์ผ์)
์์์ ๋ค๋ฃฌ main.cํ์ผ์ ์์กด์ฑ์ ๊ฐ์ง๋ fun.c์ ํค๋ํ์ผ์ด ์กด์ฌํ๋ค๋ฉด ์๋์ ๊ฐ์ด ๋ฃฐ๋ธ๋ญ์ ์์ฑํ๋ค.
a.out: main.o fun.o
gcc -o a.out main.o fun.o
main.o: fun.h main.c
fun.o: fun.h fun.c
- ๋ณ์ ์ฌ์ฉ๋ฒ
์ฌ์ฉ๊ฐ๋ฅํ ๋ณ์๋ช
์ make -p
๋ฅผ ํตํด ํ์ธํ ์ ์๋ค.
CC=gcc
CFLAG= -Wall -Werror -Wextra
OBJS= main.o fun.o
TARGET= a.out
$(TARGET): $(OBJS)
$(CC) -o $@ $(OBJS)
main.o: fun.h main.c
fun.o: fun.h fun.c
- $@์ ํ์ฌ target์ ์ด๋ฆ์ ๋ํ๋ด๋ ์๋๋ณ์
- $^์ ํ์ฌ target์ด ์์กด(Dependencies)ํ๋ ๋์๋ค์ ์ ์ฒด ๋ชฉ๋ก
- $<์ ์ฒซ ๋ฒ์งธ depend์ ํ์ผ ์ด๋ฆ
- $?์ ํ์ฌ target์ด ์์กดํ๋ ๋์๋ค์ค ๋ณ๊ฒฝ๋ ๋ชฉ๋ก
์์ Makefile์ ํด์ํด๋ณด๋ฉด a.out์ ๋ง๋ค๊ธฐ ์ํ ์์กด์ฑ ํ์ผ๋ค์ main.o, fun.o๊ฐ ์กด์ฌํ๊ณ a.out์ ๋ํ ๋ ์ํผ๋ ๋ฐ์ ๋์ ์์ง๋ง ๋จผ์ ์์กด์ฑํ์ผ๋ค์ ๋จผ์ ์์ฑํ๋ค.์์กด์ฑ ์์ฑํ์ผ์ ๋ํ ๋ฃฐ๋ธ๋ญ๋ํ ์๋์ ๋์ ์์ผ๋ฉฐ ํด๋น ๋ ์ํผ๊ฐ ์กด์ฌํ์ง ์๋ ์ด์ ๋ makefile์ ๋ด๋ถ ๊ท์ฐฉ์ ์ํด ์๋ ๋น๋๋๋ค.๋ค์ ๋์๊ฐ์
์ฌ๊ธฐ์ ๋ณ์๋ช ์ ์ฌ์ฉํ์ฌ ๋ง์ฝ ๊ฐ๋ฐ์๊ฐ a.out์ด ์๋ ๋ค๋ฅธ ์ด๋ฆ์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด ๋งจ ์ ๋ณ์ ์ ์ธ๋ถ์์ ์ด๋ฆ๋ง ๋ณ๊ฒฝํ๋ฉด ์๋์ $(TARGET)์ ์ด๋ฆ๋ค์ ์๋๋ณ๊ฒฝ๋๊ฒ ๋๋ค.
- ์ธ๋ถ ํค๋ํ์ผ ํฌํจ์ํค๋ ๋ฒ
์ธ๋ถ ํค๋ํ์ผ์ ํฌํจ์ํฌ๋ ค๋ฉด gcc ๋ค์ -I
ํ๋๊ทธ๊ฐ ๋ถ์ด์ผ ํ๋ค.(ํ์ค ๋๋ ํ ๋ฆฌ๊ฐ ์๋ ํค๋ํ์ผ์ ๊ฒฝ์ฐ ๋๋ ํ ๋ฆฌ ์์น ์ง์ )
gcc main.c -I ./include
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ฑ ๋ฐฉ๋ฒ
ar r libft.a *.o
ํ์ฌ ๋ฃจํธ์ ์กด์ฌํ๋ .o ๋ชฉ์ ํ์ผ๋ค๋ก libft.a๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ผ์ ๋ง๋ ๋ค.
ar s libft.a
ํจ์์ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๋ค.
++ ar t
๋ฅผ ํตํด ๋ด๋ถ ์ค๋ธ์ ํธ ํ์ผ์ ํ์ํ ์ ์๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฑํ ๋ ๋ง๋ค ์ฃผ์ ํ์๊ฐ ๋จ๊ธฐ ๋๋ฌธ์ c
ํ๋๊ทธ๋ฅผ ํตํด ์ ๊ฑฐํ ์ ์๋ค.
libft ํ๋ก์ ํธ์์ ๋ง๋ค์ด์ผ ํ๋ ๊ฒ์ ์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ปดํ์ผ๋ ์ค๋ธ์ ํธ ํ์ผ๋ค์ด ํ๋์ ์์นด์ด๋ธ๋ก ๋ฌถ์ฌ ์๋ ํํ๋ก, ์ค๋ธ์ ํธ ํ์ผ๋ค์ ๋ฌถ์ด ์ฃผ๋ ๋ช
๋ น์ด๊ฐ ๋ฐ๋ก ar
๋ช
๋ น์ด์ด๋ค.๊ธฐ๋ณธ์ ์ผ๋ก ์์นด์ด๋ธ๋ฅผ ์์ฑํ ๋์ ์ฌ์ฉ ์๋ ๋ค์๊ณผ ๊ฐ๋ค.
ar rscv libft.a file1.o file2.o ...
์ฌ์ค ar ๋ช ๋ น์ด๋ ์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ตญํ๋์ง ์๊ณ , ๋ฒ์ฉ์ ์ธ ๋น์์ถ ์์นด์ด๋ธ๋ก ์ฌ์ฉํ ์ ์์ผ๋ ์ผ๋ฐ์ ์ผ๋ก๋ ์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค๊ณ ํ๋ค!
ar rcus [๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ] [์ค๋ธ์ ํธ ํ์ผ๋ค]
r
: ์๋ก์ด ์ค๋ธ์ ํธ ํ์ผ์ด๋ฉด ์ถ๊ฐ, ๊ธฐ์กด ํ์ผ์ด๋ฉด ์นํ
c
: ์์นด์ด๋ธ(๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ผ) ์์ฑ, ์กด์ฌํ์ง ์๋ ์์นด์ด๋ธ๋ฅผ ์์ฑ(๋๋ ๊ฐฑ์ )ํ๋ ๊ฒฝ์ฐ์๋ ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ์ง ์์
u
: ์ค๋ธ์ ํธ ํ์ผ์ ํ์์คํฌํ๋ฅผ ๋น๊ตํด ์๋ก์ด ํ์ผ์ผ ๊ฒฝ์ฐ์๋ง ์นํ
s
: ranlib(1)๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์์นด์ด๋ธ ์ธ๋ฑ์ค ์์ฑ. ์์นด์ด๋ธ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ์ง ์์ผ๋ฉด ๋งํฌ ์๋๊ฐ ๋๋ ค์ง๊ณ , ์์คํ
ํ๊ฒฝ์ ๋ฐ๋ผ ์๋ฌ๊ฐ ๋ฐ์ํ ์๋ ์์
ar ds [๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ] [์ค๋ธ์ ํธ ํ์ผ๋ค]
d
: ์์นด์ด๋ธ ๋ชจ๋์ ์ญ์ , ์ญ์ ํ ํ์ผ์ด ์๋ค๋ฉด ๋์ํ์ง ์์
ar tv [๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ]
t
: ์์นด์ด๋ธ์ ์๋ ํ์ผ ๋ฆฌ์คํธ ์ถ๋ ฅv
: ์์ธํ ๋ด์ฉ์ ๋ณด์ฌ์ฃผ๋ verbose ๋ชจ๋๋ก, ์ด ์ต์
์ ์ด์ฉํ๋ฉด ํ์ผ ํฌ๊ธฐ๋ ๊ฐฑ์ ์๊ฐ ๋ฑ์ ์์ธ ์ ๋ณด๋ ์ถ๋ ฅ
ar xv [๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ]
x
: ์์นด์ด๋ธ์์ ์ค๋ธ์ ํธ ํ์ผ ์ถ์ถv
: ์ถ์ถํ ํ์ผ์ ํ์ผ๋ช
์ถ๋ ฅ
- clean
์์ฃผ ์ฌ์ฉ๋๋ ๋ฃฐ ๋ธ๋ญ์ ๋ชจ์ต์ด๋ฉฐ make๋ค์ ํ๋๊ทธ์ฒ๋ผ ๋ถ์ฌ ๋งคํฌ๋ก๋ก ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
target๊ณผ ๋ชฉ์ ํ์ผ๋ค์ ์ ๋ถ ์ญ์ ํ๋ ์ญํ ์ ํ๋ค. Dependencies๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉฐ recipe๋ง ์กด์ฌ
clean: rm -rf $(OBJS) $(TARGET)
- all
all: libft.a
all์ ์ค์ ๋ก ์์ฑํ๋ ๊ฒ์ด ์๋ ๋ฌด์์ด ์ต์ข target์ธ์ง ๋ช ํํ๊ฒ ์ง์ ํด์ฃผ๋ ์ญํ ์ด๋ค.
make all
์ ์คํํ ๊ฒฝ์ฐ libft.a๋ฅผ ๋ง๋ค๊ธฐ ์์..
- .PHONY
์ค์ ํ์ผ์ ์ด๋ฆ์ ๊ฐ๋ฆฌํค๋ ๊ฒ์ด ์๋ ๊ฐ์ง ํ์ผ์ ๊ฐ๋ฅดํจ๋ค..!
์ฌ์ฉํ๋ ์ด์ ๋ ๋์ผํ ์ด๋ฆ์ ์ถฉ๋์ ํผํ๊ณ ์ฑ๋ฅํฅ์์ ์ํด ์ฌ์ฉํ๋ค.
clean: rm main.o main.c
์ ๋งคํฌ๋ก๋ฅผ ์คํํ๋ฉด rm๋ช
๋ น์ clean์ด๋ผ๋ ์ด๋ฆ์ ํ์ผ์ ์์ฑํ์ง์๊ธฐ ๋๋ฌธ์ clean์ด๋ ์ด๋ฆ์ ํ์ผ์ด ์กด์ฌํ์ง ์์ ๊ฒ์ด๋ค. rm๋ช
๋ น์ make clean
์ํํ ๋ ๋ง๋ค ๋งค๋ฒ ์คํ๋๊ฒ ๋๋ค.
ํ์ง๋ง ๋๋ ํ ๋ฆฌ์ clean์ด๋ผ๋ ์ด๋ฆ์ ํ์ผ์ ์์ฑํ๊ฒ ๋๋ฉด clean์ ์ ๋๋ก ๋์ํ์ง ์๊ฒ ๋๊ณ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ .PHONY๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ ์กฐ๊ฑด์ ๋ง๋ค์ด ์ค๋ค.
์ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ฑ!
TARGET= libft.a
CC= gcc
CFLAG= -Wall -Werror -Wextra
SRCS= main.c fun.c
OBJS= $(SRCS:.c=.o)
.c.o: $(SRCS)
$(CC) $(CFLAGS) -c $<
all: $(TARGET)
$(TARGET): $(OBJS)
ar rcs $(TARGET) $(OBJS)
clean:
rm -f $(OBJS)
fclean: clean
rm -f $(TARGET)
re: fclean all
.PHONY all clean fclean re
- ๋ชฉ์ ํ์ผ(target): ๋ช ๋ น์ด ์ํ ํ ๋์จ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ ํ์ผ
- ์์กด์ฑ(dependency): ๋ชฉ์ ํ์ผ์ ๋ง๋ค๊ธฐ ์ํ ์ฌ๋ฃ ํ์ผ
- ๋ช ๋ น์ด(command): ์คํ ๋์ด์ผ ํ ๋ช ๋ น์ด๋ค
- ๋งคํฌ๋ก(macro): ์ฝ๋๋ฅผ ๋จ์ํ ์ํด
CC = gcc
target1 : dependency1 dependency2
command1
command2
target2 : dependency3 dependency4
command3
command4
Relink๋ ์์กด์ฑ์ด ๋ณ๊ฒฝ๋์์๋๋ง ํ๊ฒ์ ์์ฑํ๋ ๊ฒ์ ๋งํ๋ค.
bonus: $(OBJ_B)
$(AR) $(TARGET) $^
ํด๋น ๋ช
๋ น์ด๋ OBJ_B
๊ฐ ์กด์ฌํ๋ค๋ฉด TARGET
์ ์์ฑํ๋ค. OBJ_B
๊ฐ ๋ณ๊ฒฝ๋์๋๋ฅผ ์ฒดํฌํ์ง ์๊ธฐ ๋๋ฌธ์ make bonus
๋ฅผ ํ๋ฉด ๋ฌด์กฐ๊ฑด ๋ฆฌ๋งํฌ๋๊ฒ ๋๋ค.
ifdef WITH_BONUS
OBJ = $(OBJ_O) $(OBJ_B)
else
OBJ = $(OBJ_O)
endif
...
bonus:
make WITH_BONUS=1 all
์ ๋ช
๋ น์ด๋ make bonus
๋ฅผ ํ๋ฉด WITH_BONUS
๋ผ๋ ์์๋ฅผ 1๋ก ์ง์ ํ์ฌ ์ฝ๋๋ฅผ ์คํํ๋ค. WITH_BONUS
๋ผ๋ ์์๊ฐ 1์ผ๋๋ OBJ
๋ฅผ OBJ_O
์ OBJ_B
๋ชจ๋์ ๋ณ๊ฒฝ์ฌํญ์ ์ฒดํฌํ๊ธฐ ๋๋ฌธ์ ๋ฆฌ๋งํฌ๊ฐ ๋ฐฉ์ง๋๋ค.
์ฐธ๊ณ ์๋ฃ