I have made a basic makefile which is supposed to compile my library. It goes like this :
NAME = mylib.a
CC = gcc
FLAGS = -Wall -Wextra -Werror
LIB_SRCS = $(shell find . -type f | grep -F ".c")
LIB_OBJ = $(notdir $(LIB_SRCS:%.c=%.o))
OBJ_DIR = obj/
HEADERS_DIR = ./includes
.PHONY: all
all: $(NAME)
.PHONY: $(NAME)
$(NAME):
@$(CC) $(FLAGS) -c $(LIB_SRCS) -I $(HEADERS_DIR)
@mkdir -p $(OBJ_DIR)
@mv $(LIB_OBJ) $(OBJ_DIR)
@ar rc $(NAME) $(addprefix $(OBJ_DIR), $(LIB_OBJ))
@ranlib $(NAME)
It works pretty well, except that when I use my lib for any project, it recompiles all the files (even when I haven't changed any source from the lib). I've read this : (Makefile compiles all the files everytime) but it's said I have to create a rule for every source file (or group of source files), which I don't want since there is a lot of source files. I wanted only one rule that compiles file by file.
So I've googled a bit and found a makefile that recompiles only the sources that were modified. And it goes like this :
NAME = mylib.a
CC = gcc
FLAGS = -Wall -Wextra -Werror
INCLUDES = includes/
SRCS_DIR = srcs
OBJ_DIR = obj
ITEMS = $(shell find $(SRCS_DIR) -type f | grep -F ".c" | sed 's/$(SRCS_DIR)//g')
SRCS = $(addprefix $(SRCS_DIR), $(ITEMS))
OBJ = $(addprefix $(OBJ_DIR), $(ITEMS:%.c=%.o))
SRCSUBS = $(shell find $(SRCS_DIR) -type d)
OBJ_SUBDIR = $(SRCSUBS:$(SRCS_DIR)%=$(OBJ_DIR)%)
.PHONY: all
all: $(NAME)
$(OBJ_DIR)/%.o:$(SRCS_DIR)/%.c
@$(CC) $(FLAGS) -o $@ -c $< -I $(INCLUDES)
$(OBJ_SUBDIR):
@mkdir $@
.PHONY: $(NAME)
$(NAME): $(OBJ_SUBDIR) $(OBJ)
@ar rc $(NAME) $(OBJ)
@ranlib $(NAME)
It works exactly as expected.
Since I didn't understand everything, I've read about automatic variables and managed to understand almost everything.
I just don't get how the rule that compiles $(OBJ_DIR)/%.o:$(SRCS_DIR)/%.c
is called from the $(NAME) $(OBJ_SUBDIR) $(OBJ)
rule.
Could anyone explain me how this rule is called since there is no mention to it from the "default" rule called when I execute make command (all: $(NAME)
) ?