UPSTREAM=https://github.com/ggml-org/llama.cpp.git
WORKDIR=llama/vendor
FETCH_HEAD=364a7a6d4a786e98947c8a90430ea581213c0ba9

.PHONY: help
help:
	@echo "Available targets:"
	@echo "    sync                 Sync with upstream repositories"
	@echo "    checkout             Checkout upstream repository"
	@echo "    apply-patches        Apply patches to local repository"
	@echo "    format-patches       Format patches from local repository"
	@echo "    clean                Clean local repository"
	@echo
	@echo "Example:"
	@echo "    make -f $(lastword $(MAKEFILE_LIST)) clean apply-patches sync"

.PHONY: sync
sync: llama/build-info.cpp ml/backend/ggml/ggml/src/ggml-metal/ggml-metal-embed.metal

llama/build-info.cpp: llama/build-info.cpp.in llama/llama.cpp
	sed -e 's|@FETCH_HEAD@|$(FETCH_HEAD)|' <$< >$@

ml/backend/ggml/ggml/src/ggml-metal/ggml-metal-embed.metal: ml/backend/ggml/ggml
	go generate ./$(@D)

.PHONY: llama/llama.cpp
llama/llama.cpp: llama/vendor
	rsync -arvzc --delete -f "include LICENSE" -f "merge $@/.rsync-filter" $(addprefix $<,/LICENSE /) $@

.PHONY: ml/backend/ggml/ggml
ml/backend/ggml/ggml: llama/vendor
	rsync -arvzc --delete -f "include LICENSE" -f "merge $@/.rsync-filter" $(addprefix $<,/LICENSE /ggml/) $@

PATCHES=$(wildcard llama/patches/*.patch)
PATCHED=$(join $(dir $(PATCHES)), $(addsuffix ed, $(addprefix ., $(notdir $(PATCHES)))))

.PHONY: apply-patches
.NOTPARALLEL:
apply-patches: $(PATCHED)

llama/patches/.%.patched: llama/patches/%.patch
	@if git -c user.name=nobody -c 'user.email=<>' -C $(WORKDIR) am -3 $(realpath $<); then \
		touch $@;                                                                           \
	else                                                                                    \
		echo "Patch failed. Resolve any conflicts then continue.";                          \
		echo "1. Run 'git -C $(WORKDIR) am --continue'";                                    \
		echo "2. Run 'make -f $(lastword $(MAKEFILE_LIST)) format-patches'";                \
		echo "3. Run 'make -f $(lastword $(MAKEFILE_LIST)) clean apply-patches'";           \
		exit 1;                                                                             \
	fi

.PHONY: checkout
checkout: $(WORKDIR)
	git -C $(WORKDIR) fetch
	git -C $(WORKDIR) checkout -f $(FETCH_HEAD)

$(WORKDIR):
	git clone $(UPSTREAM) $(WORKDIR)

.PHONE: format-patches
format-patches: llama/patches
	git -C $(WORKDIR) format-patch \
		--no-signature \
		--no-numbered \
		--zero-commit \
		-o $(realpath $<) \
		$(FETCH_HEAD)

.PHONE: clean
clean: checkout
	@git -C $(WORKDIR) am --abort || true
	$(RM) llama/patches/.*.patched
