From: Dale Weiler Date: Fri, 17 Apr 2020 17:28:27 +0000 (-0400) Subject: new makefile X-Git-Tag: xonotic-v0.8.5~12 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=refs%2Fheads%2Fgraphitemaster%2Fmaster;p=xonotic%2Fgmqcc.git new makefile --- diff --git a/Makefile b/Makefile index f227d36..dc49416 100644 --- a/Makefile +++ b/Makefile @@ -1,100 +1,204 @@ -UNAME ?= $(shell uname) -CYGWIN = $(findstring CYGWIN, $(UNAME)) -MINGW = $(findstring MINGW, $(UNAME)) +# Compilation options: +# * LTO - Link time optimization [default=0] +# * ASAN - Address sanitizer [default=0] +# * UBSAN - Undefined behavior sanitizer [default=0] +# * DEBUG - Debug build [default=0] +# * UNUSED - Remove unused references [default=1] +# * SRCDIR - Out of tree builds [default=./] +LTO ?= 0 +ASAN ?= 0 +UBSAN ?= 0 +DEBUG ?= 0 +UNUSED ?= 1 +SRCDIR ?= ./ + +# Determine if we're building for Windows or not so we can set the right file +# extensions for the binaries and exclude the testsuite because it doesn't build +# for that platform. +ifeq ($(OS),Windows_NT) + GMQCC := gmqcc.exe + QCVM := qcvm.exe +else + GMQCC := gmqcc + QCVM := qcvm + TESTSUITE := testsuite +endif + +# C++ compiler +CXX ?= clang++ -ifneq ("$(CYGWIN)", "") -WINDOWS=1 +# Build artifact directories +OBJDIR := .build/objs +DEPDIR := .build/deps + +# Collect all the source files for GMQCC. +GSRCS := ast.cpp +GSRCS += code.cpp +GSRCS += conout.cpp +GSRCS += fold.cpp +GSRCS += ftepp.cpp +GSRCS += intrin.cpp +GSRCS += ir.cpp +GSRCS += lexer.cpp +GSRCS += main.cpp +GSRCS += opts.cpp +GSRCS += parser.cpp +GSRCS += stat.cpp +GSRCS += utf8.cpp +GSRCS += util.cpp + +# Collect all the source files for QCVM. +QSRCS := exec.cpp +QSRCS += stat.cpp +QSRCS += util.cpp + +# Collect all the source files for TESTSUITE. +TSRCS := conout.cpp +TSRCS += opts.cpp +TSRCS += stat.cpp +TSRCS += test.cpp +TSRCS += util.cpp + +# +# Compilation flags +# +CXXFLAGS := -Wall +CXXFLAGS += -Wextra +CXXFLAGS += -Wno-parentheses +CXXFLAGS += -Wno-class-memaccess +CXXFLAGS += -Wno-implicit-fallthrough +CXXFLAGS += -std=c++11 + +# Disable some unneeded features. +CXXFLAGS += -fno-exceptions +CXXFLAGS += -fno-rtti +CXXFLAGS += -fno-asynchronous-unwind-tables + +# Give each function and data it's own section so the linker can remove unused +# references to each, producing smaller, tighter binaries. +ifeq ($(UNUSED),1) + CXXFLAGS += -ffunction-sections + CXXFLAGS += -fdata-sections endif -ifneq ("$(MINGW)", "") -WINDOWS=1 + +# Enable link-time optimizations if requested. +ifeq ($(LTO),1) + CXXFLAGS += -flto endif -CXX ?= clang++ -CXXFLAGS = \ - -std=c++11 \ - -Wall \ - -Wextra \ - -Wno-parentheses \ - -Wno-class-memaccess \ - -fno-exceptions \ - -fno-rtti \ - -MD \ - -g3 - -CSRCS = \ - ast.cpp \ - code.cpp \ - conout.cpp \ - fold.cpp \ - ftepp.cpp \ - intrin.cpp \ - ir.cpp \ - lexer.cpp \ - main.cpp \ - opts.cpp \ - parser.cpp \ - stat.cpp \ - utf8.cpp \ - util.cpp - -TSRCS = \ - conout.cpp \ - opts.cpp \ - stat.cpp \ - test.cpp \ - util.cpp - -VSRCS = \ - exec.cpp \ - stat.cpp \ - util.cpp - -COBJS = $(CSRCS:.cpp=.o) -TOBJS = $(TSRCS:.cpp=.o) -VOBJS = $(VSRCS:.cpp=.o) - -CDEPS = $(CSRCS:.cpp=.d) -TDEPS = $(TSRCS:.cpp=.d) -VDEPS = $(VSRCS:.cpp=.d) - -ifndef WINDOWS -CBIN = gmqcc -VBIN = qcvm -TBIN = testsuite +ifeq ($(DEBUG),1) + # Ensure there is a frame-pointer in debug builds. + CXXFLAGS += -fno-omit-frame-pointer + + # Disable all optimizations in debug builds. + CXXFLAGS += -O0 + + # Enable debug symbols. + CXXFLAGS += -g else -CBIN = gmqcc.exe -VBIN = qcvm.exe + # Disable all the stack protection features in release builds. + CXXFLAGS += -fno-stack-protector + CXXFLAGS += -fno-stack-check + + # Disable frame pointer in release builds when AddressSanitizer isn't present. + ifeq ($(ASAN),1) + CXXFLAGS += -fno-omit-frame-pointer + else + CXXFLAGS += -fomit-frame-pointer + endif + + # Highest optimization flag in release builds. + CXXFLAGS += -O3 +endif + +# Sanitizer selection +ifeq ($(ASAN),1) + CXXFLAGS += -fsanitize=address +endif +ifeq ($(UBSAN),1) + CXXFLAGS += -fsanitize=undefined endif -ifndef WINDOWS -all: $(CBIN) $(QCVM) $(TBIN) +# +# Dependency flags +# +DEPFLAGS := -MMD +DEPFLAGS += -MP + +# +# Linker flags +# +LDFLAGS := + +# Remove unreferenced sections +ifeq ($(UNUSED),1) + LDFLAGS += -Wl,--gc-sections +endif + +# Enable link-time optimizations if request. +ifeq ($(LTO),1) + LDFLAGS += -flto +endif + +# Sanitizer selection +ifeq ($(ASAN),1) + LDFLAGS += -fsanitize=address +endif +ifeq ($(UBSAN),1) + LDFLAGS += -fsanitize=undefined +endif + +# Strip the binaries when not a debug build +ifneq (,$(findstring, -g,$(CXXFLAGS))) + STRIP := true else -all: $(CBIN) $(QCVM) + STRIP := strip endif -$(CBIN): $(COBJS) - $(CXX) $(COBJS) -o $@ +all: $(GMQCC) $(QCVM) $(TESTSUITE) + +# Build artifact directories. +$(DEPDIR): + @mkdir -p $(DEPDIR) +$(OBJDIR): + @mkdir -p $(OBJDIR) -$(VBIN): $(VOBJS) - $(CXX) $(VOBJS) -o $@ +$(OBJDIR)/%.o: %.cpp $(DEPDIR)/%.d | $(OBJDIR) $(DEPDIR) + $(CXX) -MT $@ $(DEPFLAGS) -MF $(DEPDIR)/$*.Td $(CXXFLAGS) -c -o $@ $< + @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d -ifndef WINDOWS -$(TBIN): $(TOBJS) - $(CXX) $(TOBJS) -o $@ +$(GMQCC): $(filter %.o,$(GSRCS:%.cpp=$(OBJDIR)/%.o)) + $(CXX) $^ $(LDFLAGS) -o $@ + $(STRIP) $@ -test: $(CBIN) $(VBIN) $(TBIN) - @./$(TBIN) +$(QCVM): $(filter %.o,$(QSRCS:%.cpp=$(OBJDIR)/%.o)) + $(CXX) $^ $(LDFLAGS) -o $@ + $(STRIP) $@ + +$(TESTSUITE): $(filter %.o,$(TSRCS:%.cpp=$(OBJDIR)/%.o)) + $(CXX) $^ $(LDFLAGS) -o $@ + $(STRIP) $@ + +# Determine if the tests should be run. +RUNTESTS := true +ifdef TESTSUITE + RUNTESTS := ./$(TESTSUITE) endif -.cpp.o: - $(CXX) -c $(CXXFLAGS) $< -o $@ +test: $(QCVM) $(TESTSUITE) + @$(RUNTESTS) clean: - rm -f *.d - rm -f $(COBJS) $(CDEPS) $(CBIN) - rm -f $(VOBJS) $(VDEPS) $(VBIN) -ifndef WINDOWS - rm -f $(TOBJS) $(TDEPS) $(TOBJS) -endif + rm -rf $(DEPDIR) $(OBJDIR) + +.PHONY: test clean $(DEPDIR) $(OBJDIR) + +# Dependencies +$(filter %.d,$(GSRCS:%.cpp=$(DEPDIR)/%.d)): +include $(wildcard $@) + +$(filter %.d,$(QSRCS:%.cpp=$(DEPDIR)/%.d)): +include $(wildcard $@) --include *.d +$(filter %.d,$(TSRCS:%.cpp=$(DEPDIR)/%.d)): +include $(wildcard $@)