
FINALPFX ?= mul
OUTFILE  ?= proga

BITS ?= $(shell getconf LONG_BIT)

ifneq ($(WIDTH),)
WIDTH:=-DFBWIDTH=$(WIDTH)
else
WIDTH:=-DFBWIDTH=1366
endif
ifneq ($(HEIGHT),)
HEIGHT:=-DFBHEIGHT=$(HEIGHT)
else
HEIGHT:=-DFBHEIGHT=768
endif

ifneq ($(FINALSFX),)
FINALSFX:=$(BITS)-$(FINALSFX)
endif
ifeq ($(FINALPFX),rody)
FINALSFX ?= $(BITS)-$(WIDTH)-$(HEIGHT)
endif

# these are probably the only parameters you might want to tweak
#CC_ ?= clang
CC_ ?= gcc

ifeq ($(CC_),clang)
SZOPT ?= -Oz
else
SZOPT ?= -Os
endif

NASM ?= nasm

NORJOHE ?= norjohe
ZIP ?= lzma

ifeq ($(ZIP),lzma)
ZFLAGS ?= --format=lzma -9 --extreme --lzma1=preset=9,lc=1,lp=0,pb=0 --keep --stdout
else
ifeq ($(ZIP),gzip)
ZFLAGS ?= -cnk9
else
ifeq ($(ZIP),xz)
ZFLAGS ?= -9 --extreme --keep --stdout
else
ifeq ($(ZFLAGS),)
$(error "Custom zip, please provide ZFLAGS.")
endif
endif
endif
endif

CFLAGS = -Iinc -std=gnu11 -fPIC -m$(BITS)
ifneq ($(TEXTMODE),)
CFLAGS += -DTEXTMODE
endif
LDFLAGS = -m$(BITS)

CC := $(CC_)

ifeq ($(LD_),)
LD := gcc # GNU ld, breaks with clang! (latter doesn't accept -T)
endif

ifeq ($(CC_),clang)
	CFLAGS += -Weverything -Wextra -Wno-vla -Wno-language-extension-token \
        -Wno-unused-macros -Wno-flexible-array-extensions -Wno-switch \
        -Wno-gnu-statement-expression -Wno-switch-default \
        -Wno-gnu-zero-variadic-macro-arguments -Wno-pointer-arith \
        -Wno-ignored-optimization-argument -Wno-zero-length-array
else
	CFLAGS += -Wall -Wno-unknown-pragmas -Wno-switch -Wno-conversion \
        -Wno-uninitialized -Wno-strict-aliasing
endif

default: release

debug: CFLAGS += -DDEBUG -O1 -g
ifeq ($(CC_),clang)
debug: CFLAGS += -fsanitize=undefined
debug: LDFLAGS += -fsanitize=undefined
endif
debug: all

release: CFLAGS += -DRELEASE -DNODEBUG $(SZOPT) \
    -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables \
    -fomit-frame-pointer -fno-inline -fno-exceptions -fno-rtti -ffast-math \
    -fno-pic -fsingle-precision-constant -fno-threadsafe-statics -fno-plt \
    -funsafe-math-optimizations -fvisibility=hidden -march=core2 -mtune=generic \
    -fwhole-program -fno-align-functions -fno-align-loops
ifneq ($(CC_),clang)
release: CFLAGS += -fno-enforce-eh-specs -fno-implicit-templates \
    -fno-use-cxa-atexit -fno-use-cxa-get-exception-ptr -fnothrow-opt \
    -fno-plt -mno-stack-arg-probe
else
release: CFLAGS += -mno-sse2 -mno-sse -mno-avx -mno-sse3 -mno-ssse3 \
    -mno-sse4.1 -mno-sse4.2 -mno-sse4a -mno-avx2 -mno-xop -mno-fma4
endif
release: LDFLAGS += -static -nostdlib -nostartfiles -T src/ld$(BITS).ld \
    -flto -fuse-linker-plugin -Wl,--gc-sections -Wl,--print-gc-sections

# specific to norjo'e
ifeq ($(BITS),32)
release: LDFLAGS += -Wl,--defsym,ehdr_base=0x08048000
else
release: LDFLAGS += -Wl,--defsym,ehdr_base=0x00400000
endif

release: all

%/:
	mkdir -p "$@"

# TODO: decide whether to use PIC
# probably not needed in this case?
obj/%.asm.o: src/%.asm
	$(NASM) -f elf$(BITS) -o$@ $<
obj/%.o: src/%.c
	$(CC) $(CFLAGS) -o "$@" -c "$<"

HEADERS := $(wildcard inc/*.h)

bin/$(OUTFILE): obj/zan.o $(HEADERS) #obj/tex.asm.o $(HEADERS)
	$(LD) $(LDFLAGS) -o "$@" $(filter-out $(HEADERS),$^)
bin/$(OUTFILE).nrjh: bin/$(OUTFILE)
	-$(NORJOHE) "$<" "$@"
obj/$(OUTFILE).$(ZIP): bin/$(OUTFILE)
	$(ZIP) $(ZFLAGS) "$<" > "$@"
obj/$(OUTFILE).nrjh.$(ZIP): bin/$(OUTFILE).nrjh
	$(ZIP) $(ZFLAGS) "$<" > "$@"
	# TODO: look for a better way to generate stubs
bin/$(FINALPFX)$(OUTFILE)$(FINALSFX): src/stub/nofont/stub-$(ZIP) obj/$(OUTFILE).nrjh.$(ZIP)
	cat $^ > "$@"
	chmod +x "$@"

.clang_complete:
	echo "$(CFLAGS)" | sed 's/  */\n/g' > "$@"
	< "$@" sed 's/\-I/\-I\.\.\//g' > "src/$@"

all: .clang_complete obj/ bin/ bin/$(OUTFILE) bin/$(FINALPFX)$(OUTFILE)$(FINALSFX)
	wc -c bin/* obj/*.$(ZIP) | sort

clean:
	@rm -fv obj/* bin/*

#TESTSTDIN:=zcat /usr/share/kbd/consolefonts/alt-8x8.gz |

test: default
	$(TESTSTDIN)bin/$(OUTFILE).nrjh|aplay
testm: default
	$(TESTSTDIN)bin/$(OUTFILE).nrjh>/dev/null

zmk:
	zmk src/zan.c "make clean&&BITS=32 make release&&$(TESTSTDIN)bin/mul$(OUTFILE)"
zmkm:
	zmk src/zan.c "make clean&&BITS=32 make release&&$(TESTSTDIN)bin/$(OUTFILE).nrjh>/dev/null"

.PHONY: debug release all clean test testm zmk

