목표
Level : 9
학습 목표
- 다른 make 파일을 호출할 수 있다.
---------
< 문제 >
- 'make all' ./src/*.c 파일들을 ./obj/*.o 파일로 컴파일 한 뒤 ./lib/libft.a 와 링킹하여 ./main을 생성하시오.
- 'make all' 실행 시 ./lib 디렉토리에 ./libft.a가 없을 시 ./lib/Makefile을 실행하여 libft.a를 생성한다.
< 제한 사항 >
- .c 파일들을 할당한 변수를 함수로 치환하여 .o 파일을 할당할 변수로 정의하시오.
- 패턴 Rule을 사용하여 오브젝트 파일 생성 규칙을 정의하시오 - Rule의 Recipe 작성 시 Target과 Dependency를 적절한 자동 변수(Automatic Variables)를 사용하여 작성하세요.
- Rule을 변수만으로 작성하시오.
- 적절한 변수를 할당하시오.
- 리링크되지 않아야 합니다.
코드
NAME := main
SRC_DIR = ./src/
SRC_NAME = main.c \
fourth.c
SRC = $(addprefix $(SRC_DIR),$(SRC_NAME))
OBJ_DIR = ./obj/
OBJ_NAME = $(SRC_NAME:.c=.o)
OBJ = $(addprefix $(OBJ_DIR),$(OBJ_NAME))
CC := gcc
CFLAGS := -Wall -Wextra -Werror
INCLUDE := -I./include -I./lib
LIB_DIR = ./lib/
LIB_NAME = ft
LIB = $(LIB_DIR)lib$(LIB_NAME).a
all : $(NAME)
clean :
rm -f $(OBJ)
make -C $(LIB_DIR) clean
fclean : clean
rm -f $(NAME)
re : fclean all
run : all
./$(NAME)
$(NAME) : $(LIB) $(OBJ)
$(CC) $(CFLAGS) $(INCLUDE) -L$(LIB_DIR) -l$(LIB_NAME) -o $@ $^
$(LIB) :
make -C $(LIB_DIR) all
$(OBJ_DIR)%.o : $(SRC_DIR)%.c
@mkdir -p $(OBJ_DIR)
$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
.PHONY : all clean fclean re run
설명
변수 설명
NAME, SRC_DIR, SRC_NAME, SRC, OBJ_DIR, OBJ_NAME, OBJ, CC, CFLAGS, INCLUDE: 이전 레벨에서 설명한 변수와 동일한 역할을 합니다.
LIB_DIR = ./lib/: 라이브러리가 위치한 디렉토리를 LIB_DIR 변수에 할당합니다.
LIB_NAME = ft: 라이브러리 이름을 LIB_NAME 변수에 할당합니다.
LIB = $(LIB_DIR)lib$(LIB_NAME).a: 라이브러리의 전체 경로를 LIB 변수에 할당합니다.
룰과 명령어
all : $(NAME): make all 또는 make 명령을 실행하면 $(NAME) 타겟이 생성됩니다.
clean :: make clean 명령을 실행하면 모든 .o 파일과 라이브러리 디렉토리의 .o 파일이 삭제됩니다.
fclean : clean: make fclean 명령을 실행하면 clean 타겟이 먼저 실행되고, 그 후에 $(NAME) 파일이 삭제됩니다.
re : fclean all: make re 명령을 실행하면 fclean과 all 타겟이 순차적으로 실행됩니다.
run : all: make run 명령을 실행하면 all 타겟이 먼저 실행되고, 그 후에 ./main 실행 파일이 실행됩니다.
$(NAME) : $(LIB) $(OBJ): $(NAME) 타겟은 $(LIB)와 $(OBJ) 의존성을 가집니다. 이 의존성을 만족시킨 후에 실행 파일을 생성합니다.
$(LIB) :: $(LIB) 타겟은 ./lib/Makefile을 실행하여 라이브러리를 생성합니다.
다른 Makefile 호출하기
make -C $(LIB_DIR) clean: clean 타겟에서는 $(LIB_DIR) 디렉토리로 이동하여 make clean을 실행합니다.
make -C $(LIB_DIR) all: $(LIB) 타겟에서는 $(LIB_DIR) 디렉토리로 이동하여 make all을 실행합니다.