diff --git a/makefile.library b/makefile.library index 6a73227..9e2f8c5 100644 --- a/makefile.library +++ b/makefile.library @@ -11,7 +11,7 @@ #You should have received a copy of the GNU General Public License #along with this program. If not, see . -#Copyright 2018-2019 rexy712 +#Copyright 2018-2020 rexy712 #Makefile to generate a single static or shared library from all the sources in SOURCE_DIRS ending in EXT @@ -28,9 +28,11 @@ CFLAGS::=-g -std=c18 -Wall -pedantic -Wextra CXXFLAGS::=-g -std=c++17 -Wall -pedantic -Wextra EXT::=cpp LANG::=$(EXT) -MAIN_LIBRARY::=test -DLLOUT::=$(MAIN_LIBRARY).dll +MAIN_LIBRARY::=tester +PRE_TARGETS::= +POST_TARGETS::= SHARED?=1 +STATIC?=0 RELEASE?=0 MEMCHK?=0 @@ -45,8 +47,8 @@ ifneq ($(WINDOWS),1) AR::=ar AS::=as else #windows - #windows is a fuckwit #windows settings + #windows is a fuckwit MINGW_PREFIX::=x86_64-w64-mingw32- CC::=$(MINGW_PREFIX)gcc CXX::=$(MINGW_PREFIX)g++ @@ -58,15 +60,25 @@ else #windows AS::=$(MINGW_PREFIX)as endif #windows -ifeq ($(SHARED),1) - ifeq ($(WINDOWS),1) - INTERNAL_MAIN_LIBRARY::=lib$(MAIN_LIBRARY).a - else - INTERNAL_MAIN_LIBRARY::=lib$(MAIN_LIBRARY).so - endif +#Put your custom targets for PRE_TARGETS and POST_TARGETS here: + + + +########################################################################################################### +#Everything past this point is internal BS, probably best not to touch it unless you know what you're doing + +#set the all target as the default target, otherwise the topmost target will run +.DEFAULT_GOAL::=all + +#setup the actual output library name depending on shared/static and windows/anything else +ifeq ($(WINDOWS),1) + INTERNAL_SHARED_LIBRARY::=lib$(MAIN_LIBRARY).a else - INTERNAL_MAIN_LIBRARY::=lib$(MAIN_LIBRARY).a + INTERNAL_SHARED_LIBRARY::=lib$(MAIN_LIBRARY).so endif +SHARED_LIBRARY_FLAGS=-fPIC +DLLOUT::=$(MAIN_LIBRARY).dll +INTERNAL_STATIC_LIBRARY::=lib$(MAIN_LIBRARY).a #system dependant bullshit @@ -98,6 +110,7 @@ endif ifeq ($(RELEASE),1) #a lot of false strict aliasing warnings from gcc 9 COMPILER_FLAGS+=-O2 -Wno-strict-aliasing + POST_TARGETS+= do_strip else ifeq ($(MEMCHK),1) #use asan to check memory leaks/invalid accesses LDFLAGS+=-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls @@ -107,35 +120,67 @@ else COMPILER_FLAGS+=-O0 -g3 -ggdb endif +#add dependency tracking and include directories INTERNAL_COMPILERFLAGS=-c $(foreach dir,$(INCLUDE_DIRS),-I"$(dir)") -MMD -MP -MF"$(DEPDIR)/$(notdir $(patsubst %.o,%.d,$@))" ifeq ($(SHARED),1) - INTERNAL_COMPILERFLAGS+=-fPIC + INTERNAL_COMPILERFLAGS+=$(SHARED_LIBRARY_FLAGS) endif +THIS_MAKEFILE_NAME::=$(lastword $(MAKEFILE_LIST)) SOURCES::=$(foreach source,$(SOURCE_DIRS),$(foreach ext,$(EXT),$(wildcard $(source)/*.$(ext)))) OBJECTS::=$(addprefix $(OBJDIR)/,$(subst \,.,$(subst /,.,$(addsuffix .o,$(SOURCES))))) -.PHONY: all +#generate a command to run a submake using this same makefile without printing "Entering directory" stuff +#note: the empty line is required in this definition +define RUN_SUBMAKE_TARGET + @$(MAKE) --no-print-directory -f "$(THIS_MAKEFILE_NAME)" "$(1)" $(2) +endef + +#default target: run targets in PRE_TARGETS, then build the main library, then POST_TARGETS +.PHONY: all +all: + $(foreach target,$(PRE_TARGETS),$(call RUN_SUBMAKE_TARGET,$(target))) ifeq ($(SHARED),1) ifeq ($(WINDOWS),1) -#target for windows shared library -all: $(DLLOUT) -$(INTERNAL_MAIN_LIBRARY): $(OBJECTS) - $(COMPILER) -shared -o "$(DLLOUT)" $^ -Wl,--out-implib,"lib$(MAIN_LIBRARY).a" $(LDLIBS) $(LDFLAGS) -$(DLLOUT): $(INTERNAL_MAIN_LIBRARY) + $(call RUN_SUBMAKE_TARGET,$(DLLOUT)) else #windows -#target for *nix shared library -all: $(INTERNAL_MAIN_LIBRARY) -$(INTERNAL_MAIN_LIBRARY): $(OBJECTS) - $(COMPILER) -shared -o "$@" $^ $(COMPILER_FLAGS) $(LDFLAGS) $(LDLIBS) + $(call RUN_SUBMAKE_TARGET,$(INTERNAL_SHARED_LIBRARY)) endif #windows -else #shared +endif #shared +ifeq ($(STATIC),1) +ifeq ($(SHARED),1) + $(call RUN_SUBMAKE_TARGET,object_clean) +endif #shared + $(call RUN_SUBMAKE_TARGET,$(INTERNAL_STATIC_LIBRARY),SHARED=0) +endif #static + $(foreach target,$(POST_TARGETS),$(call RUN_SUBMAKE_TARGET,$(target))) + +ifeq ($(WINDOWS),1) +#target for windows shared library +$(DLLOUT): $(OBJECTS) + $(COMPILER) -shared -o "$(DLLOUT)" $^ -Wl,--out-implib,"lib$(MAIN_LIBRARY).a" $(SHARED_LIBRARY_FLAGS) $(LDLIBS) $(LDFLAGS) +else #windows + +#target for *nix shared library +$(INTERNAL_SHARED_LIBRARY): $(OBJECTS) + $(COMPILER) -shared -o "$@" $^ $(COMPILER_FLAGS) $(SHARED_LIBRARY_FLAGS) $(LDFLAGS) $(LDLIBS) +endif #windows + #target for static library -all: $(INTERNAL_MAIN_LIBRARY) -$(INTERNAL_MAIN_LIBRARY): $(OBJECTS) +$(INTERNAL_STATIC_LIBRARY): $(OBJECTS) $(AR) rcs "$@" $^ $(RANLIB) "$@" -endif #shared + + +#Called in POST_TARGETS when RELEASE=1 +.PHONY: do_strip +do_strip: +ifeq ($(SHARED),1) + $(STRIP) --strip-debug "$(INTERNAL_SHARED_LIBRARY)" +endif +ifeq ($(STATIC),1) + $(STRIP) --strip-debug "$(INTERNAL_STATIC_LIBRARY)" +endif #Object target recipe define GENERATE_OBJECTS @@ -152,10 +197,13 @@ $(OBJDIR): $(DEPDIR): $(call mkdir,"$@") -.PHONY: clean -clean: - $(call rmdir,"$(DEPDIR)") +.PHONY: object_clean +object_clean: $(call rmdir,"$(OBJDIR)") + +.PHONY: clean +clean: object_clean + $(call rmdir,"$(DEPDIR)") $(call rm,"lib$(MAIN_LIBRARY).so") $(call rm,"lib$(MAIN_LIBRARY).a") $(call rm,"$(DLLOUT)")