관련 글 보기
[토막글] Make와 Sanitizer 더 잘 쓰기에서 이어지는 내용입니다.
기존 Makefile
우선 전형적인 Makefile 예시입니다.
# 예시 이름
NAME := libft.a
# 소스코드 목록 - 제출용이 아닌 경우에만 사용
SRCS ?= $(shell find . -name "*.c" | xargs)
# 기본 변수
CC := clang
CFLAGS := -Wall -Wextra -Werror
# Norm 필수 규칙 (all, clean, fclean, re)
all: $(NAME)
clean:
find . \( -name "*.o" -o -name "*.d" \) -delete
fclean: clean
rm -f $(NAME)
re:
$(MAKE) fclean
$(MAKE) all
.PHONY: all clean fclean re
# **************************************************************************** #
#
#
# 여기서부터 중요!!!
#
# 플래그로 바이너리가 달라지는 경우 파일명에 $(SUFFIX)를 붙입니다.
#
# make $(NAME)으로 $(NAME)을 만들려고 할 경우, 타겟 파일을 단순히 복사합니다.
# 타겟 파일은 $(NAME)과 이름이 겹칠 수 있어 이름에 .target을 붙였습니다.
#
# **************************************************************************** #
# 여기에 코드 추가
SUFFIX := $(if $(SANITIZER),.$(SANITIZER))
%.a:
$(AR) rcs $@ $^
%$(SUFFIX).o: %.c
# SANITIZER가 있을 때만 -fsanitizer 플래그 사용
$(CC) $(CFLAGS) -c $< -o $@ -MMD $(if $(SANITIZER),-fsanitize=$(SANITIZER),)
$(NAME:.a=.target$(SUFFIX).a): $(patsubst ./%.c,%$(SUFFIX).o,$(SRCS))
.PHONY: $(NAME)
$(NAME): $(NAME:.a=.target$(SUFFIX).a)
cp $< $@
-include $(SRCS:.c=$(SUFFIX).d)
Makefile
복사
전형적인 Makefile 예시
여기서 SANITIZER 변수를 make에 전달해야만 해당 sanitizer를 사용하게 됩니다.
플래그를 저장하자
위 예시 코드의 여기에 코드 추가 부분에 아래 코드를 추가해 주세요
ifeq ($(SANITIZER),)
ifeq ($(SAVE),1)
# SANITIZER가 주어지지 않았는데 저장한다면 (SAVE 변수가 1이라면) 이전 설정 삭제
TMP := $(shell rm -f flag_sanitizer.mk)
# 바로 쉘을 실행할 수 없기 때문에 `아무_변수명 := $(shell 실행할_것)` 트릭을 사용합니다.
else
# SANITIZER가 주어지지 않으면 (+ 저장하지 않는다면) 기본값으로 이전 설정을 사용합니다.
-include flag_sanitizer.mk
endif
else
# SANITIZER가 주어진 경우!
ifeq ($(SAVE),1)
# 설정을 저장한다면 -include로 사용할 수 있게 flag_sanitizer.mk에 저장합니다.
TMP := $(shell printf "TMP := \$$(shell printf 'No SANITIZER given. using previous one. (run \`make reset\` to reset)\\\\n' 1>&2)\\nSANITIZER := $(SANITIZER)\n" > flag_sanitizer.mk)
# 이전 설정을 사용한다는 경고 메시지를 출력하고 SANITIZER 변수를 설정하는 파일을 생성
endif
endif
# 이전 설정을 저장한 flag_sanitizer.mk를 삭제하는 reset 스크립트를 추가합니다.
.PHONY: reset
reset:
rm -f flag_sanitizer.mk
# 그리고 clean 스크립트를 실행하면 reset 스크립트도 실행되도록 dependency에 추가합니다.
clean: reset
Makefile
복사
SANITIZER를 저장하는 예시
SAVE=1 없이도 항상 유지하려면 ifeq ($(SAVE),1)와 그 endif를 제거하면 됩니다.
추가로, 제출 파일에 제한이 없다면 이렇게 추가한 코드를 별도의 파일로 분리하는 게 좋겠죠.
결론
Sanitizer를 잘 쓰자는 것이 아닙니다. 물론 Sanitizer 잘 쓰면 좋습니다.
Sanitizer만이 아니라 뭐든지, 시간을 많이 잡아먹는 게 있다면 자동화로 시간을 아끼세요.
그렇게 조금씩 아낀 시간이 모여 뭔가 할 수 있는 시간이 만들어질 거에요