new makefile

This commit is contained in:
Dale Weiler 2020-04-17 13:28:27 -04:00
parent 94c2936bfa
commit f971f89e1e

256
Makefile
View file

@ -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 ?= ./
ifneq ("$(CYGWIN)", "")
WINDOWS=1
endif
ifneq ("$(MINGW)", "")
WINDOWS=1
# 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++
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
# Build artifact directories
OBJDIR := .build/objs
DEPDIR := .build/deps
TSRCS = \
conout.cpp \
opts.cpp \
stat.cpp \
test.cpp \
util.cpp
# 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
VSRCS = \
exec.cpp \
stat.cpp \
util.cpp
# Collect all the source files for QCVM.
QSRCS := exec.cpp
QSRCS += stat.cpp
QSRCS += util.cpp
COBJS = $(CSRCS:.cpp=.o)
TOBJS = $(TSRCS:.cpp=.o)
VOBJS = $(VSRCS:.cpp=.o)
# Collect all the source files for TESTSUITE.
TSRCS := conout.cpp
TSRCS += opts.cpp
TSRCS += stat.cpp
TSRCS += test.cpp
TSRCS += util.cpp
CDEPS = $(CSRCS:.cpp=.d)
TDEPS = $(TSRCS:.cpp=.d)
VDEPS = $(VSRCS:.cpp=.d)
#
# Compilation flags
#
CXXFLAGS := -Wall
CXXFLAGS += -Wextra
CXXFLAGS += -Wno-parentheses
CXXFLAGS += -Wno-class-memaccess
CXXFLAGS += -Wno-implicit-fallthrough
CXXFLAGS += -std=c++11
ifndef WINDOWS
CBIN = gmqcc
VBIN = qcvm
TBIN = testsuite
# 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
# 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
ifndef WINDOWS
all: $(CBIN) $(QCVM) $(TBIN)
# 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
all: $(CBIN) $(QCVM)
STRIP := strip
endif
$(CBIN): $(COBJS)
$(CXX) $(COBJS) -o $@
all: $(GMQCC) $(QCVM) $(TESTSUITE)
$(VBIN): $(VOBJS)
$(CXX) $(VOBJS) -o $@
# Build artifact directories.
$(DEPDIR):
@mkdir -p $(DEPDIR)
$(OBJDIR):
@mkdir -p $(OBJDIR)
ifndef WINDOWS
$(TBIN): $(TOBJS)
$(CXX) $(TOBJS) -o $@
$(OBJDIR)/%.o: %.cpp $(DEPDIR)/%.d | $(OBJDIR) $(DEPDIR)
$(CXX) -MT $@ $(DEPFLAGS) -MF $(DEPDIR)/$*.Td $(CXXFLAGS) -c -o $@ $<
@mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
test: $(CBIN) $(VBIN) $(TBIN)
@./$(TBIN)
$(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
.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)
-include *.d
.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 $@)