X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=Makefile;h=dc49416daa8e60464c2a1812d2fcf42ffb6c15d1;hp=6f8eb9a82732f86b3ebc2619a6ec461eb3fe819b;hb=f971f89e1e239a74fd34f9f5369993b25d5432ed;hpb=655c2482c97a30c3634c22a13f0ea43f946677b5 diff --git a/Makefile b/Makefile index 6f8eb9a..dc49416 100644 --- a/Makefile +++ b/Makefile @@ -1,166 +1,204 @@ -include include.mk - -UNAME ?= $(shell uname) -CYGWIN = $(findstring CYGWIN, $(UNAME)) -MINGW = $(findstring MINGW, $(UNAME)) - -CFLAGS += -Wall -Wextra -Werror -Wstrict-aliasing -Wno-attributes -O3 -#turn on tons of warnings if clang is present -# but also turn off the STUPID ONES -ifeq ($(CC), clang) - CFLAGS += \ - -Weverything \ - -Wno-padded \ - -Wno-format-nonliteral \ - -Wno-disabled-macro-expansion \ - -Wno-conversion \ - -Wno-float-equal \ - -Wno-unknown-warning-option \ - -Wno-cast-align \ - -Wno-assign-enum \ - -pedantic-errors +# 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 - ifneq ($(CC), g++) - CFLAGS += -Wmissing-prototypes -Wstrict-prototypes - endif + GMQCC := gmqcc + QCVM := qcvm + TESTSUITE := testsuite +endif + +# C++ compiler +CXX ?= clang++ + +# 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 + +# 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 - ifneq ($(CC), tcc) - CFLAGS += -pedantic-errors + # 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 - CFLAGS += -Wno-pointer-sign -fno-common + 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 -ifneq ($(shell git describe --always 2>/dev/null),) - CFLAGS += -DGMQCC_GITINFO="\"$(shell git describe --always)\"" +# +# Linker flags +# +LDFLAGS := + +# Remove unreferenced sections +ifeq ($(UNUSED),1) + LDFLAGS += -Wl,--gc-sections endif -ifeq ($(shell valgrind --version 2>/dev/null),) - CFLAGS += -DNVALGRIND +# Enable link-time optimizations if request. +ifeq ($(LTO),1) + LDFLAGS += -flto endif -# do this last otherwise there is whitespace in the command output and -# it makes my OCD act up -CFLAGS += $(OPTIONAL_CFLAGS) -LDFLAGS += $(OPTIONAL_LDFLAGS) - -#we have duplicate object files when dealing with creating a simple list -#for dependinces. To combat this we use some clever recrusive-make to -#filter the list and remove duplicates which we use for make depend -RMDUP = $(if $1,$(firstword $1) $(call RMDUP,$(filter-out $(firstword $1),$1))) -DEPS := $(call RMDUP, $(OBJ_P) $(OBJ_T) $(OBJ_C) $(OBJ_X)) - -ifneq ("$(CYGWIN)", "") - #nullify the common variables that - #most *nix systems have (for windows) - PREFIX := - BINDIR := - DATADIR := - MANDIR := - QCVM = qcvm.exe - GMQCC = gmqcc.exe - TESTSUITE = testsuite.exe - PAK = gmqpak.exe - CFLAGS += -DNVALGRIND -else -ifneq ("$(MINGW)", "") - #nullify the common variables that - #most *nix systems have (for windows) - PREFIX := - BINDIR := - DATADIR := - MANDIR := - QCVM = qcvm.exe - GMQCC = gmqcc.exe - TESTSUITE = testsuite.exe - PAK = gmqpak.exe - CFLAGS += -DNVALGRIND -else - QCVM = qcvm - GMQCC = gmqcc - TESTSUITE = testsuite - PAK = gmqpak +# Sanitizer selection +ifeq ($(ASAN),1) + LDFLAGS += -fsanitize=address endif +ifeq ($(UBSAN),1) + LDFLAGS += -fsanitize=undefined endif -#standard rules -c.o: - $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) +# Strip the binaries when not a debug build +ifneq (,$(findstring, -g,$(CXXFLAGS))) + STRIP := true +else + STRIP := strip +endif -$(QCVM): $(OBJ_X) - $(CC) -o $@ $^ $(LDFLAGS) $(LIBS) +all: $(GMQCC) $(QCVM) $(TESTSUITE) -$(GMQCC): $(OBJ_C) $(OBJ_D) - $(CC) -o $@ $^ $(LDFLAGS) $(LIBS) +# Build artifact directories. +$(DEPDIR): + @mkdir -p $(DEPDIR) +$(OBJDIR): + @mkdir -p $(OBJDIR) -$(TESTSUITE): $(OBJ_T) - $(CC) -o $@ $^ $(LDFLAGS) $(LIBS) +$(OBJDIR)/%.o: %.cpp $(DEPDIR)/%.d | $(OBJDIR) $(DEPDIR) + $(CXX) -MT $@ $(DEPFLAGS) -MF $(DEPDIR)/$*.Td $(CXXFLAGS) -c -o $@ $< + @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d -$(PAK): $(OBJ_P) - $(CC) -o $@ $^ $(LDFLAGS) +$(GMQCC): $(filter %.o,$(GSRCS:%.cpp=$(OBJDIR)/%.o)) + $(CXX) $^ $(LDFLAGS) -o $@ + $(STRIP) $@ -all: $(GMQCC) $(QCVM) $(TESTSUITE) $(PAK) +$(QCVM): $(filter %.o,$(QSRCS:%.cpp=$(OBJDIR)/%.o)) + $(CXX) $^ $(LDFLAGS) -o $@ + $(STRIP) $@ -check: all - @ ./$(TESTSUITE) -test: all - @ ./$(TESTSUITE) +$(TESTSUITE): $(filter %.o,$(TSRCS:%.cpp=$(OBJDIR)/%.o)) + $(CXX) $^ $(LDFLAGS) -o $@ + $(STRIP) $@ -strip: $(GMQCC) $(QCVM) $(TESTSUITE) - strip $(GMQCC) - strip $(QCVM) - strip $(TESTSUITE) +# Determine if the tests should be run. +RUNTESTS := true +ifdef TESTSUITE + RUNTESTS := ./$(TESTSUITE) +endif + +test: $(QCVM) $(TESTSUITE) + @$(RUNTESTS) clean: - rm -rf *.o $(GMQCC) $(QCVM) $(TESTSUITE) $(PAK) *.dat gource.mp4 *.exe gm-qcc.tgz ./cov-int - -depend: - @ makedepend -Y -w 65536 2> /dev/null $(subst .o,.c,$(DEPS)) - - -coverity: - @cov-build --dir cov-int $(MAKE) - @tar czf gm-qcc.tgz cov-int - @rm -rf cov-int - @echo gm-qcc.tgz generated, submit for analysis - -#install rules -install: install-gmqcc install-qcvm install-gmqpak install-doc -install-gmqcc: $(GMQCC) - install -d -m755 $(DESTDIR)$(BINDIR) - install -m755 $(GMQCC) $(DESTDIR)$(BINDIR)/$(GMQCC) -install-qcvm: $(QCVM) - install -d -m755 $(DESTDIR)$(BINDIR) - install -m755 $(QCVM) $(DESTDIR)$(BINDIR)/$(QCVM) -install-gmqpak: $(PAK) - install -d -m755 $(DESTDIR)$(BINDIR) - install -m755 $(PAK) $(DESTDIR)$(BINDIR)/$(PAK) -install-doc: - install -d -m755 $(DESTDIR)$(MANDIR)/man1 - install -m644 doc/gmqcc.1 $(DESTDIR)$(MANDIR)/man1/ - install -m644 doc/qcvm.1 $(DESTDIR)$(MANDIR)/man1/ - install -m644 doc/gmqpak.1 $(DESTDIR)$(MANDIR)/man1/ - -# DO NOT DELETE - -ansi.o: platform.h gmqcc.h opts.def -util.o: gmqcc.h opts.def platform.h -hash.o: gmqcc.h opts.def -stat.o: gmqcc.h opts.def -fs.o: gmqcc.h opts.def platform.h -opts.o: gmqcc.h opts.def -conout.o: gmqcc.h opts.def -pak.o: gmqcc.h opts.def -test.o: gmqcc.h opts.def platform.h -main.o: gmqcc.h opts.def lexer.h -lexer.o: gmqcc.h opts.def lexer.h -parser.o: parser.h gmqcc.h opts.def lexer.h ast.h ir.h -code.o: gmqcc.h opts.def -ast.o: gmqcc.h opts.def ast.h ir.h parser.h lexer.h -ir.o: gmqcc.h opts.def ir.h -ftepp.o: gmqcc.h opts.def lexer.h -utf8.o: gmqcc.h opts.def -correct.o: gmqcc.h opts.def -fold.o: ast.h ir.h gmqcc.h opts.def parser.h lexer.h -intrin.o: parser.h gmqcc.h opts.def lexer.h ast.h ir.h -exec.o: gmqcc.h opts.def + 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 $@) + +$(filter %.d,$(TSRCS:%.cpp=$(DEPDIR)/%.d)): +include $(wildcard $@)