Created
January 12, 2022 04:13
-
-
Save rotrojan/0f128ca391ee0d1f06c9e44a3ac46b76 to your computer and use it in GitHub Desktop.
A Makefile template for C++ projects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# **************************************************************************** # | |
# # | |
# ::: :::::::: # | |
# Makefile :+: :+: :+: # | |
# +:+ +:+ +:+ # | |
# By: rotrojan <marvin@42.fr> +#+ +:+ +#+ # | |
# +#+#+#+#+#+ +#+ # | |
# Created: 2021/10/21 21:06:11 by rotrojan #+# #+# # | |
# Updated: 2021/12/20 21:54:05 by bigo ### ########.fr # | |
# # | |
# **************************************************************************** # | |
include settings.mk | |
OBJS = $(SRCS:%.cpp=$(OBJS_DIR)/%.o) | |
DEPENDENCIES = $(OBJS:%.o=%.d) | |
LDFLAGS = $(LIBS:%=-L lib%) | |
LDLIBS = $(LIBS:%=-l%) | |
CXXFLAGS += -MMD -MP | |
MAKEFLAGS += --no-print-directory | |
# Binaries | |
MAKE = make | |
RM = rm -f | |
MKDIR = mkdir -p | |
# Debug variables | |
DEBUG = 0 | |
ifeq ($(shell test -f $(OBJS_DIR)/debug1; echo $$?), 0) | |
DEBUG = 1 | |
endif | |
SANITIZE = 0 | |
ifeq ($(shell test -f $(OBJS_DIR)/sanitize1; echo $$?), 0) | |
SANITIZE = 1 | |
endif | |
ifeq ($(DEBUG), 1) | |
CXXFLAGS += -g3 | |
endif | |
ifeq ($(SANITIZE), 1) | |
CXXFLAGS += -fsanitize=address | |
endif | |
# Colors ans escape sequences | |
ESC_SEQ = \033[ | |
BLUE = $(ESC_SEQ)34m | |
YELLOW = $(ESC_SEQ)33m | |
GREEN = $(ESC_SEQ)32m | |
BOLD = $(ESC_SEQ)1m | |
MOVE_UP = $(ESC_SEQ)1A | |
ERASE = \r$(ESC_SEQ)K | |
ERASE_ALL = $(ESC_SEQ)M | |
ESC_STOP = $(ESC_SEQ)0m | |
# Variables used for cosmetic purposes | |
COMPILING_PRINTED = 0 | |
VARIABLES_PRINTED = 0 | |
VARIABLES_INTERLINE_PRINTED = 0 | |
PRINT_INTERLINE = printf '$(YELLOW)$(BOLD)================================================================================$(ESC_STOP)\n' | |
# Prevents the Makefile from recursively calling itself infinitely | |
# See $(OBJS) rule | |
NO_RECURS = 0 | |
# Draw a progress bar during while compiling the sources. | |
NUM_FILE_BEING_COMPILED = 1 | |
define DRAW_PROGRESS_BAR | |
PROGRESS_BAR=$(PROGRESS_BAR) \ | |
SIZE=$${#PROGRESS_BAR} \ | |
NB_BAR=`expr $(NUM_FILE_BEING_COMPILED) '*' $$SIZE / $(NB_FILES_TO_COMPILE)`; \ | |
printf '$(ERASE)$(BLUE)[ $(PROGRESS_BAR)$(BOLD) ][ %d / %d ]\r[ $(ESC_STOP)' \ | |
$(NUM_FILE_BEING_COMPILED) $(NB_FILES_TO_COMPILE); \ | |
for N in `seq $$NB_BAR`; \ | |
do printf '$(BOLD)$(BLUE)$(FILLING_CHAR)$(ESC_STOP)'; \ | |
done | |
endef | |
vpath %.cpp ./ $(shell find $(SRCS_DIR) -type d) | |
all: display_variables $(NAME) | |
$(NAME): $(OBJS) | display_variables | |
@$(PRINT_INTERLINE) | |
@printf '$(YELLOW)$(BOLD)linking object files$(ESC_STOP)\n' | |
@$(CXX) $(CXXFLAGS) $(OBJS) -o $(NAME) $(LDFLAGS) $(LDLIBS) | |
@$(PRINT_INTERLINE) | |
@printf '$(YELLOW)$(BOLD)%s$(ESC_STOP)$(YELLOW) built$(ESC_STOP)\n' '$@' | |
@$(PRINT_INTERLINE) | |
$(OBJS): $(OBJS_DIR)/%.o: %.cpp $(OBJS_DIR)/debug$(DEBUG) $(OBJS_DIR)/sanitize$(SANITIZE) | $(OBJS_DIR) | |
# This retrieves the number of files to be compiled / updated | |
# The $(NO_RECURS) variable prevents an infinite loop | |
ifeq ($(NO_RECURS), 0) | |
$(eval NB_FILES_TO_COMPILE ?= $(shell make NO_RECURS=1 --dry-run --debug=b | grep "does not\|Must remake" | grep -o "'.*\.o'" | sort | uniq | wc -l)) | |
endif | |
@if [ '$(COMPILING_PRINTED)' -eq '0' ]; then \ | |
if [ '$(VARIABLES_INTERLINE_PRINTED)' -eq '0' ]; then \ | |
$(PRINT_INTERLINE); \ | |
fi; \ | |
printf '$(BOLD)$(YELLOW)compiling sources$(ESC_STOP)\n'; \ | |
fi; $(eval COMPILING_PRINTED = 1) | |
@printf '%s\n' $@ | |
@$(DRAW_PROGRESS_BAR) | |
@$(CXX) $(CXXFLAGS) $(INCLUDES_DIR:%=-I %) -c $< -o $@ | |
@printf '$(ERASE)$(MOVE_UP)$(GREEN)%s$(ESC_STOP)\n' $@ | |
@if [ '$(NUM_FILE_BEING_COMPILED)' -eq '$(NB_FILES_TO_COMPILE)' ]; then \ | |
$(DRAW_PROGRESS_BAR); \ | |
printf '\n'; \ | |
fi; $(eval NUM_FILE_BEING_COMPILED = $(shell echo $$(($(NUM_FILE_BEING_COMPILED) + 1)))) | |
$(OBJS_DIR): | |
@$(MKDIR) $@ | |
# This two files prevent make from recompiling if the actual and the previous | |
# compilation was made using the -g3 and / or the -fsanitize=address | |
$(OBJS_DIR)/debug$(DEBUG): | $(OBJS_DIR) | |
@$(RM) $(OBJS_DIR)/debug0 $(OBJS_DIR)/debug1 | |
@touch $@ | |
$(OBJS_DIR)/sanitize$(SANITIZE): | $(OBJS_DIR) | |
@$(RM) $(OBJS_DIR)/sanitize0 $(OBJS_DIR)/sanitize1 | |
@touch $@ | |
display_variables: | |
@if [ '$(VARIABLES_PRINTED)' -eq '0' ]; then \ | |
$(PRINT_INTERLINE); \ | |
printf '$(YELLOW)executable name: $(BOLD)%s$(ESC_STOP)\n' '$(NAME)'; \ | |
printf '$(YELLOW)compiler:$(ESC_STOP) %s\n' '$(CXX)'; \ | |
printf '$(YELLOW)compilation flags:$(ESC_STOP) %s\n' '$(CXXFLAGS)'; \ | |
printf '$(YELLOW)libraries:$(ESC_STOP) %s\n' '$(LIBS)'; \ | |
printf '$(YELLOW)linking flags:$(ESC_STOP) %s\n' '$(LDFLAGS)'; \ | |
$(PRINT_INTERLINE); \ | |
fi; $(eval VARIABLES_PRINTED = 1) $(eval VARIABLES_INTERLINE_PRINTED = 1) | |
clean: | |
@$(RM) -r $(OBJS_DIR) | |
@printf '%s/ removed\n' '$(OBJS_DIR)' | |
fclean: clean | |
@$(RM) $(NAME) $(BONUS) | |
@printf '%s removed\n' '$(NAME)' | |
re: fclean all | |
-include $(DEPENDENCIES) | |
.PHONY: all clean fclean re display_variables |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# **************************************************************************** # | |
# # | |
# ::: :::::::: # | |
# settings.mk :+: :+: :+: # | |
# +:+ +:+ +:+ # | |
# By: rotrojan <marvin@42.fr> +#+ +:+ +#+ # | |
# +#+#+#+#+#+ +#+ # | |
# Created: 2021/10/21 21:06:11 by rotrojan #+# #+# # | |
# Updated: 2022/01/12 02:27:36 by bigo ### ########.fr # | |
# # | |
# **************************************************************************** # | |
# The name of the binary | |
NAME = name | |
# The list of the all the sources, because $(wildcard *.c) is too dangerous | |
SRCS = main.cpp \ | |
file.cpp \ | |
# The file where make will look for all the sources (in addition to the root | |
# directory of the Makefile) | |
SRCS_DIR = srcs | |
# The libraries used | |
LIBS = | |
# The directory where all object and dependency files will be compiled | |
OBJS_DIR = .objs | |
# The file where make will look for all the header files | |
INCLUDES_DIR = includes | |
# The C++ compiler | |
CXX = c++ | |
# The C++ compilation flags | |
CXXFLAGS = -Wall -Wextra -Werror -std=c++98 -pedantic | |
# The characters and the length of the progress bar will adjust automatically | |
PROGRESS_BAR = ------------------------------------------------------------------- | |
FILLING_CHAR = \# |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment