X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=Makefile;h=dc49416daa8e60464c2a1812d2fcf42ffb6c15d1;hp=2e5c1eea8323b4cac1b55e9933f8d22014c7baa6;hb=f971f89e1e239a74fd34f9f5369993b25d5432ed;hpb=144672fada7324651eabbbd0eaec68ed4dd031c1 diff --git a/Makefile b/Makefile index 2e5c1ee..dc49416 100644 --- a/Makefile +++ b/Makefile @@ -1,253 +1,204 @@ -DESTDIR := -OPTIONAL:= -PREFIX := /usr/local -BINDIR := $(PREFIX)/bin -DATADIR := $(PREFIX)/share -MANDIR := $(DATADIR)/man - -UNAME ?= $(shell uname) -CYGWIN = $(findstring CYGWIN, $(UNAME)) -MINGW = $(findstring MINGW32, $(UNAME)) - -CC ?= clang -# linker flags and optional additional libraries if required -LDFLAGS += -LIBS += -lm - -CFLAGS += -Wall -Wextra -Werror -fno-strict-aliasing $(OPTIONAL) -ifneq ($(shell git describe --always 2>/dev/null),) - CFLAGS += -DGMQCC_GITINFO="\"$(shell git describe --always)\"" +# 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++ + +# 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 -#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-missing-prototypes \ - -Wno-float-equal \ - -Wno-unknown-warning-option \ - -Wstrict-prototypes + +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 - #Tiny C Compiler doesn't know what -pedantic-errors is - # and instead of ignoring .. just errors. - ifneq ($(CC), tcc) - CFLAGS += -Wstrict-prototypes -pedantic-errors + # 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 -ifeq ($(track), no) - CFLAGS += -DNOTRACK +# Sanitizer selection +ifeq ($(ASAN),1) + CXXFLAGS += -fsanitize=address +endif +ifeq ($(UBSAN),1) + CXXFLAGS += -fsanitize=undefined endif -OBJ_D = util.o code.o ast.o ir.o conout.o ftepp.o opts.o fs.o utf8.o correct.o stat.o -OBJ_P = util.o fs.o conout.o opts.o pak.o stat.o -OBJ_T = test.o util.o conout.o fs.o stat.o -OBJ_C = main.o lexer.o parser.o fs.o stat.o -OBJ_X = exec-standalone.o util.o conout.o fs.o stat.o - -#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_D) $(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 = pak.exe -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 +# +# 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 - QCVM = qcvm - GMQCC = gmqcc - TESTSUITE = testsuite - PAK = gmqpak + 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 -#gource flags -GOURCEFLAGS= \ - --date-format "%d %B, %Y" \ - --seconds-per-day 0.01 \ - --auto-skip-seconds 1 \ - --title "GMQCC" \ - --key \ - --camera-mode overview \ - --highlight-all-users \ - --file-idle-time 0 \ - --hide progress,mouse \ - --stop-at-end \ - --max-files 99999999999 \ - --max-file-lag 0.000001 \ - --bloom-multiplier 1.3 \ - --logo doc/html/gmqcc.png \ - -1280x720 - -#ffmpeg flags for gource -FFMPEGFLAGS= \ - -y \ - -r 60 \ - -f image2pipe \ - -vcodec ppm \ - -i - \ - -vcodec libx264 \ - -preset ultrafast \ - -crf 1 \ - -threads 0 \ - -bf 0 - -#splint flags -SPLINTFLAGS = \ - -redef \ - -noeffect \ - -nullderef \ - -usedef \ - -type \ - -mustfreeonly \ - -nullstate \ - -varuse \ - -mustfreefresh \ - -compdestroy \ - -compmempass \ - -nullpass \ - -onlytrans \ - -predboolint \ - -boolops \ - -incondefs \ - -macroredef \ - -retvalint \ - -nullret \ - -predboolothers \ - -globstate \ - -dependenttrans \ - -branchstate \ - -compdef \ - -temptrans \ - -usereleased \ - -warnposix \ - +charindex \ - -kepttrans \ - -unqualifiedtrans \ - +matchanyintegral \ - +voidabstract \ - -nullassign \ - -unrecog \ - -casebreak \ - -retvalbool \ - -retvalother \ - -mayaliasunique \ - -realcompare \ - -observertrans \ - -abstract \ - -statictrans \ - -castfcnptr - -#standard rules -default: all -%.o: %.c - $(CC) -c $< -o $@ $(CPPFLAGS) $(CFLAGS) - -exec-standalone.o: exec.c - $(CC) -c $< -o $@ $(CPPFLAGS) $(CFLAGS) -DQCVM_EXECUTOR=1 - -$(QCVM): $(OBJ_X) - $(CC) -o $@ $^ $(LDFLAGS) $(LIBS) - -$(GMQCC): $(OBJ_C) $(OBJ_D) - $(CC) -o $@ $^ $(LDFLAGS) $(LIBS) - -$(TESTSUITE): $(OBJ_T) - $(CC) -o $@ $^ $(LDFLAGS) $(LIBS) - -$(PAK): $(OBJ_P) - $(CC) -o $@ $^ $(LDFLAGS) - -all: $(GMQCC) $(QCVM) $(TESTSUITE) $(PAK) - -check: all - @ ./$(TESTSUITE) -test: all - @ ./$(TESTSUITE) +test: $(QCVM) $(TESTSUITE) + @$(RUNTESTS) clean: - rm -f *.o $(GMQCC) $(QCVM) $(TESTSUITE) $(PAK) *.dat gource.mp4 *.exe - -splint: - @ splint $(SPLINTFLAGS) *.c *.h - -gource: - @ gource $(GOURCEFLAGS) - -gource-record: - @ gource $(GOURCEFLAGS) -o - | ffmpeg $(FFMPEGFLAGS) gource.mp4 - -depend: - @makedepend -Y -w 65536 2> /dev/null \ - $(subst .o,.c,$(DEPS)) - -#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/ - -uninstall: - rm -f $(DESTDIR)$(BINDIR)/gmqcc - rm -f $(DESTDIR)$(BINDIR)/qcvm - rm -f $(DESTDIR)$(BINDIR)/gmqpak - rm -f $(DESTDIR)$(MANDIR)/man1/doc/gmqcc.1 - rm -f $(DESTDIR)$(MANDIR)/man1/doc/qcvm.1 - rm -f $(DESTDIR)$(MANDIR)/man1/doc/gmqpak.1 - -# DO NOT DELETE - -util.o: gmqcc.h opts.def -code.o: gmqcc.h opts.def -ast.o: gmqcc.h opts.def ast.h ir.h -ir.o: gmqcc.h opts.def ir.h -conout.o: gmqcc.h opts.def -ftepp.o: gmqcc.h opts.def lexer.h -opts.o: gmqcc.h opts.def -fs.o: gmqcc.h opts.def -utf8.o: gmqcc.h opts.def -correct.o: gmqcc.h opts.def -stat.o: gmqcc.h opts.def -pak.o: gmqcc.h opts.def -test.o: gmqcc.h opts.def -main.o: gmqcc.h opts.def lexer.h -lexer.o: gmqcc.h opts.def lexer.h -parser.o: gmqcc.h opts.def lexer.h ast.h ir.h intrin.h + 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 $@)