#!/usr/bin/make -f
include /usr/share/dpkg/pkg-info.mk
include /usr/share/dpkg/buildtools.mk

# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1

# Exclude .svn directories from packages
export DH_ALWAYS_EXCLUDE=.svn

# Enable hardening
export DEB_BUILD_MAINT_OPTIONS=hardening=+all

VERSION=$(shell echo $(DEB_VERSION) | sed -Ee s/\(build\|ubuntu\)[0-9]+//)

PREFIX=/usr
DATADIR=$(PREFIX)/share/nsis
DOCDIR=$(PREFIX)/share/doc/nsis
SYSCONF=/etc
BUILDDIR=build
UNICODE=yes
INSTDIR=$(CURDIR)/debian
TESTDIR=$(CURDIR)/$(BUILDDIR)/test

# Decomposition of version string
define SPLIT
	$(if $(2),$(call SPLIT,$(subst $(firstword $(2)), ,$(1)),$(filter-out $(firstword $(2)), $(2))), $(1))
endef
VERSION_DECOMPOSED=$(call SPLIT,$(VERSION),. - + ~)
VER_MAJOR=$(firstword $(VERSION_DECOMPOSED))
VER_MINOR=$(word 2,$(VERSION_DECOMPOSED))
VER_REVISION=$(firstword $(subst +, ,$(word 3,$(VERSION_DECOMPOSED))))

# Variables for Win32/Win64 cross compiler
XGCC_W32_X86 = i686-w64-mingw32-gcc
XGCC_W32_X86_PATH = $(abspath $(shell $(XGCC_W32_X86) -print-file-name=libkernel32.a)/../..)
XGCC_W32_X86_PREFIX = $(subst -gcc,-,$(XGCC_W32_X86))
XGCC_W32_AMD64 = x86_64-w64-mingw32-gcc
XGCC_W32_AMD64_PATH = $(abspath $(shell $(XGCC_W32_AMD64) -print-file-name=libkernel32.a)/../..)
XGCC_W32_AMD64_PREFIX = $(subst -gcc,-,$(XGCC_W32_AMD64))


# Evaluate parallel build option
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
ifeq (,$(shell dh_listpackages -i))
	NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
	SCONSFLAGS = -j $(NUMJOBS)
endif
endif

# Honor hardening flags
SCONSHOSTFLAGS = APPEND_CCFLAGS="$(shell dpkg-buildflags --get CPPFLAGS) \
  $(shell dpkg-buildflags --get CFLAGS)" \
  APPEND_LINKFLAGS="$(shell dpkg-buildflags --get LDFLAGS)"

# Propagate CCACHE_DIR environment variable
ifneq (,$(CCACHE_DIR))
	SCONSHOSTFLAGS += CC="CCACHE_DIR=\"$(CCACHE_DIR)\" $(CC)" CXX="CCACHE_DIR=\"$(CCACHE_DIR)\" $(CXX)"
endif

SCONSOPTS = $(SCONSFLAGS) VERSION=$(VERSION) VER_MAJOR=$(VER_MAJOR) \
  VER_MINOR=$(VER_MINOR) VER_REVISION=$(VER_REVISION) \
  PREFIX=$(PREFIX) PREFIX_CONF=$(SYSCONF) CHMDOCS=0 \
  STRIP_CP=no \
  $(if $(findstring nostripfull,$(DEB_BUILD_OPTIONS)),STRIP_W32=no,)

ifneq (,$(UNICODE),yes)
	SCONSOPTS += UNICODE=yes
	BUILDTYPE := u
endif

ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
	SCONSOPTS += DEBUG=yes
	BUILDTYPE := $(BUILDTYPE)debug
else
	BUILDTYPE := $(BUILDTYPE)release
endif

ifdef XGCC_W32_X86_PATH
SCONSOPTS_X86 = PREFIX_PLUGINAPI_INC=$(XGCC_W32_X86_PATH)/include/ \
  PREFIX_PLUGINAPI_LIB=$(XGCC_W32_X86_PATH)/lib/ \
  XGCC_W32_PREFIX=$(XGCC_W32_X86_PREFIX) \
  TARGET_ARCH=x86
endif

ifdef XGCC_W32_AMD64_PATH
SCONSOPTS_AMD64 = PREFIX_PLUGINAPI_INC=$(XGCC_W32_AMD64_PATH)/include/ \
  PREFIX_PLUGINAPI_LIB=$(XGCC_W32_AMD64_PATH)/lib/ \
  XGCC_W32_PREFIX=$(XGCC_W32_AMD64_PREFIX) \
  TARGET_ARCH=amd64
endif

COMMA := ,

UTILS_ALL = 'Library/RegTool,MakeLangId,Makensisw,NSIS Menu,UIs,SubStart,VPatch/Source/GenPat,zip2exe'

# Only build GenPat for the host system
IGNORE_UTILS_NSIS   := $(subst $(COMMA)VPatch/Source/GenPat,,$(UTILS_ALL))

# Build the win32 user interfaces (UIs) and RegTool
IGNORE_UTILS_COMMON := $(subst Library/RegTool$(COMMA),,$(UTILS_ALL))
IGNORE_UTILS_COMMON := $(subst $(COMMA)UIs,,$(IGNORE_UTILS_COMMON))

SCONSOPTS_HOST   := $(SCONSHOSTFLAGS) $(SCONSOPTS) \
  SKIPPLUGINS=all SKIPSTUBS=all \
  SKIPUTILS=$(IGNORE_UTILS_NSIS) SKIPDOC=COPYING
SCONSOPTS_COMMON := $(SCONSOPTS) SKIPUTILS=$(IGNORE_UTILS_COMMON) \
  SKIPDOC=COPYING

INSTALL_nsis = install-utils install-compiler install-conf
INSTALL_FLAGS_nsis = $(SCONSOPTS_HOST)
INSTALL_nsis-common = install-stubs install-plugins install-data install-utils
INSTALL_FLAGS_nsis-common = $(SCONSOPTS_COMMON)
INSTALL_nsis-pluginapi = install-pluginapi
INSTALL_FLAGS_nsis-pluginapi = $(SCONSOPTS_COMMON)
INSTALL_nsis-doc = install-examples install-doc install-docs
INSTALL_FLAGS_nsis-doc = $(SCONSOPTS_COMMON) \
  SKIPPLUGINS=ExDLL SKIPSTUBS=all SKIPUTILS=$(IGNORE_UTILS_COMMON) \
  SKIPDOC=COPYING

# Exclude test scripts which are not appropriate for POSIX platforms.
IGNORE_TESTS = gfx.nsi|install-per-user.nsi|install-shared.nsi|makensis.nsi

# Path to .nsi scripts
SCRIPTS_PATH = $(DOCDIR)/Examples

# Add contents to the given Debian package by taking
# INSTALL_FLAGS_<package> and INSTALL_<package> variables into account.
# $(1) package name, for example nsis-common
# $(2) additional flags for scons
define DO_SCONS_INSTALL
	scons $(INSTALL_FLAGS_$(1)) $(2) PREFIX_DEST="$(INSTDIR)/$(1)" $(INSTALL_$(1)) || exit 1;
endef

# Add contents to the given Debian package via the path specfic target
# $(1) package name, for example nsis-common
# $(2) path specfic scons target
define DO_SCONS_INSTALL_EXTRA
	scons $(INSTALL_FLAGS_$(1)) PREFIX_DEST="$(INSTDIR)/$(1)" "$(INSTDIR)/$(1)$(2)" || exit 1;
endef

# Convert html to text using the pretty.style configuration
# $(1) html formatted input file
# $(2) If omitted then the resulting text is written to standard output
#      otherwise to the provided output file
define HTML2TEXT_PRETTY
	html2text -nobs \
		-rcfile /usr/share/doc/html2text/examples/pretty.style \
		$(if $(2),-o $(2) ,)$(1)
endef

# Substitute reference to License text file in Modern UI examples
# with source file to enable their compilation with makensis
define SANITIZE_MODERN_UI
	for f in $$(find "$(1)" -type f -name '*.nsi' -print0 | xargs -0 -n 1 basename); \
	do \
		sed -i \
		-e "s&\$${NSISDIR}\\\\Docs\\\\Modern UI\\\\License.txt&$${f}&g" \
		"$(1)/$${f}"; \
	done
endef

# Replace duplicate files with symbolic link
define SYMLINK_DUPLICATES
	for f in $$(ls -1 "$(1)"); \
	do \
		cmp -s "$(1)/$${f}" "$(2)/$${f}"; \
		if [ $$? -eq 0 ]; \
		then \
			ln -sf "$(3)/$${f}" "$(2)/$${f}"; \
			echo $${f}; \
		fi; \
	done
endef

%:
	dh "$@"

override_dh_auto_clean:
	# Remove build directory instead of removing target files
	# via Scons due to pull in of dependencies.
	-rm -rf .sconf_temp .sconsign.dblite SCons/Tools/__pycache__ SCons/Tools/crossmingw.pyc build config.log .test $(BUILDDIR) $(TESTDIR)
	-rm -f Source/exehead/sconf.h Source/version.h Source/defines.h config.log

$(BUILDDIR)/NEWS:
	scons $(SCONSOPTS_HOST) Docs/src; \
	html2text -nobs "$(BUILDDIR)/$(BUILDTYPE)/Docs/html/AppendixF.html" | \
	sed -e '0,/^\*\*\*\*\*/c\NSIS Release Notes (automatically converted from AppendixF.html)' -e 's/F\.[.0-9]* //g' -e 's/^\*\*\*\** *\([^*]*\)  *\**\*\*\*/\n\1\n/g' -e '/Changelog/d' -e '/^NSIS_1.x_version_history/,/^=/c\    http://nsis.sourceforge.net/download/nsis1/' -e 's/^\(Released.*\)/    \1\n/g' | cat -s > "$@"

# Convert DocBook to man page
$(BUILDDIR)/%.1: debian/%.xml
	xsltproc --nonet --output $@ $<

override_dh_auto_build-arch: $(BUILDDIR)/NEWS $(BUILDDIR)/GenPat.1 $(BUILDDIR)/makensis.1
	scons $(SCONSOPTS_HOST) utils makensis

override_dh_auto_build-indep: $(BUILDDIR)/NEWS
	# nsis-common must be built on little-endian
	[ "$(shell dpkg-architecture -qDEB_BUILD_ARCH_ENDIAN)" = "little" ]

	scons $(SCONSOPTS_HOST) makensis
ifdef XGCC_W32_X86_PATH
	scons $(SCONSOPTS_COMMON) $(SCONSOPTS_X86) stubs plugins utils
endif
ifdef XGCC_W32_AMD64_PATH
	scons $(SCONSOPTS_COMMON) $(SCONSOPTS_AMD64) stubs plugins utils
endif
	$(call HTML2TEXT_PRETTY,"Contrib/Modern UI/Readme.html","$(BUILDDIR)/README.Modern UI")
	$(call HTML2TEXT_PRETTY,"Contrib/Modern UI 2/Readme.html","$(BUILDDIR)/README.Modern UI 2")
	$(call HTML2TEXT_PRETTY,Contrib/VPatch/Readme.html,$(BUILDDIR)/README.VPatch)
	$(call HTML2TEXT_PRETTY,Contrib/InstallOptions/Readme.html,$(BUILDDIR)/README.InstallOptions)
	$(call HTML2TEXT_PRETTY,Contrib/MultiUser/Readme.html,$(BUILDDIR)/README.MultiUser)
	$(call HTML2TEXT_PRETTY,Contrib/nsDialogs/Readme.html,$(BUILDDIR)/README.nsDialogs)

override_dh_auto_test-arch:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
	scons $(SCONSOPTS_HOST) test-code
endif

override_dh_auto_test-indep:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
	test -x "$(BUILDDIR)/$(BUILDTYPE)/makensis/makensis" && \
	scons $(INSTALL_FLAGS_nsis) PREFIX_DEST="$(TESTDIR)"\
		install-compiler install-conf && \
	scons $(INSTALL_FLAGS_nsis-doc) PREFIX_DEST="$(TESTDIR)"\
		install-examples && \
	scons $(INSTALL_FLAGS_nsis-common) $(SCONSOPTS_X86) PREFIX_DEST="$(TESTDIR)" \
		$(INSTALL_nsis-common) && \
	scons $(INSTALL_FLAGS_nsis-common) $(SCONSOPTS_AMD64) PREFIX_DEST="$(TESTDIR)" \
		$(INSTALL_nsis-common) && \
	$(call SANITIZE_MODERN_UI,$(TESTDIR)$(DOCDIR)/Examples/Modern UI) && \
	for script_path in $(TESTDIR)$(SCRIPTS_PATH)/*.nsi \
		$(TESTDIR)$(SCRIPTS_PATH)/*/*.nsi; do \
		script=$${script_path#$(TESTDIR)$(SCRIPTS_PATH)/}; \
		if [ "$${script%/*}" != "$${script}" ]; then \
			mkdir -p "$(TESTDIR)/$${script%/*}"; \
		fi; \
		case $${script} in \
		$(IGNORE_TESTS)) ;; \
		*) \
		if [ -f "$${script_path}" ]; then \
			PATH=$(TESTDIR)$(PREFIX)/bin:$(PATH) \
			NSISDIR=$(TESTDIR)$(DATADIR) \
			NSISCONFDIR=$(TESTDIR)$(SYSCONF) \
			"$(TESTDIR)$(PREFIX)/bin/makensis" \
			"$${script_path}" \
			-X"OutFile \"$(TESTDIR)/$${script%.nsi}.exe\"" \
			|| exit 1; \
		fi;; \
		esac; \
	done;
	# Fail the build if libwinpthread is needed at runtime (see #722898)
	test `find $(TESTDIR)$(DATADIR)/Plugins -iname "*.dll" -exec objdump -p {} \; | grep -E "file format|DLL Name" | grep -cim1 libwinpthread` -eq 0
endif

override_dh_auto_install-arch:
	$(foreach p,$(shell dh_listpackages -a),$(call DO_SCONS_INSTALL,$(p)))

override_dh_fixperms-arch:
	dh_fixperms
	find "$(INSTDIR)/nsis/$(SYSCONF)" \
		-type f -perm /111 -exec chmod a-x {} \;

override_dh_auto_install-indep:
	$(foreach p,$(shell dh_listpackages -i),$(call DO_SCONS_INSTALL,$(p),$(SCONSOPTS_X86)))
	$(foreach p,$(shell dh_listpackages -i),$(call DO_SCONS_INSTALL,$(p),$(SCONSOPTS_AMD64)))
	# Add plugin example to nsis-pluginapi package
	$(call DO_SCONS_INSTALL_EXTRA,nsis-pluginapi,$(DOCDIR)/Examples/Plugin)
	# Exclude any architecture dependent binaries from nsis-common
	rm -rf "$(INSTDIR)/nsis-common$(PREFIX)/bin"
	# Clean up examples and documentation
	# The docs file can't seem to have spaces within the file name(s)
	dh_installdocs -pnsis-doc "$(BUILDDIR)/README.Modern UI" \
		"$(BUILDDIR)/README.Modern UI 2"
	rm "debian/nsis-doc$(DOCDIR)/Docs/Modern UI/License.txt"
	rm "debian/nsis-doc$(DOCDIR)/Docs/Modern UI 2/License.txt"
	rm "debian/nsis-doc$(DOCDIR)/Docs/NSISdl/License.txt"
	$(call SANITIZE_MODERN_UI,$(INSTDIR)/nsis-doc$(DOCDIR)/Examples/Modern UI)
	# Replace duplicate image files with symbolic links
	$(call SYMLINK_DUPLICATES,$(INSTDIR)/nsis-doc$(DOCDIR)/Docs/Modern UI/images,$(INSTDIR)/nsis-doc$(DOCDIR)/Docs/Modern UI 2/images,../../Modern UI/images)

override_dh_compress-indep:
	dh_compress -X.nlf -X.nsh -X.nsi -X.dll
	# Adapt links to documents with those of their compressed version
	if [ -d debian/nsis-doc$(DOCDIR) ]; then \
		cd debian/nsis-doc$(DOCDIR) ; \
		find -mindepth 2 -name \*.gz | \
		sed -e 's,^\.\(.\+\)\.gz$$,\1,g' -e 's, ,%20,g' | \
		xargs -i88 sh -c 'fgrep -rl "88\"" . | \
		xargs -i{} sed -i -e "s|88\"|88.gz\"|g" "{}"'; \
	fi

override_dh_fixperms-indep:
	dh_fixperms
	# Remove executable flag from data files
	find "$(INSTDIR)/nsis-common$(DATADIR)" \
		-type f -perm /111 -exec chmod a-x {} \;
	# Fix permissions for plugin API header and library files
ifdef XGCC_W32_X86_PATH
	find "$(INSTDIR)/nsis-pluginapi$(XGCC_W32_X86_PATH)" \
		-type f -perm /111 -exec chmod a-x {} \;
endif
ifdef XGCC_W32_AMD64_PATH
	find "$(INSTDIR)/nsis-pluginapi$(XGCC_W32_AMD64_PATH)" \
		-type f -perm /111 -exec chmod a-x {} \;
endif
