# Makefile for GTK version of Golly using wxWidgets (3.1.5 or later is required).
# It assumes you've built and installed wxWidgets with commands like these:
#
# cd <wx-install-dir>
# mkdir buildgtk
# cd buildgtk
# ../configure --with-gtk --disable-shared --enable-unicode --with-opengl
# (depending on your g++ version you might also need --disable-precomp-headers)
# make
# sudo make install
# sudo ldconfig

include local-gtk-template.mk
-include local-gtk.mk

APP_VERSION = 5.0

# these directory paths are relative to the location of this makefile:
EXEDIR = ..
DOCSDIR = ../docs
BASEDIR = ../gollybase
CMDDIR = ../cmdline
LUADIR = ../lua
SOUNDDIR = ../sound
OTHERGUIS = ../gui-android ../gui-common ../gui-ios ../gui-web

# Dealing with rpath and packaging shared libraries.
LOCALSTR = .local
RPATHSTR = $(LOCALSTR)/lib
LOCALDIR = $(EXEDIR)/$(LOCALSTR)
LIBDIR = $(EXEDIR)/$(RPATHSTR)

# for building binary and source distributions:
RELEASENAME = $(EXEDIR)/golly-$(APP_VERSION)
BITSIZE = `getconf LONG_BIT`
DIRNAME = $(RELEASENAME)-gtk-$(BITSIZE)bit
SHAREDFILES = $(EXEDIR)/Help $(EXEDIR)/Patterns $(EXEDIR)/Scripts $(EXEDIR)/Rules
EXEFILES = $(EXEDIR)/golly $(EXEDIR)/bgolly
DOCFILES = $(DOCSDIR)/ReadMe.html $(DOCSDIR)/License.html
SRCFILES = $(DOCSDIR) $(BASEDIR) $(CMDDIR) $(OTHERGUIS)
GUIFILES = makefile-gtk makefile-mac makefile-win local-win-template.mk local-gtk-template.mk \
    golly.rc Info.plist.in wx*.h wx*.cpp bitmaps icons
LUAFILES = $(LUADIR)/*.h $(LUADIR)/*.c $(LUADIR)/*.hpp $(LUADIR)/Makefile $(LUADIR)/ReadMe.html
SOUNDFILES = $(SOUNDDIR)/*.h $(SOUNDDIR)/*.c

LUALIB = $(LUADIR)/liblua.a -ldl

CXXC = g++
CXXFLAGS := -DVERSION=$(APP_VERSION) -DGOLLYDIR="$(GOLLYDIR)" \
    -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -I$(BASEDIR) \
    -O3 -Wall -Wno-non-virtual-dtor -fno-strict-aliasing $(CXXFLAGS)
LDFLAGS := -Wl,--as-needed -Wl,-rpath,'$$ORIGIN/$(RPATHSTR)' $(LDFLAGS)

# For sound support
ifdef ENABLE_SOUND
    CXXFLAGS += -DENABLE_SOUND
    SOUND_INCLUDE = -I$(SOUNDDIR)
    ### SOUND_LINK = /usr/local/lib/libSDL2.a -lrt
    ### above loads SDL2 lib statically (but requires building SDL2 from source)
    SOUND_LINK = -lSDL2
endif

# For Python script support
PYTHON_INCLUDE = -I`$(PYTHON) -c "import distutils.sysconfig as s; print(s.get_python_inc())"`
# we don't want to link against a specific library: PYTHON_LINK = -lpython2.3
# following generates "-Xlinker -export-dynamic" but doesn't seem to be needed
# PYTHON_LINK = `python -c "import distutils.sysconfig; print distutils.sysconfig.get_config_var('LINKFORSHARED')"`
PYTHON_LINK =
# the following determines the filename for the python dynamic library (e.g. libpython3.8.so)
PYTHON_SHLIB = `$(PYTHON) -c "import distutils.sysconfig as s; print(s.get_config_var('LDLIBRARY'))"`
PYTHON_PREFS = -DPYTHON_SHLIB="$(PYTHON_SHLIB)"

# default settings for zlib support, so clear these to build without zlib
ZLIB_CXXFLAGS = -DZLIB
ZLIB_LDFLAGS = -lz

# libs for OpenGL
# Edited to work regardless of wxGTK versions.
EXTRALIBS_OPENGL = `$(WX_CONFIG) --libs gl` -lGL -lGLU

# for wxGTK support (required for GUI)
WX_CXXFLAGS = `$(WX_CONFIG) --cxxflags` -I$(LUADIR) $(SOUND_INCLUDE)
WX_LDFLAGS = `$(WX_CONFIG) --libs`

OBJDIR = ObjGTK
BASEH = $(BASEDIR)/bigint.h $(BASEDIR)/ghashbase.h $(BASEDIR)/hlifealgo.h $(BASEDIR)/jvnalgo.h \
    $(BASEDIR)/platform.h $(BASEDIR)/lifealgo.h $(BASEDIR)/lifepoll.h $(BASEDIR)/liferender.h $(BASEDIR)/liferules.h \
    $(BASEDIR)/qlifealgo.h $(BASEDIR)/ltlalgo.h $(BASEDIR)/readpattern.h $(BASEDIR)/util.h $(BASEDIR)/viewport.h \
    $(BASEDIR)/writepattern.h $(BASEDIR)/ruletreealgo.h $(BASEDIR)/generationsalgo.h $(BASEDIR)/ruletable_algo.h \
    $(BASEDIR)/ruleloaderalgo.h $(BASEDIR)/superalgo.h
BASEOBJ = $(OBJDIR)/bigint.o $(OBJDIR)/lifealgo.o $(OBJDIR)/hlifealgo.o \
    $(OBJDIR)/hlifedraw.o $(OBJDIR)/qlifealgo.o $(OBJDIR)/qlifedraw.o $(OBJDIR)/ltlalgo.o $(OBJDIR)/ltldraw.o \
    $(OBJDIR)/jvnalgo.o $(OBJDIR)/ruletreealgo.o $(OBJDIR)/ruletable_algo.o $(OBJDIR)/ruleloaderalgo.o \
    $(OBJDIR)/ghashbase.o $(OBJDIR)/ghashdraw.o $(OBJDIR)/readpattern.o \
    $(OBJDIR)/writepattern.o $(OBJDIR)/liferules.o $(OBJDIR)/util.o \
    $(OBJDIR)/liferender.o $(OBJDIR)/viewport.o $(OBJDIR)/lifepoll.o \
    $(OBJDIR)/generationsalgo.o $(OBJDIR)/superalgo.o
WXH = wxalgos.h wxedit.h wxgolly.h wxhelp.h wxinfo.h wxlayer.h wxmain.h wxprefs.h \
    wxlua.h wxpython.h wxrender.h wxrule.h wxscript.h wxselect.h wxstatus.h \
    wxtimeline.h wxundo.h wxutils.h wxview.h wxoverlay.h
WXOBJ = $(OBJDIR)/wxutils.o $(OBJDIR)/wxprefs.o $(OBJDIR)/wxalgos.o $(OBJDIR)/wxrule.o \
    $(OBJDIR)/wxinfo.o $(OBJDIR)/wxhelp.o $(OBJDIR)/wxstatus.o $(OBJDIR)/wxview.o $(OBJDIR)/wxoverlay.o \
    $(OBJDIR)/wxrender.o $(OBJDIR)/wxscript.o $(OBJDIR)/wxlua.o $(OBJDIR)/wxpython.o \
    $(OBJDIR)/wxfile.o $(OBJDIR)/wxedit.o $(OBJDIR)/wxcontrol.o $(OBJDIR)/wxtimeline.o \
    $(OBJDIR)/wxundo.o $(OBJDIR)/wxselect.o $(OBJDIR)/wxlayer.o $(OBJDIR)/wxmain.o $(OBJDIR)/wxgolly.o

all: $(OBJDIR) golly bgolly

$(BASEOBJ): $(BASEH)
$(WXOBJ): $(BASEH) $(WXH) icons/appicon.xpm bitmaps/*.xpm

$(OBJDIR) $(LIBDIR):
	mkdir -p $@

clean: 
	rm -f $(EXEDIR)/golly $(EXEDIR)/bgolly
	-rm -rf $(OBJDIR)
	-rm -rf $(LOCALDIR)
	-(cd $(LUADIR) && $(MAKE) clean)

golly: $(OBJDIR) $(BASEOBJ) $(WXOBJ) $(LUALIB)
	$(CXXC) $(CXXFLAGS) -o $(EXEDIR)/golly $(BASEOBJ) $(WXOBJ) $(LUALIB) \
	$(LDFLAGS) $(ZLIB_LDFLAGS) $(EXTRALIBS_OPENGL) $(WX_LDFLAGS) $(PYTHON_LINK) $(SOUND_LINK)

bgolly: $(OBJDIR) $(BASEOBJ) $(OBJDIR)/bgolly.o
	$(CXXC) $(CXXFLAGS) -o $(EXEDIR)/bgolly $(BASEOBJ) $(OBJDIR)/bgolly.o $(LDFLAGS) $(ZLIB_LDFLAGS)

$(LUALIB):
	(cd $(LUADIR) && $(MAKE) all)

$(OBJDIR)/bgolly.o: $(CMDDIR)/bgolly.cpp
	$(CXXC) $(CXXFLAGS) $(ZLIB_CXXFLAGS) -c -o $@ $(CMDDIR)/bgolly.cpp

$(OBJDIR)/bigint.o: $(BASEDIR)/bigint.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/bigint.cpp

$(OBJDIR)/lifealgo.o: $(BASEDIR)/lifealgo.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/lifealgo.cpp

$(OBJDIR)/hlifealgo.o: $(BASEDIR)/hlifealgo.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/hlifealgo.cpp

$(OBJDIR)/hlifedraw.o: $(BASEDIR)/hlifedraw.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/hlifedraw.cpp

$(OBJDIR)/qlifealgo.o: $(BASEDIR)/qlifealgo.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/qlifealgo.cpp

$(OBJDIR)/qlifedraw.o: $(BASEDIR)/qlifedraw.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/qlifedraw.cpp

$(OBJDIR)/ltlalgo.o: $(BASEDIR)/ltlalgo.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/ltlalgo.cpp

$(OBJDIR)/ltldraw.o: $(BASEDIR)/ltldraw.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/ltldraw.cpp

$(OBJDIR)/jvnalgo.o: $(BASEDIR)/jvnalgo.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/jvnalgo.cpp

$(OBJDIR)/ruleloaderalgo.o: $(BASEDIR)/ruleloaderalgo.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/ruleloaderalgo.cpp

$(OBJDIR)/ruletable_algo.o: $(BASEDIR)/ruletable_algo.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/ruletable_algo.cpp

$(OBJDIR)/ruletreealgo.o: $(BASEDIR)/ruletreealgo.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/ruletreealgo.cpp

$(OBJDIR)/generationsalgo.o: $(BASEDIR)/generationsalgo.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/generationsalgo.cpp

$(OBJDIR)/superalgo.o: $(BASEDIR)/superalgo.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/superalgo.cpp

$(OBJDIR)/ghashbase.o: $(BASEDIR)/ghashbase.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/ghashbase.cpp

$(OBJDIR)/ghashdraw.o: $(BASEDIR)/ghashdraw.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/ghashdraw.cpp

$(OBJDIR)/liferules.o: $(BASEDIR)/liferules.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/liferules.cpp

$(OBJDIR)/liferender.o: $(BASEDIR)/liferender.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/liferender.cpp

$(OBJDIR)/readpattern.o: $(BASEDIR)/readpattern.cpp
	$(CXXC) $(CXXFLAGS) $(ZLIB_CXXFLAGS) -c -o $@ $(BASEDIR)/readpattern.cpp

$(OBJDIR)/writepattern.o: $(BASEDIR)/writepattern.cpp
	$(CXXC) $(CXXFLAGS) $(ZLIB_CXXFLAGS) -c -o $@ $(BASEDIR)/writepattern.cpp

$(OBJDIR)/util.o: $(BASEDIR)/util.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/util.cpp

$(OBJDIR)/viewport.o: $(BASEDIR)/viewport.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/viewport.cpp

$(OBJDIR)/lifepoll.o: $(BASEDIR)/lifepoll.cpp
	$(CXXC) $(CXXFLAGS) -c -o $@ $(BASEDIR)/lifepoll.cpp

$(OBJDIR)/wxutils.o: wxutils.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxutils.cpp

$(OBJDIR)/wxprefs.o: wxprefs.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) $(PYTHON_PREFS) -c -o $@ wxprefs.cpp

$(OBJDIR)/wxalgos.o: wxalgos.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxalgos.cpp

$(OBJDIR)/wxrule.o: wxrule.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxrule.cpp

$(OBJDIR)/wxinfo.o: wxinfo.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxinfo.cpp

$(OBJDIR)/wxhelp.o: wxhelp.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxhelp.cpp

$(OBJDIR)/wxstatus.o: wxstatus.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxstatus.cpp

$(OBJDIR)/wxview.o: wxview.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxview.cpp

$(OBJDIR)/wxoverlay.o: wxoverlay.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxoverlay.cpp

$(OBJDIR)/wxrender.o: wxrender.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxrender.cpp

$(OBJDIR)/wxlua.o: wxlua.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxlua.cpp

$(OBJDIR)/wxpython.o: wxpython.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) $(PYTHON_INCLUDE) -c -o $@ wxpython.cpp

$(OBJDIR)/wxscript.o: wxscript.cpp $(SOUNDDIR)/cute_sound.h $(SOUNDDIR)/stb_vorbis.c
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxscript.cpp

$(OBJDIR)/wxfile.o: wxfile.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxfile.cpp

$(OBJDIR)/wxedit.o: wxedit.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxedit.cpp

$(OBJDIR)/wxselect.o: wxselect.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxselect.cpp

$(OBJDIR)/wxcontrol.o: wxcontrol.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxcontrol.cpp

$(OBJDIR)/wxtimeline.o: wxtimeline.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxtimeline.cpp

$(OBJDIR)/wxundo.o: wxundo.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxundo.cpp

$(OBJDIR)/wxlayer.o: wxlayer.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxlayer.cpp

$(OBJDIR)/wxmain.o: wxmain.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxmain.cpp

$(OBJDIR)/wxgolly.o: wxgolly.cpp
	$(CXXC) $(CXXFLAGS) $(WX_CXXFLAGS) -c -o $@ wxgolly.cpp

srcdist: 
	-rm -rf $(RELEASENAME)-src
	mkdir $(RELEASENAME)-src
	mkdir $(RELEASENAME)-src/gui-wx
	mkdir $(RELEASENAME)-src/lua
	mkdir $(RELEASENAME)-src/sound
	cp -rp $(SRCFILES) $(SHAREDFILES) $(RELEASENAME)-src
	cp -rp $(GUIFILES) $(RELEASENAME)-src/gui-wx
	cp -rp $(LUAFILES) $(RELEASENAME)-src/lua
	cp -rp $(SOUNDFILES) $(RELEASENAME)-src/sound
	find $(RELEASENAME)-src -name '.[^.]*' -delete
	find $(RELEASENAME)-src -name '*.o' -delete
	find $(RELEASENAME)-src -name 'makefile' -delete
	find $(RELEASENAME)-src/Scripts/Python -name '*.pyc' -delete
	tar -cf - ./$(RELEASENAME)-src | gzip > $(RELEASENAME)-src.tar.gz
	
bindist: all
	-rm -rf $(DIRNAME)
	mkdir $(DIRNAME)
	install $(EXEFILES) $(DIRNAME)
	cp -rp $(DOCFILES) $(SHAREDFILES) $(DIRNAME)
	find $(DIRNAME) -name '.[^.]*' -delete
	find $(DIRNAME)/Scripts/Python -name '*.pyc' -delete
	tar -cf - ./$(DIRNAME) | gzip > $(DIRNAME).tar.gz
                                          
# Packaging a portable distribution.
# We need to copy the necessary shared libraries.
EXCLUDELISTURL = https://raw.githubusercontent.com/probonopd/AppImages/master/excludelist
portable-excludelist:
	@echo
	# Getting shared libraries to exclude from AppImage repo...
	wget -O - $(EXCLUDELISTURL) | sed -e 's/[[:space:]]*#.*//' -e '/^$$/d' | sort > $@

portable-libs: $(LIBDIR) portable-excludelist
	@echo
	# Copying system files to lib directory...
	-ldd ../golly | grep '=>' | sed -e 's/=>//' | awk '{print $$1, $$2}' | \
	grep -vFf portable-excludelist | sort | uniq | \
	while read -r soname sopath; do \
		echo "Copying $${soname}..."; \
		cp "$${sopath}" $(LIBDIR); \
	done

portable: all portable-libs
	-rm -rf $(DIRNAME)
	mkdir $(DIRNAME)
	install $(EXEFILES) $(DIRNAME)
	cp -Rp $(DOCFILES) $(SHAREDFILES) $(DIRNAME)
	find $(DIRNAME) -name '.[^.]**' -delete
	find $(DIRNAME)/Scripts/Python -name '*.pyc' -delete
	cp -Rp $(LOCALDIR) $(DIRNAME)
	tar -cf - $(DIRNAME) | gzip > $(DIRNAME)-portable.tar.gz
