Skip to content
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
/build/
/release/
/release/
*.mk
*.user
*.d
141 changes: 123 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,54 @@
# - Windows #
# ----------------------------------------------------- #

# Variables
# ---------
# ASAN
# Builds with address sanitizer, includes DEBUG.
# DEBUG
# Builds a debug build, forces -O0 and adds debug symbols.
# MINGW_CHOST
# If you use mingw this can specify architecture.
# Available values:
# x86_64-w64-mingw32 -> indicates x86_64
# i686-w64-mingw32 -> indicates i386
# QUIET
# If defined, "===> CC ..." lines are silenced.
# SOURCE_DATE_EPOCH
# For reproduceable builds, look here for details:
# https://reproducible-builds.org/specs/source-date-epoch/
# If set, adds a BUILD_DATE define to CFLAGS.
# UBSAN
# Builds with undefined behavior sanitizer.includes DEBUG.
# VERBOSE
# Prints full compile, linker and misc commands.
# WERR
# Treat compiler warnings as errors.
# If defined, -Werror is added to compiler flags.
# ----------

# User configurable options
# -------------------------

# CONFIG_FILE
# This is an optional configuration file, it'll be used in
# case of presence.
CONFIG_FILE:=config.mk

# ----------

# In case of a configuration file being present, we'll just use it
ifeq ($(wildcard $(CONFIG_FILE)), $(CONFIG_FILE))
include $(CONFIG_FILE)
endif

# Normalize QUIET value to either "x" or ""
ifdef QUIET
override QUIET := "x"
else
override QUIET := ""
endif

# Detect the OS
ifdef SystemRoot
YQ2_OSTYPE ?= Windows
Expand Down Expand Up @@ -71,24 +119,58 @@ else
COMPILER := unknown
endif

# ASAN includes DEBUG
ifdef ASAN
DEBUG=1
endif

# UBSAN includes DEBUG
ifdef UBSAN
DEBUG=1
endif

# ----------

# Set up build and bin output directories

# Root dir names
override BINROOT :=
override BUILDROOT := build

override BINDIR := $(BINROOT)release
override BUILDDIR := $(BUILDROOT)

# ----------

# Base CFLAGS. These may be overridden by the environment.
# Highest supported optimizations are -O2, higher levels
# will likely break this crappy code.
ifdef DEBUG
CFLAGS ?= -O0 -g -Wall -pipe
CFLAGS ?= -O0 -g -Wall -pipe -DDEBUG
ifdef ASAN
override CFLAGS += -fsanitize=address -DUSE_SANITIZER
endif
ifdef UBSAN
override CFLAGS += -fsanitize=undefined -DUSE_SANITIZER
endif
else
CFLAGS ?= -O2 -Wall -pipe -fomit-frame-pointer
endif

# Optionally treat warnings as errors
ifdef WERR
override CFLAGS += -Werror
endif

# Always needed are:
# -fno-strict-aliasing since the source doesn't comply
# with strict aliasing rules and it's next to impossible
# to get it there...
# -fwrapv for defined integer wrapping. MSVC6 did this
# and the game code requires it.
override CFLAGS += -fno-strict-aliasing -fwrapv
# -fvisibility=hidden to keep symbols hidden. This is
# mostly best practice and not really necessary.
override CFLAGS += -fno-strict-aliasing -fwrapv -fvisibility=hidden

# -MMD to generate header dependencies. Unsupported by
# the Clang shipped with OS X.
Expand Down Expand Up @@ -124,8 +206,6 @@ override CFLAGS += -DYQ2OSTYPE=\"$(YQ2_OSTYPE)\" -DYQ2ARCH=\"$(YQ2_ARCH)\"

# ----------

# For reproduceable builds, look here for details:
# https://reproducible-builds.org/specs/source-date-epoch/
ifdef SOURCE_DATE_EPOCH
CFLAGS += -DBUILD_DATE=\"$(shell date --utc --date="@${SOURCE_DATE_EPOCH}" +"%b %_d %Y" | sed -e 's/ /\\ /g')\"
endif
Expand Down Expand Up @@ -154,7 +234,17 @@ LDFLAGS ?=
# It's a shared library.
override LDFLAGS += -shared

# Required libaries
# Link address sanitizer if requested.
ifdef ASAN
override LDFLAGS += -fsanitize=address
endif

# Link undefined behavior sanitizer if requested.
ifdef UBSAN
override LDFLAGS += -fsanitize=undefined
endif

# Required libraries
ifeq ($(YQ2_OSTYPE), Darwin)
override LDFLAGS += -arch $(YQ2_ARCH)
else ifeq ($(YQ2_OSTYPE), Windows)
Expand All @@ -163,6 +253,19 @@ else
override LDFLAGS += -lm
endif

# ASAN and UBSAN must not be linked
# with --no-undefined. OSX and OpenBSD
# don't support it at all.
ifndef ASAN
ifndef UBSAN
ifneq ($(YQ2_OSTYPE), Darwin)
ifneq ($(YQ2_OSTYPE), OpenBSD)
override LDFLAGS += -Wl,--no-undefined
endif
endif
endif
endif

# ----------

# Builds everything
Expand Down Expand Up @@ -197,24 +300,26 @@ clean:
ifeq ($(YQ2_OSTYPE), Windows)
xatrix:
@echo "===> Building game.dll"
${Q}mkdir -p release
${MAKE} release/game.dll
${Q}mkdir -p $(BINDIR)
${MAKE} $(BINDIR)/game.dll
else ifeq ($(YQ2_OSTYPE), Darwin)
xatrix:
@echo "===> Building game.dylib"
${Q}mkdir -p release
$(MAKE) release/game.dylib
${Q}mkdir -p $(BINDIR)
$(MAKE) $(BINDIR)/game.dylib
else
xatrix:
@echo "===> Building game.so"
${Q}mkdir -p release
$(MAKE) release/game.so
${Q}mkdir -p $(BINDIR)
$(MAKE) $(BINDIR)/game.so

release/game.so : CFLAGS += -fPIC
$(BINDIR)/game.so : CFLAGS += -fPIC
endif

build/%.o: %.c
@echo "===> CC $<"
$(BUILDDIR)/%.o: %.c
@if [ -z $(QUIET) ]; then\
echo "===> CC $<";\
fi
${Q}mkdir -p $(@D)
${Q}$(CC) -c $(CFLAGS) -o $@ $<

Expand Down Expand Up @@ -277,7 +382,7 @@ XATRIX_OBJS_ = \
# ----------

# Rewrite paths to our object directory
XATRIX_OBJS = $(patsubst %,build/%,$(XATRIX_OBJS_))
XATRIX_OBJS = $(patsubst %,$(BUILDDIR)/%,$(XATRIX_OBJS_))

# ----------

Expand All @@ -292,15 +397,15 @@ XATRIX_DEPS= $(XATRIX_OBJS:.o=.d)
# ----------

ifeq ($(YQ2_OSTYPE), Windows)
release/game.dll : $(XATRIX_OBJS)
$(BINDIR)/game.dll : $(XATRIX_OBJS)
@echo "===> LD $@"
${Q}$(CC) -o $@ $(XATRIX_OBJS) $(LDFLAGS)
else ifeq ($(YQ2_OSTYPE), Darwin)
release/game.dylib : $(XATRIX_OBJS)
$(BINDIR)/game.dylib : $(XATRIX_OBJS)
@echo "===> LD $@"
${Q}$(CC) -o $@ $(XATRIX_OBJS) $(LDFLAGS)
else
release/game.so : $(XATRIX_OBJS)
$(BINDIR)/game.so : $(XATRIX_OBJS)
@echo "===> LD $@"
${Q}$(CC) -o $@ $(XATRIX_OBJS) $(LDFLAGS)
endif
Expand Down