Makefile
기본적인 문법:
target: ingredient
command1
command2
target1 : ingredient
command1
command2
1. 기본 틀
타겟 : 타겟을 만드는 데 필요한 재료
실행할 쉘 명령어
2. 변수 선언 :
CC = cc , CFLAGS = -Wall -Wextr -Werror 선언 한 뒤,
$(CC) 이런 식으로 사용한다.
예시:
CC = cc
CFLAGS = -Wall -Wextra -Werror
%o : %c
$(CC) $(CFLAGS) ^@ ^<
이런 짤막한 예시에서는 이런 것들이 중요도가 낮아보인다.
하지만 makefile이 길어진다면, 그리고 파일 명이 한번 수정되었을 때 바뀌어야 하는 코드의 개수를 고려하면,
처음에 변수 선언에서 수정할 수 있다는 것이 얼마나 큰 장점이 될 수 있을 지 생각해볼만 하다
좀 더 신빙성을 위해 github에서 리눅스의 makefile을 직접 캡쳐해보았다. (ㅋㅋ)
가장 첫줄에서 역시나 변수선언을 하는 것이 보인다.
3. 와일드 문자 :
^@ : 타겟 (%o)가 해당.
$< : 재료 중 첫번 째 . (%.c 중 첫번째)
$^ : 재료 전체 (% .c 전체)
4. OBJS = $(SRCS_C:.c=.o)
.c를 .o로 바꾸어서 대입.
ex)SRCS_C = main.c utils.c
OBJS = $(SRC_CS:.c=.o) 하고 나면
OBJS = main.o utils.o 가 된 것과 같다.
5. $(addprefix $(SRCS_DIR), $(SRCS_C))
디렉토리 명 뒤에 파일을 붙이고 싶을 때 사용.
ex) SRS_DIR = ./includes/
SRCS_C = main.c utils.c
$(addprefix $(SRCS_DIR), $(SRCS_C)) 하고 나면 ./includes/main.c. ./includes/utils.c
6. j 옵션: job (프로세스 개수 )
make -j 를 사용시, 여러 프로세스로 나누어 make를 실행할 수 있다.
make가 오래걸리는 경우, 이 옵션을 사용하면 시간을 줄일 수 있다.
7.Makefile의 의존성
기본적으로 Makefile은 위에서부터 아래로 읽으며 수행하지만,
반드시 순서대로 짤 필요는 없다.
Makefile의 가장 특징이 바로 의존성인데, 타겟을 만들기 위해 필요한 재료가 아직 없다면
아래로 내려가서 그 재료를 만드는 명령어를 또 실행한다.
따라서 기본적으로 어떤 명령어를 먼저 실행시키도록 짤 것이냐의 문제에서 벗어날 수 있다.
CC = cc
CFLAGS = -Wall -Wextra -Werror
NAME = #만드려는 프로그램명
SRCS = main.c utils.c
OBJS = (SRCS:.c=.o) #main.o utils.o
%o : %c
$(CC) $(CFLAGS) ^@ ^<
#위의 사항은 기본이라서 저렇게 필요하다면 생략가능하다.
all : $(NAME)
#만드려는 궁극적인 타겟
re :
$(MAKE) fclean
$(MAKE) all
clean :
rm -rf $(OBJS)
fclean :
$(MAKE) clean
rm -rf $(NAME)
.PHONY: re clean fclean
#업데이트가 안되어도 매번 실행할 파일들 명령.
#가독성을 위해
#.PHONY re
#re : ..
#.PHONY clean
# clean: ..
#이런 식으로 하나씩 쓰는 경우도 있다. (리눅스 makefile)
8. 주의점
re : fclean all
이렇게 타겟 옆에 재료가 병행으로 있으면 순서가 정해져있지 않다.
re 에서 fclean all을 하면, j 옵션을 주었을 때 동시에 실행되는 문제가 발생한다:
두 명령의 순서가 정해져 있지 않아서
all 을 실행하고 fclean을 하거나 fclean을 하고 all이 실행 되는 등의 문제.
따라서 개행을 줘서 위에서 아래로 순차적으로 실행할 수 있도록 한 줄 띄어서 하도록 하자!
요렇게:
re : fclean
all
9. 팁
$(INC) = 포함시켜야 할 헤더파일 들어간 폴더.
NAME : $(OBJ_FILES) $(CC) $(CFLAGS) -o $@ $^ $(INC)
위처럼 적고 여기서 $(INC)를 적지 않아도 되는 이유는, 어차피 .c 파일 내에 #include "./include.h" 가 있어야 하고
그러면 $(INC)가 없어도 잘 되기 때문.
즉 $(INC) 을 애초에 안적어도 된다.
------
for more:
*리눅스 메이크 파일 뜯어보기:
'CS(computer science)' 카테고리의 다른 글
makefile 오류 - 'linker' input unused [-Werror,-Wunused-command-line-argument] (0) | 2022.12.10 |
---|---|
컴퓨터네트워크 - 애플케이션 계층 (간단 맛보기) (1) | 2022.12.04 |
linux - pthread_create 매뉴얼 뜯어보기[pthread] (4) | 2022.12.01 |
ft_print 구현해보기(printf, 가변인자 이해하기) (0) | 2022.11.29 |
linux - 메모리 릭 확인하는 법[쉘, 리눅스, do leaks] (4) | 2022.11.29 |