UPSTREAM=https://github.com/ggerganov/llama.cpp.git
WORKDIR=llama/vendor
FETCH_HEAD=de4c07f93783a1a96456a44dc16b9db538ee1618

.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 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 -f "merge $@/.rsync-filter" $< $@

.PHONY: ml/backend/ggml/ggml
ml/backend/ggml/ggml: llama/vendor/ggml/
	rsync -arvzc -f "merge $@/.rsync-filter" $< $@

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 git -C $(WORKDIR) am --abort; 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
	$(RM) llama/patches/.*.patched