#!/usr/bin/make -f

# resolve DEB_VERSION_UPSTREAM DEB_DISTRIBUTION
include /usr/share/dpkg/pkg-info.mk

# resolve DEB_BUILD_OPTION_PARALLEL
-include /usr/share/dpkg/buildopts.mk

# resolve if release is experimental
EXP_RELEASE = $(filter experimental% UNRELEASED,$(DEB_DISTRIBUTION))

# will run a generated subset of tests
# to re-generate it, run and interrupt
# test/runner.py randomcore2100
# test/runner.py randomwasm2js2100
# and copy the lists into it
TESTS_SUBSET = debian/tests_subset.txt

# Handle both "~dfsg" and the future "+dfsg"
DEB_VERSION_UPSTREAM_ORIG := $(firstword $(subst ~,$() ,$(DEB_VERSION_UPSTREAM)))
DEB_VERSION_UPSTREAM_ORIG := $(firstword $(subst +,$() ,$(DEB_VERSION_UPSTREAM_ORIG)))

DOCS_SRC = README.md
ifeq (,$(filter nodoc,$(DEB_BUILD_OPTIONS)))
DOCS = $(DOCS_SRC:md=html) $(DOCS_SRC:md=txt)
CHANGELOGS = ChangeLog.html ChangeLog.txt
endif

_ENV = $(strip PATH="$(CURDIR):$$PATH")

# generate manpage with help2man from --help option of python script
_mkman = $(_ENV) \
 help2man $(if $3,--name "$(strip $3)") --no-info --version-string $(DEB_VERSION_UPSTREAM) --output $2 $1 \
 || { $(_ENV) $1 --help; false; }
_mkman_sloppy = $(_ENV) \
 help2man $(if $3,--name "$(strip $3)") --no-info --version-string $(DEB_VERSION_UPSTREAM) --no-discard-stderr --output $2 $1 \
 || true

ifneq (,$(DEB_BUILD_OPTION_PARALLEL))
export EMCC_CORES=$(DEB_BUILD_OPTION_PARALLEL)
endif

EMCC = $(_ENV) emcc
TESTS_RUNNER = $(_ENV)\
 EMTEST_LACKS_CLOSURE_COMPILER=1\
 EMTEST_SKIP_V8=1\
 EMTEST_SKIP_WASM64=1\
 EMTEST_SKIP_EH=1\
 EMTEST_SKIP_FLAKY=1\
 EMTEST_SKIP_JSPI=1\
 EMTEST_SKIP_NODE_25=$(shell node -p "parseInt(process.versions.node) < 25 ? 1 : ''")\
 HOME=$(CURDIR)/cache\
 test/runner.py --skip-slow --cores=1

# files generated during build
NEON_H = system/include/compat/arm_neon.h

# requires third-party tests
#  * test_freetype also requires symlinked LiberationSansBold.ttf
#  * test_poppler also requires tests.poppler.paper.pdf
ERRORS_core += \
 test_freetype \
 test_lua \
 test_openjpeg \
 test_poppler

# requires Emscripten Ports
ERRORS_other += \
 test_boost_graph \
 test_bullet \
 test_bullet_autoconf \
 test_bullet_cmake \
 test_bzip2 \
 test_cmake_find_sdl2 \
 test_cmake_find_stuff \
 test_cmake_html \
 test_deps_info \
 test_freetype \
 test_giflib \
 test_libjpeg \
 test_libpng \
 test_contrib_ports \
 test_sdl2_config \
 test_sdl2_gfx_linkable \
 test_sdl2_linkable \
 test_sdl2_mixer_wav \
 test_sdl2_ttf \
 test_vorbis

# attempts to download files from a remote server
ERRORS_other += \
 test_icu \
 test_pthread_icu

# avoid unimportant mode causing multiple failures: strict
CHECK_MODES_coreX = core0 core1 core2 core3 cores corez
CHECK_MODES_coreZ = corez wasm2jsz
CHECK_MODES_core23Z = core2 core3 corez
CHECK_MODES_coreJS = wasm2js1 wasm2js2 wasm2js3 wasm2jss wasm2jsz
CHECK_MODES_coreJS1S = wasm2js1 wasm2jss

# expects smaller output
FAILS_core1 += \
 test_emscripten_lazy_load_code_unconditional
FAILS_other += \
 test_function_exports_are_small \
 test_js_function_names_are_minified \
 test_metadce_minimal_pthreads \
 test_minimal_runtime_code_size_*

# needs node module wasm2c
FAILS_other += \
 test_wasm2c_multi_lib \

# requires bugfix for Error: FS error
FAILS_core += \
 test_fs_nodefs_home

# requires bugfix for RuntimeError: memory access out of bounds
FAILS_core += \
 test_pthread_dylink_exceptions

# unreliable; sometimes fails with AssertionError: Expected to find ... pthread sent an error! undefined:undefined: Aborted().
FAILS_core += \
 test_pthread_abort \

# likely requires newer LLVM
ERRORS_core += \
 test_dylink_syslibs_missing_assertions
FAILS_other += \
 test_lld_report_undefined_exceptions

# unknown cause
FAILS_coreX += \
 test_dlfcn_self \
 test_pthread_exit_process \
 test_pthread_proxying
FAILS_other += \
 test_cmake_stdproperty \
 test_embind_finalization \
 test_ld_library_path \
 test_metadce_hello_main_module_2 \
 test_minimal_dynamic \
 test_split_main_module

NONSCRIPT_EXECUTABLE = \
 tools/system_libs.py

SCRIPT_NOT_EXECUTABLE = ""

override_dh_clean:
	dh_clean -- $(DOCS) $(CHANGELOGS)

override_dh_auto_configure: $(NEON_H)
# refresh upstream version hints from Debian package
	cp -f emscripten-version.txt emscripten-version.txt.orig
	echo $(DEB_VERSION_UPSTREAM_ORIG) > emscripten-version.txt
	echo $(patsubst $(DEB_VERSION_UPSTREAM_ORIG)-%,%,$(DEB_VERSION_UPSTREAM_ORIG_REVISION)) \
		> emscripten-revision.txt
	tools/maint/create_dom_pk_codes.py
	tools/maint/create_entry_points.py

execute_before_dh_auto_build:
	$(EMCC) --generate-config

# set local cache, no freeze
override_dh_auto_build:
	cp .emscripten debian/.emscripten
	echo "BINARYEN_ROOT = '/usr'" >> debian/.emscripten
	echo "EMSCRIPTEN_ROOT	= '/usr/share/emscripten'" >> debian/.emscripten
	echo "import os\nCACHE = os.path.expanduser(os.path.join('~', '.cache', 'emscripten'))" >> debian/.emscripten

execute_after_dh_auto_build-arch: $(DOCS) $(CHANGELOGS)

# build documentation unless nodoc requested
execute_after_dh_auto_build-indep: $(DOCS) $(CHANGELOGS)
ifeq (,$(filter nodoc,$(DEB_BUILD_OPTIONS)))
	sphinx-build -b html -D html_theme=sphinx_rtd_theme site/source debian/doc/html
endif

execute_before_dh_auto_test:
	ln -sT /usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf test/freetype/LiberationSansBold.ttf

ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
override_dh_auto_test:
	pkgjs-install-minimal
	$(EMCC) test/hello_world.c
	esbuild --target=es6 a.out.js > /dev/null
	$(EMCC) -O3 test/hello_world.c
	esbuild --target=es6 a.out.js > /dev/null
	rm a.out.js a.out.wasm
ifeq (,$(TESTS_SUBSET))
	$(TESTS_RUNNER) test_zlib_configure test_zlib_cmake
	$(TESTS_RUNNER) \
		$(CHECK_MODES_coreX) $(CHECK_MODES_coreJS) \
		$(addprefix skip:core*.,$(ERRORS_core) $(FAILS_core)) \
		$(addprefix skip:wasm*.,$(ERRORS_core) $(FAILS_core)) \
		$(addprefix skip:core1.,$(FAILS_core1)) \
		$(addprefix skip:core2.,$(FAILS_core2)) \
		$(foreach mode,$(CHECK_MODES_coreX),\
			$(addprefix skip:$(mode).,$(FAILS_coreX))) \
		$(foreach mode,$(CHECK_MODES_coreZ),\
			$(addprefix skip:$(mode).,$(FAILS_coreZ))) \
		$(foreach mode,$(CHECK_MODES_core23Z),\
			$(addprefix skip:$(mode).,$(FAILS_core23Z))) \
		$(foreach mode,$(CHECK_MODES_coreJS),\
			$(addprefix skip:$(mode).,$(FAILS_coreJS))) \
		$(foreach mode,$(CHECK_MODES_coreJS1S),\
			$(addprefix skip:$(mode).,$(FAILS_coreJS1S))) \
	$(TESTS_RUNNER) other \
		$(addprefix skip:other.,$(ERRORS_other) $(FAILS_other))
else
	$(TESTS_RUNNER) $(shell sed 's/^\* //; s/$$/ /' $(TESTS_SUBSET))
endif
endif

execute_after_dh_install:
	mkdir -p debian/emscripten/usr/bin
	python3 -c 'from tools.maint.create_entry_points import entry_points, compiler_entry_points; print(*compiler_entry_points, *entry_points, sep="\n")' | \
	while IFS= read -r p; do \
		b=$$(basename "$$p"); \
		if [ "$$(dirname "$$p")" = "." ]; then ln -sf "../share/emscripten/$$b" "debian/emscripten/usr/bin/$$b"; fi; \
	done

execute_after_dh_auto_install:
	$(call _mkman, em++, debian/em++.1,\
		emscripten compiler for WASM and JavaScript like g++ or clang++)
	$(call _mkman_sloppy, em-config, debian/em-config.1,\
		helper tool to read emscripten configuration variables)
	$(call _mkman, emar, debian/emar.1,\
		emscripten archiver for WASM and JavaScript like ar or llvm-ar)
	$(call _mkman, embuilder, debian/embuilder.1,\
		Tool to manage building of Emscripten system libraries and ports)
	$(call _mkman, emcc, debian/emcc.1,\
		emscripten compiler for WASM and JavaScript like gcc or clang)
	$(call _mkman_sloppy, emcmake, debian/emcmake.1,\
		emscripten wrapper cmake)
	$(call _mkman_sloppy, emconfigure, debian/emconfigure.1,\
		emscripten wrapper around ./configure scripts)
	$(call _mkman, emdwp, debian/emdwp.1,\
		emscripten wrapper around llvm-dwp)
	$(call _mkman_sloppy, emmake, debian/emmake.1,\
		emscripten wrapper around make)
	$(call _mkman, emnm, debian/emnm.1,\
		emscripten wrapper around llvm-nm)
	$(call _mkman, emprofile, debian/emprofile.1,\
		emscripten profiler tool)
	$(call _mkman, emranlib, debian/emranlib.1,\
		emscripten wrapper around llvm-ranlib)
	$(call _mkman, emrun, debian/emrun.1,\
		emscripten tool to compile as an HTML page)
	$(call _mkman_sloppy, emscons, debian/emscons.1,\
		emscripten wrapper around scons)
	$(call _mkman, emsize, debian/emsize.1,\
		emscripten replacement for size)
	$(call _mkman, emstrip, debian/emstrip.1,\
		emscripten wrapper around llvm-strip)
	$(call _mkman, emsymbolizer, debian/emsymbolizer.1,\
		emscripten utility for looking up symbol names and/or file+line numbers of code addresses)

# avoid cache sanity hint, license and Visual Studio files
override_dh_install:
	dh_install $(addprefix --exclude=,\
		sanity.txt \
		COPYING GPL LICENSE License.txt license.dox \
		.dsp .dsw .sln .vcproj)
	rm -rf debian/emscripten/usr/share/emscripten/test
	find debian/emscripten/usr/share/emscripten \( -iname 'README*' -o -iname 'CREDITS.TXT' -o -iname 'CHANGELOG.*' \) -delete

override_dh_installdocs:
	dh_installdocs -- $(DOCS)

override_dh_installchangelogs:
	dh_installchangelogs -- $(CHANGELOGS)

execute_after_dh_fixperms:
	chmod -x $(addprefix debian/emscripten/usr/share/emscripten/,\
		$(NONSCRIPT_EXECUTABLE))
	chmod +x $(addprefix debian/emscripten/usr/share/emscripten/,\
		$(SCRIPT_NOT_EXECUTABLE))

# restore maybe-outdated upstream version hint
override_dh_auto_clean:
	[ ! -e emscripten-version.txt.orig ] \
		|| mv -f emscripten-version.txt.orig emscripten-version.txt
	rm -f .emscripten $(NEON_H)
	find . -maxdepth 1 -type l -delete
	find . -maxdepth 1 -type f -name 'em*' ! -name '*.*' -delete
	rm -f test/runner tools/file_packager tools/webidl_binder
	rm -f test/freetype/LiberationSansBold.ttf

# generate header file from SIMDe source
$(NEON_H): /usr/include/simde/arm/neon.h
	echo '#define SIMDE_ARM_NEON_A32V7_ENABLE_NATIVE_ALIASES' > $@
	echo '#define SIMDE_ARM_NEON_A32V8_ENABLE_NATIVE_ALIASES' >> $@
	echo '#define SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES' >> $@
	echo '#include "/usr/include/simde/arm/neon.h"' >> $@
	echo '#undef SIMDE_ARM_NEON_A32V7_ENABLE_NATIVE_ALIASES' >> $@
	echo '#undef SIMDE_ARM_NEON_A32V8_ENABLE_NATIVE_ALIASES' >> $@
	echo '#undef SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES' >> $@

override_dh_gencontrol:
	dh_gencontrol -- -V"types:Version=$(shell jq --raw-output .version < Xtypes/package.json)~$(DEB_VERSION)"

%.html: %.md
	cmark-gfm $< > $@

%.txt: %.md
	cmark-gfm --to plaintext $< > $@

%:
	dh $@
