# madcat-say — VoxCPM2 voice-cloning CLI (on-device, MLX/Metal)
#
# MLX needs a compiled Metal shader library (mlx.metallib) sitting next to the
# binary, or inference crashes with "Failed to load the default metallib".
# We reuse the one speech-swift already builds.

SPEECH_SWIFT ?= ../speech-swift
CONFIG       ?= release

.PHONY: build run clean metallib install

build:
	swift build -c $(CONFIG)
	@$(MAKE) --no-print-directory metallib

# Copy the prebuilt metallib next to our binary. SwiftPM's real bin dir is
# triple-prefixed (e.g. .build/arm64-apple-macosx/release) and the
# .build/<config> symlink is not always present in speech-swift, so resolve
# both ends with `swift build --show-bin-path` instead of hardcoding the path.
# If speech-swift hasn't built the metallib yet, fall back to its build script.
metallib:
	@ss_bin="$$(cd "$(SPEECH_SWIFT)" && swift build -c $(CONFIG) --show-bin-path)"; \
	if [ ! -f "$$ss_bin/mlx.metallib" ]; then \
		echo "metallib missing in speech-swift — building it there..."; \
		( cd "$(SPEECH_SWIFT)" && swift build -c $(CONFIG) && ./scripts/build_mlx_metallib.sh $(CONFIG) ); \
		ss_bin="$$(cd "$(SPEECH_SWIFT)" && swift build -c $(CONFIG) --show-bin-path)"; \
	fi; \
	our_bin="$$(swift build -c $(CONFIG) --show-bin-path)"; \
	cp "$$ss_bin/mlx.metallib" "$$our_bin/mlx.metallib"; \
	echo "metallib in place: $$our_bin/mlx.metallib"

# Quick smoke test (default voice).
run: build
	.build/$(CONFIG)/madcat-say "Hello. This is madcat say, running on device."

# Install to ~/.local/bin (binary + metallib alongside it).
install: build
	@mkdir -p $(HOME)/.local/bin
	cp ".build/$(CONFIG)/madcat-say" "$(HOME)/.local/bin/madcat-say"
	cp ".build/$(CONFIG)/mlx.metallib" "$(HOME)/.local/bin/mlx.metallib"
	@echo "installed to ~/.local/bin/madcat-say (with mlx.metallib)"

clean:
	swift package clean
	rm -rf .build
