edmonds-matching-algorithm/Makefile

132 lines
3.0 KiB
Makefile

# Configuration (File extensions, tools to be used, etc)
OPTLIBEXT=-O
DEBUGLIBEXT=-g
LIBEXTS=$(OPTLIBEXT) $(DEBUGLIBEXT)
ifeq "$(MAKECMDGOALS)" "opt"
LIBEXT=$(OPTLIBEXT)
OPTFLAGS=$(OPTFLAGS_OPT)
else
LIBEXT=$(DEBUGLIBEXT)
OPTFLAGS=$(OPTFLAGS_DEBUG)
endif
CXX=clang++
CC=clang
LN=ln
RM=rm
MKDIR=mkdir
TOUCH=touch
DIRNAME=dirname
OPTFLAGS_OPT=-O3
OPTFLAGS_DEBUG=-O0 -g
# flags used for linking and compilation
FLAGS=#
# These flags are for compilation (not linking) only
# -MMD auto-genenerates .d files in Make format when .o files are created
COMPILE_FLAGS=-MMD -Werror -Wall -Wextra -pedantic -pipe $(OPTFLAGS)
# Flags for linking only.
LINK_FLAGS=-fuse-ld=gold
# C / C++ specific compilation flags
CXX_STD_FLAGS=-std=c++20
CXX_COMPILE_FLAGS=$(CXX_STD_FLAGS)
C_STD_FLAGS=-std=c99
C_COMPILE_FLAGS=$(C_STD_FLAGS)
CXX_SRC_EXTS=cpp C CPP
C_SRC_EXTS=c
SRC_EXTS=$(CXX_SRC_EXTS) $(C_SRC_EXTS)
BUILDDIR=build
DIRECTORIES=$(BUILDDIR)
EXECUTABLE_REL=main
LINK_NAME=$(BUILDDIR)/$(EXECUTABLE_REL)
EXECUTABLE=$(LINK_NAME)$(LIBEXT)
# Collect files to be compiled
CXX_SRCS=$(foreach ext, $(CXX_SRC_EXTS), $(shell find src -name "*.$(ext)"))
C_SRCS=$(foreach ext, $(C_SRC_EXTS), $(shell find src -name "*.$(ext)"))
SRCS=$(CXX_SRCS) $(C_SRCS)
OBJS=$(foreach ext, $(SRC_EXTS), $(patsubst %.$(ext), $(BUILDDIR)/%$(LIBEXT).o, $(filter %.$(ext), $(SRCS))))
# If there is at least one C++ source use the c++ compiler CXX to link.
LINKER=$(CC) $(FLAGS) $(LINK_FLAGS)
ifneq "$(strip $(CXX_SRCS))" ""
LINKER=$(CXX) $(FLAGS) $(LINK_FLAGS)
endif
MAKECONFIG=Make.config
# The set of Make-files influencing the build, hence everything depends on them
MAKE_DEPENDENCIES=Makefile $(MAKECONFIG)
DEFAULT_TARGET=debug
# Include Make.config to modify variables above
-include $(MAKECONFIG)
# The supported meta targets, dependencies
.PHONY: clean debug opt default check
default: $(DEFAULT_TARGET)
clean debug opt: check
opt debug: $(EXECUTABLE)
$(OBJS) : $(MAKE_DEPENDENCIES) | $(BUILDDIR)
# include autogenerated .d files
-include $(OBJS:.o=.d)
# Rules
define CXX_TO_OBJ
$(CXX) $(FLAGS) $(CXX_COMPILE_FLAGS) $(COMPILE_FLAGS) $< -c -o $@
endef
define C_TO_OBJ
$(CC) $(FLAGS) $(C_COMPILE_FLAGS) $(COMPILE_FLAGS) $< -c -o $@
endef
define MK_TARGETDIR
@$(MKDIR) -p $$($(DIRNAME) $@)
endef
$(BUILDDIR)/%$(LIBEXT).o: %.cpp
$(MK_TARGETDIR)
$(CXX_TO_OBJ)
$(BUILDDIR)/%$(LIBEXT).o: %.C
$(MK_TARGETDIR)
$(CXX_TO_OBJ)
$(BUILDDIR)/%$(LIBEXT).o: %.CPP
$(MK_TARGETDIR)
$(CXX_TO_OBJ)
$(BUILDDIR)/%$(LIBEXT).o: %.c
$(MK_TARGETDIR)
$(C_TO_OBJ)
$(EXECUTABLE): $(OBJS) | $(BUILDDIR)
$(LINKER) $(OBJS) -o $@
# Create link in opt/debug target
opt debug:
$(LN) -sf $(EXECUTABLE_REL)$(LIBEXT) $(LINK_NAME)
check: $(BUILDDIR)
@forbidden=$$(find $(BUILDDIR) -not -type d $(foreach filext, .o .d, -not -name "*$(filext)") $(foreach libext, $(LIBEXTS) "", -not -name "$(EXECUTABLE_REL)$(libext)")); \
if [ "$${forbidden}x" != "x" ]; then echo "Error: $(BUILDDIR) contains non-autogenerated files $${forbidden}"; exit 1; fi
$(DIRECTORIES):
@$(MKDIR) $@
$(MAKECONFIG):
@$(TOUCH) $@
clean:
@$(RM) -rf $(BUILDDIR)