본문 바로가기

공부기록/42 Seoul

[ft_printf] 03 libft.a 를 다른 프로젝트에서 사용할 수 있게 하기

ft_printf 에서 libft 함수들을 사용하려면,

폴더를 생성하고 그 안에 Makefile을 넣은 뒤에, 그 Makefile을 이용해서 libft.a를 만들고 본 프로젝트를 컴파일해야 한다.

 

Makefile이 lib/libft 폴더에 있는 또다른 Makefile을 실행해서 컴파일 하는 예제 코드를 slack에서 주워서, 내 tree 구조에 맞게 고쳐봤다.

NAME = libftprintf.a
FLAGS = -Wall -Wextra -Werror
SRC = ft_printf.c
OBJ = $(SRC:.c=.o)
INC_LINK = -I./includes
LIBFT = -L./Libft -lft

all : $(NAME)

$(NAME) : $(OBJ) libft
	cp Libft/libft.a ./$(NAME)
	ar rsc $(NAME) $(OBJ)

%.o: %.c
	gcc $(FLAGS) $(INC_LINK) -c $< -o $(<:.c=.o)

# libft compile
libft :
	@$(MAKE) -C ./Libft all

clean :
	@$(MAKE) -C ./Libft clean
	@rm -rf $(OBJ)
fclean : clean
	@$(MAKE) -C ./Libft fclean
	@rm -rf $(NAME)

re : fclean all

.PHONY: all clean fclean re libft

 

  • 두 정적 라이브러리 파일을 합치는 것은 11, 12행의 cp 명령이 핵심이었다. 단순히 cp로 가능했다니...

 

  • 그 외 위 Makefile의 문법에 대해 간단히 정리
    • %.o : %.c 여기서 % 기호는 확장자를 뺀 파일명을 나타낸다.
    • $<   dependency 파일들 중 첫번째 파일을 가리킨다.
    • $@  콜론을 기준으로 왼쪽에 오는 패턴을 치환한다. Target을 나타낸다고 생각하면 될듯하다.
    • make 메뉴얼을 보니 위와 같은 것들을 자동변수(Automatic variable)이라고 하는 듯 하다.
  • .PHONY 에 libft를 추가해주는게 필수적이다.
    .PHONY 는 파일이름이 아닌 것들을 makefile에게 알려주는 것이다. 여기에 적히는 항목들은 recipe 이름이거나, explicit request이다.

.PHONY를 쓰는 이유는 이름이 같은 파일과의 충돌을 피하기 위함인데, 예를들어 아래와 같은 rule을 작성했다고 해보자.

clean:
	rm *.o temp

여기서, clean이라는 파일이 존재했다면 이 rule은 제대로 동작하지 않을 것이다. .PHONY에 이 키워드를 넣어줌으로써 clean이라는 파일의 존재유무와 무관하게 위 rule은 제대로 동작할 것이다. 위 Makefile 코드에도 libft 라는 규칙이 있으니 .PHONY에 libft를 추가해야하는 것이다.

 

  • @ : recipe echoing
    Make는 기본적으로 실행되는 모든 라인을 출력한다(echo 된다). 그런데 @으로 시작하는 라인은, 실행되더라도 명령어가 출력되지 않는다. ( -s 옵션도 같은 기능을 한다. )

 

이렇게 Libft와 같이 묶어서 정적 라이브러리 파일 lftprintf.a 를 만들고, 만들어진 libftprintf.a 를 이용해 테스트 파일을 컴파일하고 실행해봤다.
컴파일은 이 명령어를 .sh 파일로 작성해서 따로 해줬다.

gcc -Wall -Werror -Wextra ft_printf.o main.c -I./includes -L. -lftprintf -o a.out

 

 

https://github.com/hysimok/42Seoul/commit/9ce0eaa7d1c9a2fba3cd117f703eac10fab5794c

 

위 commit에서 libft 함수와, 가변인자가 잘 작동하는지 테스트해본 main 함수를 볼 수 있다.