###############################################################################
# This makefile is provided as a simple convenience

## Optional features; either set to 'true' to enable or 'false' to disable:
##   $ make DEBUG=true
## or set 'enabled', 'disabled', or 'auto' (enabled if requirements are met)
##   $ make STATIC=enabled

# Include coverage instrumentation in build
COVERAGE := false

# Debug build; adds warnings, debugging symbols, and extra STL/POSIX asserts
DEBUG := ${COVERAGE}

# Build and install man page
MANPAGE := enabled

# Build and install HTML documentation (https://adapterremoval.readthedocs.org)
DOCS := disabled

# Use `uv` to install dependencies for regression tests
UV := auto

# Enable address and undefined behavior sanitation
SANITIZE := false

# Enable hardening flags
HARDEN := true

# Enable link-time optimizations
# WARNING: Causes irreproducible builds and possibly other issues
LTO := false

# LTO mode; older systems may need to use `make LTO_MODE=default`
LTO_MODE := thin

# Generate statically linked binary
STATIC := false

###############################################################################

# Extra meson flags
MESON_OPTIONS :=

# Enable extra checks for STL and POSIX functions
ifeq ($(strip ${DEBUG}), true)
override MESON_OPTIONS += -Db_ndebug=false
endif

ifeq ($(strip ${SANITIZE}), true)
override MESON_OPTIONS += -Db_sanitize=address,undefined
else
ifneq ($(strip ${SANITIZE}), false)
$(error "SANITIZE must be 'true' or 'false', not '${SANITIZE}'")
endif
endif

# Use custom installation prefix instead of the system default
ifneq ($(strip ${PREFIX}), )
override MESON_OPTIONS += --prefix=${PREFIX}
endif

###############################################################################

# Meson commands cannot be run in parallel
.NOTPARALLEL:

# Default meson build directory
BUILDDIR := build
# Location of ninja build-file; used to detected existing setup
NINJAFILE := ${BUILDDIR}/build.ninja

executable: ${NINJAFILE}
	meson compile -C "${BUILDDIR}" adapterremoval3

executables: ${NINJAFILE}
	meson compile -C "${BUILDDIR}" adapterremoval3 unit_tests

clean:
	rm -rf "${BUILDDIR}" ".venv"

clean-coverage:
	test ! -d "${BUILDDIR}" || find "${BUILDDIR}" -name '*.gcda' -delete

coverage: ${NINJAFILE}
	ninja -C "${BUILDDIR}" coverage-text
	cat build/meson-logs/coverage.txt

coverage-xml: ${NINJAFILE}
	ninja -C "${BUILDDIR}" coverage-xml

docs: ${NINJAFILE}
	meson compile -C "${BUILDDIR}" docs man

install: ${NINJAFILE}
	meson install -C "${BUILDDIR}"

regression-tests: ${NINJAFILE}
	meson compile -C "${BUILDDIR}" run-regression-tests

setup ${NINJAFILE}:
	# WORKAROUND: Ensure that index is up-to-date, to prevent false positive
	#             `dirty` flags from `git describe` when building `version.cpp`
	git update-index --refresh || true
	# WORKAROUND: `setup` fails on existing builddirs without `--reconfigure`,
	#             but that option requires existing builddir in v1.0.0 or older
	rm -rf "${BUILDDIR}"
	meson setup "${BUILDDIR}" \
		-Db_coverage=${COVERAGE} \
		-Db_lto=${LTO} \
		-Db_lto_mode=${LTO_MODE} \
		-Ddebug=${DEBUG} \
		-Dmanpage=${MANPAGE} \
		-Ddocs=${DOCS} \
		-Duv=${UV} \
		-Dharden=${HARDEN} \
		-Dstatic=${STATIC} \
		${MESON_OPTIONS}

unit-tests-executable: ${NINJAFILE}
	meson compile -C "${BUILDDIR}" unit_tests

unit-tests: ${NINJAFILE}
	meson compile -C "${BUILDDIR}" run-unit-tests

update-regression-tests: ${NINJAFILE}
	meson compile -C "${BUILDDIR}" update-regression-tests

test tests: executables unit-tests regression-tests

.PHONY: clean clean-coverage coverage-xml coverage docs executable \
	executables install regression-tests setup test tests unit-tests \
	unit-tests-executable update-regression-tests
