X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=Makefile;h=dc49416daa8e60464c2a1812d2fcf42ffb6c15d1;hb=f971f89e1e239a74fd34f9f5369993b25d5432ed;hp=a032e87f53ba176ed64b683ed706bb1f4e1f32de;hpb=5b9e0a62abc5677d5cb49f7bad9a4382d8149e75;p=xonotic%2Fgmqcc.git diff --git a/Makefile b/Makefile index a032e87..dc49416 100644 --- a/Makefile +++ b/Makefile @@ -1,44 +1,204 @@ -CC ?= clang -CFLAGS = -MD -Wall -Wextra -pedantic-errors -LDFLAGS = -lm +# 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 ?= ./ -CSRCS = ansi.c ast.c code.c conout.c fold.c fs.c ftepp.c hash.c intrin.c ir.c lexer.c main.c opts.c parser.c stat.c utf8.c util.c -TSRCS = ansi.c conout.c fs.c hash.c opts.c stat.c test.c util.c -VSRCS = ansi.c exec.c fs.c hash.c stat.c util.c +# 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 -COBJS = $(CSRCS:.c=.o) -TOBJS = $(TSRCS:.c=.o) -VOBJS = $(VSRCS:.c=.o) +# C++ compiler +CXX ?= clang++ -CDEPS = $(CSRCS:.c=.d) -TDEPS = $(TSRCS:.c=.d) -VDEPS = $(VSRCS:.c=.d) +# Build artifact directories +OBJDIR := .build/objs +DEPDIR := .build/deps -CBIN = gmqcc -TBIN = testsuite -VBIN = qcvm +# 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 -all: $(CBIN) $(TBIN) $(VBIN) +# Collect all the source files for QCVM. +QSRCS := exec.cpp +QSRCS += stat.cpp +QSRCS += util.cpp -$(CBIN): $(COBJS) - $(CC) $(COBJS) $(LDFLAGS) -o $@ +# Collect all the source files for TESTSUITE. +TSRCS := conout.cpp +TSRCS += opts.cpp +TSRCS += stat.cpp +TSRCS += test.cpp +TSRCS += util.cpp -$(TBIN): $(TOBJS) - $(CC) $(TOBJS) $(LDFLAGS) -o $@ +# +# Compilation flags +# +CXXFLAGS := -Wall +CXXFLAGS += -Wextra +CXXFLAGS += -Wno-parentheses +CXXFLAGS += -Wno-class-memaccess +CXXFLAGS += -Wno-implicit-fallthrough +CXXFLAGS += -std=c++11 -$(VBIN): $(VOBJS) - $(CC) $(VOBJS) $(LDFLAGS) -o $@ +# Disable some unneeded features. +CXXFLAGS += -fno-exceptions +CXXFLAGS += -fno-rtti +CXXFLAGS += -fno-asynchronous-unwind-tables -.c.o: - $(CC) -c $(CFLAGS) $< -o $@ +# 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 -test: $(CBIN) $(TBIN) $(VBIN) - @./$(TBIN) +# Enable link-time optimizations if requested. +ifeq ($(LTO),1) + CXXFLAGS += -flto +endif + +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 + # 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 + +# +# 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 + STRIP := strip +endif + +all: $(GMQCC) $(QCVM) $(TESTSUITE) + +# Build artifact directories. +$(DEPDIR): + @mkdir -p $(DEPDIR) +$(OBJDIR): + @mkdir -p $(OBJDIR) + +$(OBJDIR)/%.o: %.cpp $(DEPDIR)/%.d | $(OBJDIR) $(DEPDIR) + $(CXX) -MT $@ $(DEPFLAGS) -MF $(DEPDIR)/$*.Td $(CXXFLAGS) -c -o $@ $< + @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d + +$(GMQCC): $(filter %.o,$(GSRCS:%.cpp=$(OBJDIR)/%.o)) + $(CXX) $^ $(LDFLAGS) -o $@ + $(STRIP) $@ + +$(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 + +test: $(QCVM) $(TESTSUITE) + @$(RUNTESTS) clean: - rm -f *.d - rm -f $(COBJS) $(CDEPS) $(CBIN) - rm -f $(TOBJS) $(TDEPS) $(TBIN) - rm -f $(VOBJS) $(VDEPS) $(VBIN) + 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 $@)