Reputation: 173
I'm encountering a problem with my Makefile in a C project, where changes in source files, except for the first file listed in my SRC variable, are not triggering a recompilation. I have a typical setup with source files, object files, and dependency files, and I use a standard pattern for my rules in the Makefile.
The Problem:
When I modify any source file other than main.c and run make, these changes are not detected, and the recompilation does not happen. This is despite having all object files and dependency files correctly generated in my objs folder. For example, if I modify main.c, make correctly detects the change and recompiles it. However, modifying any other file like utils.c or geometry.c does not trigger a recompilation.
Here's a snippet of my Makefile for reference:
SRC = $(SRCDIR)main.c \
$(SRCDIR)utils.c \
$(SRCDIR)geomtery.c \
... (other source files) ...
OBJ = $(SRC:$(SRCDIR)%.c=$(OBJDIR)%.o)
DEP = $(OBJ:.o=.d)
-include $(DEP)
CC = gcc
CFLAGS = -Wall -Wextra -Werror -O3 # -g -g3 -fsanitize=address
LFLAGS = -lm -lft -lmlx -framework OpenGL -framework AppKit
DEP_FLAGS = -MMD -MP
all: start_compilation $(NAME) end_compilation
start_compilation:
@printf "\n$(YELLOW)Compiling...$(WHITE)\n"
end_compilation:
@printf "$(GREEN)Compilation succesfull!$(WHITE)\n"
$(OBJDIR)%.o: $(SRCDIR)%.c
@mkdir -p $(OBJDIR)
$(CC) $(CFLAGS) $(DEP_FLAGS) -I $(INCLUDES) -c $< -o $@
$(NAME): $(OBJ) $(LIBFT) $(MLX)
@printf "\n$(CYAN)Generating project executable...$(WHITE)\n"
$(CC) $(CFLAGS) $(LFLAGS) $(OBJ) -L $(LFT_PATH) -L $(MLX_PATH) -o $(NAME)
What I've Tried:
I'm wondering if there's something I'm missing in my Makefile configuration that causes this behavior. Has anyone experienced a similar issue or can spot a potential mistake in my setup? Any help or insights would be greatly appreciated.
Upvotes: 0
Views: 59
Reputation: 101041
Make will always build the first explicit target found in the makefile, by default.
You are putting your include
at the beginning of the file:
-include $(DEP)
...
all:
that means that unless you specify a particular target (by running make all
for example), it will build the first target found in any of the included files. This is probably not what you want.
I should also say, this:
all: start_compilation $(NAME) end_compilation
is not likely to work correctly if you run with parallel builds. You can't "order" targets to be built using prerequisites in general. It only happens to work because make will build things in a specific order, and if you use -j1
(serial) build mode you are sure that the previous prerequisites are done before the next one starts.
Upvotes: 1