# Makefile wrapper for CMake-based NIF build

ifndef MIX_APP_PATH
	MIX_APP_PATH=$(shell pwd)
endif

PRIV_DIR = $(MIX_APP_PATH)/priv
NIF_SO = $(PRIV_DIR)/hexagon_tpu_nif.so
CMAKE_BUILD_DIR = $(MIX_APP_PATH)/cmake_build

# Accept QAIRT_SDK_PATH as an alias for QNN_SDK_ROOT
ifndef QNN_SDK_ROOT
	ifdef QAIRT_SDK_PATH
		QNN_SDK_ROOT = $(QAIRT_SDK_PATH)
	endif
endif

ifdef CMAKE_TOOLCHAIN_FILE
	CMAKE_CONFIGURE_FLAGS=-D CMAKE_TOOLCHAIN_FILE="$(CMAKE_TOOLCHAIN_FILE)"
else ifdef CROSSCOMPILE
	# Nerves exports CC/CXX/CROSSCOMPILE; use the generic env-driven cross file.
	CMAKE_CONFIGURE_FLAGS=-D CMAKE_TOOLCHAIN_FILE="$(shell pwd)/cmake/env-toolchain.cmake"
endif

CMAKE_BUILD_TYPE ?= Release
MAKE_JOBS ?= $(shell nproc 2>/dev/null || echo 1)

build: check_sdk $(NIF_SO)

check_sdk:
ifndef QNN_SDK_ROOT
	$(error QNN_SDK_ROOT is not set. Point it at an extracted QAIRT SDK \
	(e.g. .../qairt/2.42.0.251225) so the QNN headers under include/QNN are found. \
	QAIRT_SDK_PATH is accepted as an alias)
endif

NIF_SOURCES = $(wildcard c_src/*.cpp) $(wildcard c_src/*.hpp) CMakeLists.txt

# cc_precompiler builds several targets in the same checkout. The .so must be
# rebuilt (from a clean CMake cache) whenever the toolchain changes, or a
# stale artifact from the previous target gets shipped.
TOOLCHAIN_ID = $(CC)|$(CXX)|$(CROSSCOMPILE)|$(CMAKE_TOOLCHAIN_FILE)|$(QNN_SDK_ROOT)
TOOLCHAIN_STAMP = $(CMAKE_BUILD_DIR)/.toolchain

$(TOOLCHAIN_STAMP): FORCE
	@mkdir -p "$(CMAKE_BUILD_DIR)"
	@if [ "$$(cat '$@' 2>/dev/null)" != '$(TOOLCHAIN_ID)' ]; then \
		rm -rf "$(CMAKE_BUILD_DIR)" "$(NIF_SO)"; \
		mkdir -p "$(CMAKE_BUILD_DIR)"; \
		printf '%s' '$(TOOLCHAIN_ID)' > "$@"; \
	fi

FORCE:

$(NIF_SO): $(PRIV_DIR) $(NIF_SOURCES) $(TOOLCHAIN_STAMP)
	@ mkdir -p "$(CMAKE_BUILD_DIR)" && \
	cd "$(CMAKE_BUILD_DIR)" && \
	cmake --no-warn-unused-cli \
		-D CMAKE_BUILD_TYPE="$(CMAKE_BUILD_TYPE)" \
		-D C_SRC="$(shell pwd)/c_src" \
		-D MIX_APP_PATH="$(MIX_APP_PATH)" \
		-D PRIV_DIR="$(PRIV_DIR)" \
		-D ERTS_INCLUDE_DIR="$(ERTS_INCLUDE_DIR)" \
		-D QNN_SDK_ROOT="$(QNN_SDK_ROOT)" \
		$(CMAKE_CONFIGURE_FLAGS) "$(shell pwd)" && \
	cmake --build . --config "$(CMAKE_BUILD_TYPE)" -j$(MAKE_JOBS) && \
	cp "hexagon_tpu_nif.so" "$(NIF_SO)"

clean:
	@rm -rf "$(CMAKE_BUILD_DIR)"
	@rm -f "$(NIF_SO)"

$(PRIV_DIR):
	@mkdir -p "$(PRIV_DIR)"

.PHONY: build check_sdk clean
