#!/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))

DEB_VERSION_UPSTREAM_ORIG = $(firstword $(subst ~,$() ,$(DEB_VERSION_UPSTREAM)))

_ENV = $(strip \
 PATH="$(CURDIR)/debian/tmpbin:$$PATH" \
 EM_CACHE="$(CURDIR)/debian/em_cache")

# 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) --output $2 $1 \
 || true

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

EMCC = $(_ENV) emcc
TESTS_RUNNER = $(_ENV) EMTEST_SKIP_SLOW=1 EMTEST_LACKS_CLOSURE_COMPILER=1 EMTEST_SKIP_V8=1 tests/runner.py
# use ccache when available
ifneq (,$(wildcard /usr/bin/ccache))
override_dh_auto_test: export EM_COMPILER_WRAPPER=ccache
endif

# files generated during build
SOURCE_MAP_MIN_JS = src/emscripten-source-map.min.js
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_wasm += \
 test_freetype \
 test_lua \
 test_openjpeg \
 test_poppler

# requires Emscripten Ports
ERRORS_other += \
 test_bullet \
 test_bullet_autoconf \
 test_bullet_cmake \
 test_bzip2 \
 test_cmake_find_stuff \
 test_cmake_html \
 test_deps_info \
 test_freetype \
 test_libjpeg \
 test_libpng \
 test_sdl2_gfx_linkable \
 test_sdl2_linkable \
 test_sdl2_mixer_wav \
 test_vorbis
FAILS_CERTAIN_other += \
 test_boost_graph

# avoid unimportant mode causing multiple failures: strict
CHECK_MODES_WASMX = wasm0 wasm1 wasm2 wasm3 wasms wasmz
CHECK_MODES_WASMZ = wasmz wasm2jsz
CHECK_MODES_WASM23Z = wasm2 wasm3 wasmz
CHECK_MODES_WASMJS = wasm2js1 wasm2js2 wasm2js3 wasm2jss wasm2jsz
CHECK_MODES_WASMJS1S = wasm2js1 wasm2jss

# expects smaller output
FAILS_wasm1 += \
 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_wasmX += \
 test_autodebug_wasm_standalone \
 test_cube2hash_standalone \
 test_longjmp_standalone \
 test_posixtime_standalone \
 test_wasm2c_sandboxing_full \
 test_wasm2c_sandboxing_mask \
 test_wasm2c_sandboxing_none
FAILS_other += \
 test_wasm2c_multi_lib \
 test_wasm2c_reactor

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

# unreliable; sometimes fails with AssertionError: Expected to find 'done!
UNRELIABLE_wasm += \
 test_pthread_c11_threads

# requires newer LLVM: <https://github.com/emscripten-core/emscripten/issues/13773>
FAILS_wasm += \
 test_dylink_weak

# likely requires newer LLVM
ERRORS_wasm += \
 test_dylink_syslibs_missing_assertions
FAILS_wasm += \
 test_relaxed_simd_implies_simd128
FAILS_other += \
 test_lld_report_undefined_exceptions

# requires newer LLVM: see <https://reviews.llvm.org/D108877> and git commit 06dcec6
FAILS_wasm += \
 test_pthread_dylink_tls \
 test_dylink_tls_export

# unknown cause
FAILS_wasm2js2 += \
 test_pthread_abort
FAILS_wasmX += \
 test_pthread_exit_process
FAILS_wasmZ += \
 test_float_builtins
FAILS_other += \
 test_cmake_stdproperty

BIN_WRAPPER_SYMLINK = \
 em++ \
 emar \
 embuilder \
 emcc \
 emcmake \
 em-config \
 emconfigure \
 emmake \
 emranlib \
 emrun \
 emscons \
 emsize

BIN_WRAPPER_TOOLS_SYMLINK = \
 emdump \
 emdwp \
 emnm \
 emprofile \

NONSCRIPT_EXECUTABLE = \
 system/lib/libcxx/readme.txt \
 tests/other/wasm_sourcemap/foo.wasm \
 tests/other/wasm_sourcemap_dead/t.wasm \
 tools/system_libs.py

SCRIPT_NOT_EXECUTABLE = \
 src/compiler.js \
 tests/embind/build_benchmark \
 tests/sourcemap2json.js \
 tools/preprocessor.js \
 tools/run_python_compiler.sh

%:
	dh $@

override_dh_auto_configure: $(SOURCE_MAP_MIN_JS) $(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/create_dom_pk_codes.py
	mkdir -p debian/em_cache
# setup binaries for use during build-time testing
	mkdir --parents debian/tmpbin
	sed "s,/usr/share/emscripten/,$$PWD/," < debian/bin/wrapper > debian/tmpbin/wrapper
	sed "s,/usr/share/emscripten/,$$PWD/," < debian/bin/wrapper-tools > debian/tmpbin/wrapper-tools
	chmod +x debian/tmpbin/wrapper debian/tmpbin/wrapper-tools
	$(foreach symlink,$(BIN_WRAPPER_SYMLINK),ln -fsT wrapper debian/tmpbin/$(symlink);)
	$(foreach symlink,$(BIN_WRAPPER_TOOLS_SYMLINK),ln -fsT wrapper-tools debian/tmpbin/$(symlink);)

override_dh_auto_build:

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

execute_after_dh_auto_install:
	$(EMCC) -v 2>&1
	$(call _mkman, debian/tmpbin/em++, debian/em++.1,\
		emscripten compiler for WASM and JavaScript like g++ or clang++)
	$(call _mkman, debian/tmpbin/emar, debian/emar.1,\
		emscripten archiver for WASM and JavaScript like ar or llvm-ar)
	$(call _mkman, debian/tmpbin/embuilder, debian/embuilder.1,\
		Tool to manage building of Emscripten system libraries and ports)
	$(call _mkman, debian/tmpbin/emcc, debian/emcc.1,\
		emscripten compiler for WASM and JavaScript like gcc or clang)
	$(call _mkman_sloppy, debian/tmpbin/emcmake, debian/emcmake.1,\
		emscripten wrapper cmake)
	$(call _mkman_sloppy, debian/tmpbin/em-config, debian/em-config.1,\
		helper tool to read emscripten configuration variables)
	$(call _mkman_sloppy, debian/tmpbin/emconfigure, debian/emconfigure.1,\
		emscripten wrapper around ./configure scripts)
	$(call _mkman_sloppy, debian/tmpbin/emmake, debian/emmake.1,\
		emscripten wrapper around make)
	$(call _mkman, debian/tmpbin/emranlib, debian/emranlib.1,\
		emscripten wrapper around llvm-ranlib)
	$(call _mkman, debian/tmpbin/emrun, debian/emrun.1,\
		emscripten tool to compile as an HTML page)
#	$(call _mkman, debian/tmpbin/emscons, debian/emscons.1,\
#		emscripten wrapper around scons)
	$(call _mkman, debian/tmpbin/emsize, debian/emsize.1,\
		emscripten replacement for size)
	$(call _mkman, debian/tmpbin/emdump, debian/emdump.1,\
		emscripten tool to print out statistics about compiled code sizes)
	$(call _mkman, debian/tmpbin/emdwp, debian/emdwp.1,\
		emscripten wrapper around llvm-dwp)
	$(call _mkman, debian/tmpbin/emnm, debian/emnm.1,\
		emscripten wrapper around llvm-nm)
	$(call _mkman, debian/tmpbin/emprofile, debian/emprofile.1,\
		emscripten profiler tool)

ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
override_dh_auto_test:
	$(EMCC) -v 2>&1
	$(EMCC) tests/hello_world.c
	eslint --no-eslintrc --quiet --env browser --format unix a.out.js
	$(EMCC) -O3 tests/hello_world.c
	eslint --no-eslintrc --quiet --env browser --format unix a.out.js
	rm a.out.js a.out.wasm
	ln -sT /usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf \
		tests/freetype/LiberationSansBold.ttf
	$(TESTS_RUNNER) test_zlib_configure test_zlib_cmake
	$(TESTS_RUNNER) \
		$(CHECK_MODES_WASMX) $(CHECK_MODES_WASMJS) \
		$(addprefix skip:wasm*.,$(ERRORS_wasm) $(FAILS_wasm)) \
		$(addprefix skip:wasm1.,$(FAILS_wasm1)) \
		$(addprefix skip:wasm2js1.,$(FAILS_wasm2js1)) \
		$(addprefix skip:wasm2js2.,$(FAILS_wasm2js2)) \
		$(addprefix skip:wasm2jss.,$(FAILS_wasm2jss)) \
		$(foreach wasm,$(CHECK_MODES_WASMX),\
			$(addprefix skip:$(wasm).,$(FAILS_wasmX))) \
		$(foreach wasm,$(CHECK_MODES_WASMZ),\
			$(addprefix skip:$(wasm).,$(FAILS_wasmZ))) \
		$(foreach wasm,$(CHECK_MODES_WASM23Z),\
			$(addprefix skip:$(wasm).,$(FAILS_wasm23Z))) \
		$(foreach wasm,$(CHECK_MODES_WASMJS),\
			$(addprefix skip:$(wasm).,$(FAILS_wasmJS))) \
		$(foreach wasm,$(CHECK_MODES_WASMJS1S),\
			$(addprefix skip:$(wasm).,$(FAILS_wasmJS1S))) \
		$(if $(EXP_RELEASE),|| true)
	$(TESTS_RUNNER) other \
		$(addprefix skip:other.,$(ERRORS_other) $(FAILS_CERTAIN_other) $(FAILS_other)) \
		$(if $(EXP_RELEASE),|| true)
	$(TESTS_RUNNER) \
		$(foreach wasm,$(CHECK_MODES_WASMX) $(CHECK_MODES_WASMJS),\
			$(addprefix $(wasm).,$(UNRELIABLE_wasm))) \
		|| true
ifneq (,$(EXP_RELEASE))
	$(TESTS_RUNNER) \
		$(addprefix wasm1.,$(FAILS_wasm1)) \
		$(addprefix wasm2js1.,$(FAILS_wasm2js1)) \
		$(addprefix wasm2js2.,$(FAILS_wasm2js2)) \
		$(addprefix wasm2jss.,$(FAILS_wasm2jss)) \
		$(foreach wasm,$(CHECK_MODES_WASMX) $(CHECK_MODES_WASMJS),\
			$(addprefix $(wasm).,$(FAILS_wasm))) \
		$(foreach wasm,$(CHECK_MODES_WASMX),\
			$(addprefix $(wasm).,$(FAILS_wasmX))) \
		$(foreach wasm,$(CHECK_MODES_WASMZ),\
			$(addprefix $(wasm).,$(FAILS_wasmZ))) \
		$(foreach wasm,$(CHECK_MODES_WASM23Z),\
			$(addprefix $(wasm).,$(FAILS_wasm23Z))) \
		$(foreach wasm,$(CHECK_MODES_WASMJS),\
			$(addprefix $(wasm).,$(FAILS_wasmJS))) \
		$(foreach wasm,$(CHECK_MODES_WASMJS1S),\
			$(addprefix $(wasm).,$(FAILS_wasmJS1S))) \
		$(addprefix other.,$(FAILS_other)) \
		|| true
endif
	rm -f tests/freetype/LiberationSansBold.ttf
endif

# avoid license and Visual Studio files
override_dh_install:
	dh_install $(addprefix --exclude=,\
		COPYING GPL LICENSE License.txt license.dox \
		.dsp .dsw .sln .vcproj)

# webassembly code is alien to dh_strip
override_dh_strip:
	dh_strip --exclude=/usr/share/emscripten/cache

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 -rf debian/em_cache debian/tmpbin
	rm -f .emscripten $(SOURCE_MAP_MIN_JS) $(NEON_H)

# 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_A64V8_ENABLE_NATIVE_ALIASES' >> $@
	cat $< >> $@
	echo '#undef SIMDE_ARM_NEON_A32V7_ENABLE_NATIVE_ALIASES' >> $@
	echo '#undef SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES' >> $@

# join source-less and source-only parts of upstream source-map script
$(SOURCE_MAP_MIN_JS): \
 /usr/share/javascript/source-map/source-map.min.js \
 debian/missing-sources/source-map-footer_$(DEB_VERSION_UPSTREAM_ORIG).js
	cat $^ > $@

# custom rule: get source-only part of upstream source-map script
# (see README.source)
get-source-map-footer:
	wget -O- https://github.com/emscripten-core/emscripten/raw/$(DEB_VERSION_UPSTREAM_ORIG)/src/emscripten-source-map.min.js \
		| tail -n +2 \
		> debian/missing-sources/source-map-footer_$(DEB_VERSION_UPSTREAM_ORIG).js

# TODO: drop when bug#1000136 is fixed
override_dh_sphinxdoc:
	dh_sphinxdoc -i || { \
	rm -rf debian/emscripten-doc/usr/share/doc/emscripten-doc/html/.doctrees;\
	find debian/emscripten-doc -type f -name .buildinfo -delete;\
	ln --symbolic --force \
		--target-directory=debian/emscripten-doc/usr/share/doc/emscripten-doc/html/_static/ \
		$(addprefix ../../../../javascript/sphinxdoc/1.0/,doctools.js jquery.js language_data.js searchtools.js underscore.js);\
	}

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