PROJECTNAME=minicc

VERSION=$(shell dpkg-parsechangelog --show-field Version)
DISTROS=base #debian10 ubuntu2004 ubuntu2010

CXX=clang++-11
#CXX=g++-10

#CXXFLAGS=-O2 -DNDEBUG
CXXFLAGS=-O0 -g -D_DEBUG
# -fprofile-instr-generate -fcoverage-mapping
# gcc:--coverage

CXXFLAGS+= -Wall -I. -std=c++20
CXXFLAGS+= -fPIE -DVERSION=\"$(VERSION)\"


ifeq ($(CXX),clang++-11)
CXXFLAGS+=-stdlib=libc++
endif

CXXTESTFLAGS+=-Igoogletest/include -Igooglemock/include/ -Igoogletest -Igooglemock

LIBS=\
-lboost_context \
-lboost_coroutine \
-lboost_program_options \
-lboost_system \
-lboost_thread \
-lboost_filesystem \
-lboost_regex \
-lpthread

ifeq ($(CXX),clang++-11)
LIBS+= \
-fuse-ld=lld-11 \
-lc++ \
-lc++abi
#-lc++fs
#-lstdc++ \
#-lstdc++fs
else
LIBS+= \
-lstdc++
#-lstdc++fs
endif

PROGSRC=\
    asm/assembler.cpp \
    asm/chunk.cpp \
    asm/intel64/add.cpp \
    asm/intel64/and.cpp \
    asm/intel64/bsf.cpp \
    asm/intel64/bsr.cpp \
    asm/intel64/cmp.cpp \
    asm/intel64/cmovcc.cpp \
    asm/intel64/dec.cpp \
    asm/intel64/div.cpp \
    asm/intel64/idiv.cpp \
    asm/intel64/inc.cpp \
    asm/intel64/imul.cpp \
    asm/intel64/int.cpp \
    asm/intel64/jmp.cpp \
    asm/intel64/mov.cpp \
    asm/intel64/movsx.cpp \
    asm/intel64/mul.cpp \
    asm/intel64/neg.cpp \
    asm/intel64/not.cpp \
    asm/intel64/or.cpp \
    asm/intel64/pop.cpp \
    asm/intel64/push.cpp \
    asm/intel64/rcl.cpp \
    asm/intel64/rcr.cpp \
    asm/intel64/rol.cpp \
    asm/intel64/ror.cpp \
    asm/intel64/sal_shl.cpp \
    asm/intel64/sar.cpp \
    asm/intel64/setcc.cpp \
    asm/intel64/shr.cpp \
    asm/intel64/sub.cpp \
    asm/intel64/trivials.cpp \
    asm/intel64/xor.cpp \
    asm/intel64/codes.cpp \
    asm/intel64/encode.cpp \
    asm/operators.cpp \
    asm/parse.cpp \
    asm/segment.cpp \
    bnf.cpp \
    byteorder.cpp \
    cpp.cpp \
    cppbnf.cpp \
    coff.cpp \
    debug.cpp \
    elf.cpp \
    flowgraph/data.cpp \
    flowgraph/graph.cpp \
    flowgraph/node.cpp \
    flowgraph/scope.cpp \
    flowgraph/storage.cpp \
    file.cpp \
    grammer.cpp \
    lexer.cpp \
    minicc.cpp \
    programopts.cpp

TESTSRC=\
    tests/test-asm.cpp \
    tests/test-cpp.cpp \
    tests/test-cppbnf.cpp \
    tests/test-elf.cpp \
    tests/test-flowgraph.cpp \
    tests/test-grammer.cpp \
    tests/test-lexer.cpp \
    tests/test-minicc.cpp \
    googlemock/src/gmock-all.cpp \
    googletest/src/gtest-all.cpp \
    $(PROGSRC)

SRC=$(PROGSRC) mcc.cpp

all: mcc

test: unittest systemtest

check: test

install:
	mkdir -p $(DESTDIR)/usr/bin
	cp mcc $(DESTDIR)/usr/bin

# Tests on C++ level
unittest: test-$(PROJECTNAME)
	./test-$(PROJECTNAME) #--gtest_filter='CppTest.compile_parentheses_right'

# Testing mcc executable and compiled elf programs
systemtest: mcc
	runtest --srcdir systemtest --tool mcc # --all

# testsuite ----------------------------------------------
test-$(PROJECTNAME): dep $(TESTSRC:.cpp=.o)
	$(CXX) $(CXXFLAGS) $(TESTSRC:.cpp=.o) $(LIBS) -o $@

mcc: dep $(SRC:.cpp=.o)
	$(CXX) $(CXXFLAGS) $(SRC:.cpp=.o) $(LIBS) -o $@

dep: $(TESTSRC:.cpp=.d) mcc.d

%.d: %.cpp
	$(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -MM -MP -MF $@ -MT $(*D)/$(*F).o -c $<

%.o: %.cpp %.d
	$(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@

googletest/src/%.o: googletest/src/%.cc
	$(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@

# dependencies

ADD_DEP=Makefile

# misc ---------------------------------------------------
deb:
	# build binary deb package
	dpkg-buildpackage -rfakeroot

deb-src:
	dh_clean
	dh_auto_clean
	dpkg-source -b -I.git -Iresult .

$(DISTROS): deb-src
	sudo pbuilder build --basetgz /var/cache/pbuilder/$@.tgz --buildresult result/$@ ../$(PROJECTNAME)_$(VERSION).dsc
	debsign result/$@/$(PROJECTNAME)_$(VERSION)_amd64.changes

debs: $(DISTROS)

DISTFILES= \
	   $(TESTSRC) \
	   $(PROGSRC:.cpp=.h) \
           debian/control \
           debian/compat \
           debian/copyright \
           debian/source \
           debian/source/format \
           debian/changelog \
           debian/README.Debian \
           debian/rules \
	   README \
	   TODO

dist: clean
	rm -rf $(PROJECTNAME)-$(VERSION)
	mkdir $(PROJECTNAME)-$(VERSION)
	cp --parents -r $(DISTFILES) $(PROJECTNAME)-$(VERSION)
	tar cfJ ../$(PROJECTNAME)-$(VERSION).tar.xz $(PROJECTNAME)-$(VERSION)
	rm -rf $(PROJECTNAME)-$(VERSION)
	ls -l ../$(PROJECTNAME)-$(VERSION).tar.xz

clean:
	-rm -f test-$(PROJECTNAME) mcc tempfile.txt
	-find . -name '*.o' -o -name '*.d' -o -name '*.gcno' -o -name '*.gcda' | xargs rm -f
	-rm -f *.log *.sum

zip: clean
	-rm -f ../$(PROJECTNAME).zip
	zip -r ../$(PROJECTNAME).zip *
	ls -l ../$(PROJECTNAME).zip

.PHONY: clean all zip dep test check systemtest unittest

-include $(wildcard $(SRC:.cpp=.d))