CC = clang CFLAGS = -Wall -Wextra -Werror -O2 LDFLAGS = -flto SRC_DIR = srcs OBJ_DIR = obj BUILD_DIR = build HDRS_DIR = hdrs LIBRARY = $(BUILD_DIR)/libft.a # Source and object files for library SRCS = $(shell find $(SRC_DIR) -type f -name "*.c") OBJS = $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRCS)) # Test configuration TESTS_DIR = tests TESTS_SRCS = $(wildcard $(TESTS_DIR)/*.c) TESTS_OBJS = $(patsubst $(TESTS_DIR)/%.c,$(OBJ_DIR)/%.test.o,$(TESTS_SRCS)) TESTS_BINS = $(patsubst $(TESTS_DIR)/%.c,$(BUILD_DIR)/%_test,$(TESTS_SRCS)) # Flags for configuration CONFIG_FLAGS := $(shell grep -E '^[a-zA-Z0-9_]+=' .config | sed 's/\([A-Za-z0-9_]*\)=y/-D\1=1/;s/\([A-Za-z0-9_]*\)=n/-D\1=0/') CFLAGS += $(CONFIG_FLAGS) all: $(LIBRARY) $(OBJ_DIR) $(BUILD_DIR): @mkdir -p $@ # Build object files for library $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HDRS_DIR)/*.h | $(OBJ_DIR) @mkdir -p $(dir $@) @echo -e " CC\t$<" @$(CC) $(CFLAGS) -I$(HDRS_DIR) -c $< -o $@ $(LIBRARY): $(OBJS) | $(BUILD_DIR) @echo -e " AR\t$@" @$(AR) rcs $(LIBRARY) $(OBJS) # Build object files for tests $(OBJ_DIR)/%.test.o: $(TESTS_DIR)/%.c $(HDRS_DIR)/*.h | $(OBJ_DIR) @mkdir -p $(dir $@) @echo -e " CC\t$<" @$(CC) $(CFLAGS) -I$(HDRS_DIR) -I$(SRC_DIR) -c $< -o $@ # Link each test binary $(BUILD_DIR)/%_test: $(OBJ_DIR)/%.test.o $(LIBRARY) | $(BUILD_DIR) @echo -e " LD\t$@" @$(CC) $(CFLAGS) $< -L$(BUILD_DIR) -lft -o $@ tests: $(LIBRARY) $(TESTS_BINS) @for testbin in $(TESTS_BINS); do \ ./$$testbin; \ done clean: @echo " CLEAN" @rm -rf $(OBJ_DIR) fclean: clean @echo " FCLEAN" @rm -rf $(BUILD_DIR) @rm -f $(TESTS_BIN) re: fclean all .PHONY: all clean fclean re tests CONFIG_FILE := .config genconfig: @echo -e " C\t${CONFIG_FILE}" @echo "USE_SLIST=y" > $(CONFIG_FILE) @echo "USE_DLIST=y" >> $(CONFIG_FILE) @echo "USE_STACK=y" >> $(CONFIG_FILE)