Make 유틸리티
여러개의 소스코드를 빌드하는데 쓰이는 소프트웨어
- 파일 수가 많은 경우 이를 일일이 컴파일을 하게 될 때, 그 불편함과 함께 컴파일하지 않아도 될 것도 컴파일을 하게 될 수도 있고, 컴파일해야 할 것도 미처 못하게 되는 경우가 있다.
- 이러한 점을 해결할 때 make를 사용한다.
mermaid
graph TD
libft.h --> ft_strjoin.c --> ft_strjoin.o --> libft.a
libft.h --> ft_strchr.c --> ft_strchr.o --> libft.a
libft.h --> ft_strlcat.c --> ft_strlcat.o --> libft.a
make 실행하기
다음과 같이 터미널 창에 입력하면 된다.
bash
make [명령어]
# make
# make all
물론, 그냥은 안되고 해당 폴더 안에 Makefile이라는 것이 존재해야 한다.
Makefile
makefile이란?
- make 유틸리티의 설정 파일.
- make 유틸리티를 실행시키는 make 명령어가 작동하려면, 반드시 필요하다.
- make 프로그램은 makefile을 읽어 소스코드와 라이브러리를 실행파일으로 만든다.
makefile의 구조
목표(target), 의존관계(dependency), 명령(command)
bash
target : dependency
command
목표(target) : 빌드할 대상의 이름
의존관계(dependency) : 빌드하기 위해 필요한 헤더파일과 소스파일
명령(command) : 어떻게 빌드할지에 대한 명령(커맨드)
makefile : 예시
makefile
# test 만들기
test : main.o read.o write.o
gcc -o test main.o read.o write.o
main.o : io.h main.c
gcc -c main.c
read.o : io.h read.c
gcc -c read.c
write.o: io.h write.c
gcc -c write.c
- test를 만들기 위해서 (target)
- main.o, read.o write.o가 필요하고 (dependency)
- 이것들을 gcc라는 컴파일러로 묶어서 test를 만든다. (command)
- 주석은 # 기호를 치면 만들어진다.
그런데, 이렇게 적어도 파일이 늘어나면 복잡해진다. 그래서 보통 매크로를 사용한다.
매크로와 확장자
makefile을 좀 더 간결하게 만들고, 기능을 늘리기 위해 사용한다.
매크로
매크로는 맨 위에 대문자로 선언하고, 사용할 때는 $()와 같이 사용한다.
makefile
OBJECTS = main.o read.o write.o
test : $(OBJECTS)
gcc -o test $(OBJECTS)
어떤 매크로는 미리 정해져 있다. (터미널 창에서 make -p를 치면 나온다.)
대표적인 지정 매크로는 다음과 같다.
bash
CFLAGS # gcc 의 옵션 세팅
CC #
all #
clean #
fclean #
.PHONY #
확장자
프로그램을 만들기만 하지 않고,
makefile
$@ # 현재 목표(target) 파일
$^
makefile 작성 팁
명령어 줄 넘김
다음과 같이 \ 기호를 사용한다.
makefile
OBJS = shape.o \
rectangle.o \
circle.o \
line.o \
bezier.o
매크로 치환
하나의 매크로를 다른 매크로로 바꾸는 것을 의미한다.
이를 이용하면 코드의 길이를 확실히 줄일 수 있다. 보통 다음과 같이 작성한다.
makefile
# 매크로A의 파일을 매크로B로 변환
# 매크로B = $(매크로A: 변환 전 확장자 = 변환 이후 확장자)
OBJS = main.o read.o write.o
SRCS = $(OBJS:.c=.o)
라이브러리 작성
보통 command에 ar 유틸리티를 사용한다.
makefile
$(NAME) : $(OBJ_TEMP)
ar -rc libft.a $(OBJ_TEMP)
ar 유틸리티란? 오브젝트 파일을 만들고 조작하고 추출하는 기능.
-r : 오브젝트 추가
-c : 아카이브 생성
-s : 인덱스 생성