CC ?= cc
CPPFLAGS ?=
CFLAGS ?=
LDFLAGS ?=
TMPDIR ?= /tmp
VROOT  ?= .
VC     ?= ./vc
VEXE   ?= ./v
V1_FALLBACK_EXE = $(dir $(VEXE))v1_fallback$(EXE_EXT)
# Portable VC snapshots do not embed the default compiler. Keep their v1 executable on the full
# compatibility compiler path even when the generated C is built on a V3 host.
VC_BOOTSTRAP_DEFINE := -DCUSTOM_DEFINE_v1_fallback
VCREPO ?= https://github.com/vlang/vc
TCCREPO ?= https://github.com/vlang/tccbin
LEGACYREPO ?= https://github.com/macports/macports-legacy-support
GIT ?= git
# Command-line variables are exported automatically.  Keep GIT as literal data
# until platform detection decides whether the Linux selector will consume it.
override V_GIT_LITERAL := $(value GIT)
unexport GIT

VCFILE := v.c
TMPTCC := $(VROOT)/thirdparty/tcc
LEGACYLIBS := $(VROOT)/thirdparty/legacy
TMPLEGACY := $(LEGACYLIBS)/source
TCCOS := unknown
TCCARCH := unknown
LINUX_TCC_SELECTOR := $(VROOT)/cmd/tools/select_linux_tcc.sh
GIT_ARGV_RUNNER := $(VROOT)/cmd/tools/git_argv.sh

#### Platform detections and overrides:
_SYS := $(shell uname 2>/dev/null || echo Unknown)
_SYS := $(patsubst MSYS%,MSYS,$(_SYS))
_SYS := $(patsubst MINGW%,MinGW,$(_SYS))

ifneq ($(filter $(_SYS),MSYS MinGW),)
WIN32 := 1
EXE_EXT := .exe
# vc/v.c is generated with `-cross` targeting the host OS that ran gen_vc_ci.yml
# (Linux), so it only guards *nix headers/APIs, not Windows. The dedicated
# `-os windows` snapshot lives in vc/v_win.c; that is the one Windows needs.
VCFILE := v_win.c
# GNU make defaults CC to `cc`, but mingw32-make installations often only
# provide `gcc`. Switch only the implicit default and preserve explicit CC=...
ifneq ($(filter $(origin CC),default file),)
ifeq ($(CC),cc)
CC := gcc
endif
endif
endif

ifeq ($(_SYS),Linux)
LINUX := 1
TCCOS := linux
ifneq ($(shell ldd --version 2>&1 | grep -i musl),)
TCCOS := linuxmusl
endif
endif

ifeq ($(_SYS),Darwin)
MAC := 1
TCCOS := macos
ifeq ($(shell expr $(shell uname -r | cut -d. -f1) \<= 16), 1)
LEGACY := 1
CPPFLAGS += -I$(LEGACYLIBS)/include/LegacySupport
LDFLAGS += -L$(LEGACYLIBS)/lib
LDFLAGS += -lMacportsLegacySupport
VFLAGS += -cc $(CC)
VFLAGS += -cflags "$(strip $(CPPFLAGS) $(CFLAGS))"
VFLAGS += -ldflags -L$(LEGACYLIBS)/lib
VFLAGS += -cflags $(LEGACYLIBS)/lib/libMacportsLegacySupport.a
endif
endif

ifeq ($(_SYS),FreeBSD)
TCCOS := freebsd
LDFLAGS += -lexecinfo
endif

ifeq ($(_SYS),NetBSD)
NETBSD := 1
TCCOS := netbsd
LDFLAGS += -lexecinfo
endif

ifeq ($(_SYS),OpenBSD)
OPENBSD := 1
TCCOS := openbsd
LDFLAGS += -lexecinfo
endif

ifdef ANDROID_ROOT
ANDROID := 1
undefine LINUX
TCCOS := android
ifneq ($(wildcard $(PREFIX)/lib/libexecinfo.*),)
LDFLAGS += -lexecinfo
endif
endif
#####

ifdef WIN32
TCCOS := windows
endif

TCCARCH := $(shell uname -m 2>/dev/null || echo unknown)
# A 32-bit userland can run on a 64-bit kernel (Raspberry Pi OS 32-bit on a Pi 4/5,
# an armhf or i386 container), where `uname -m` names the kernel's architecture.
# The C compiler, the TCC bundle and the bootstrap follow the userland, whose word
# size `getconf LONG_BIT` reports.
ifeq ($(shell getconf LONG_BIT 2>/dev/null),32)
ifneq ($(filter aarch64 arm64 armv8%,$(TCCARCH)),)
	TCCARCH := armv7l
endif
ifeq ($(TCCARCH),x86_64)
	TCCARCH := i686
endif
endif

ifeq ($(TCCARCH),x86_64)
	TCCARCH := amd64
else
ifneq ($(filter x86%,$(TCCARCH)),)
	TCCARCH := i386
else
ifeq ($(TCCARCH),arm64)
	TCCARCH := arm64
else
ifneq ($(filter arm%,$(TCCARCH)),)
	TCCARCH := arm
# otherwise, just use the arch name
endif
endif
endif
endif

ifeq ($(TCCOS),linux)
override GIT := $(V_GIT_LITERAL)
export GIT
# GNU Make before 4.4 does not export make variables to $(shell ...).
# Linux recipes validate and execute custom GIT argv at recipe execution time.
else
export GIT
HAS_GIT := $(shell command -v $(GIT) >/dev/null 2>&1 && echo 1 || echo 0)
endif
GITCLEANPULL := $(GIT) clean -xf && $(GIT) pull --rebase --quiet
GITFASTCLONE := $(GIT) clone --filter=blob:none --quiet

TCCBUILDSCRIPT = $(VROOT)/thirdparty/build_scripts/thirdparty-$(TCCOS)-$(TCCARCH)_tcc.sh

.PHONY: all v1 clean rebuild check fresh_vc fresh_tcc fresh_legacy latest_tcc_source check_for_working_tcc etags ctags

ifdef prod
VFLAGS+=-prod
endif

# Keep bootstrap C compiler/linker flags aligned with the initial `v1` build.
BOOTSTRAP_CC_CFLAGS := $(strip $(CFLAGS))
BOOTSTRAP_CFLAGS := $(strip $(CPPFLAGS) $(CFLAGS))
BOOTSTRAP_VC_CC_CFLAGS := $(BOOTSTRAP_CC_CFLAGS)
BOOTSTRAP_VC_CFLAGS := $(BOOTSTRAP_CFLAGS)
BOOTSTRAP_LDFLAGS := $(strip $(LDFLAGS))
ifeq ($(LINUX),1)
ifeq ($(TCCARCH),arm)
BOOTSTRAP_LDFLAGS := $(strip $(BOOTSTRAP_LDFLAGS) -latomic)
endif
ifneq ($(filter $(TCCARCH),arm64 aarch64),)
BOOTSTRAP_VC_UNSAFE_OPTFLAGS := $(filter-out -O -O0 -O1,$(filter -O%,$(BOOTSTRAP_CC_CFLAGS)))
ifneq ($(BOOTSTRAP_VC_UNSAFE_OPTFLAGS),)
	# Some Linux ARM64 system compilers miscompile the external vc bootstrap
	# snapshot at -O2/-O3, making `v1` segfault before it can build `v2`.
	# Keep the bootstrap stages at -O1, but preserve the requested flags for
	# the final `v` build.
	BOOTSTRAP_VC_SAFE_CFLAGS := $(strip $(filter-out -O%,$(BOOTSTRAP_CC_CFLAGS)) -O1)
	BOOTSTRAP_VC_CC_CFLAGS := $(BOOTSTRAP_VC_SAFE_CFLAGS)
	BOOTSTRAP_VC_CFLAGS := $(strip $(CPPFLAGS) $(BOOTSTRAP_VC_SAFE_CFLAGS))
endif
endif
endif
# A vc snapshot may use the lean compiler dispatcher when its generated C is built
# on a Unix-like host. Keep the temporary v1 on the full compatibility path so
# it can create v2 before either the compiler driver or v1_fallback exists.
BOOTSTRAP_VC_CC_CFLAGS += -DCUSTOM_DEFINE_v1_fallback
BOOTSTRAP_VC_EXTRA_SOURCES :=
# Portable vc snapshots generated before the OpenBSD entropy and semaphore guards
# still reference two libc symbols that OpenBSD does not provide. Supply the small
# bootstrap-only compatibility implementations until vc is regenerated.
ifdef OPENBSD
BOOTSTRAP_VC_CC_CFLAGS += -DSYS_getrandom=0
BOOTSTRAP_VC_EXTRA_SOURCES += $(VROOT)/cmd/tools/openbsd_vc_compat.c
endif
# Portable vc snapshots guard android_print with `defined(__ANDROID__) && !defined(__TERMUX__)`.
# Termux's compiler does not predefine __TERMUX__, so a native Termux bootstrap must define it;
# otherwise v1 references android_print, which only the android target links (#30279).
ifdef ANDROID
ifneq ($(or $(TERMUX_VERSION),$(findstring com.termux,$(PREFIX))),)
BOOTSTRAP_VC_CC_CFLAGS += -D__TERMUX__
endif
endif
BOOTSTRAP_TCC_REQUESTED := $(or $(findstring -cc tcc,$(strip $(VFLAGS))),$(findstring -cc=tcc,$(strip $(VFLAGS))))
BOOTSTRAP_CCOMPILER_VFLAG :=
BOOTSTRAP_VC_CCOMPILER_VFLAG :=
POST_BOOTSTRAP_CCOMPILER_VFLAG :=
BOOTSTRAP_GC_VFLAG :=
ifeq ($(filter -gc -gc=%,$(VFLAGS)),)
	BOOTSTRAP_GC_VFLAG := -gc none
endif
ifneq ($(filter $(_SYS),Linux FreeBSD NetBSD OpenBSD DragonFly),)
ifneq ($(filter $(TCCARCH),arm64 aarch64 arm),)
ifeq ($(filter -cc,$(VFLAGS)),)
ifeq ($(findstring -cc=,$(VFLAGS)),)
	# Bundled TCC can hang, fail, or miscompile V while bootstrapping on ARM64,
	# so keep both `v1 -> v2` and `v2 -> v` on the same system compiler
	# unless the user overrode it explicitly. On 32-bit ARM, TCC cannot link V
	# itself: the Thumb-2 C startup code of armhf distributions calls into libc
	# with a branch that cannot reach across V's text, and TCC adds no veneer.
	BOOTSTRAP_CCOMPILER_VFLAG := -cc "$(CC)"
	BOOTSTRAP_VC_CCOMPILER_VFLAG := $(BOOTSTRAP_CCOMPILER_VFLAG)
endif
endif
endif
endif
ifdef MAC
ifeq ($(filter -cc,$(VFLAGS)),)
ifeq ($(findstring -cc=,$(VFLAGS)),)
ifeq ($(shell expr $(shell uname -r | cut -d. -f1) \>= 27), 1)
	# Darwin 27's dyld fills the zero-fill pages of TCC-linked executables with file
	# bytes, corrupting their globals (see pref.host_rejects_tcc_executables), so keep
	# both `v1 -> v2` and `v2 -> v` on the system compiler.
	BOOTSTRAP_CCOMPILER_VFLAG := -cc "$(CC)"
	BOOTSTRAP_VC_CCOMPILER_VFLAG := $(BOOTSTRAP_CCOMPILER_VFLAG)
endif
endif
endif
endif
ifeq ($(LINUX),1)
ifneq ($(BOOTSTRAP_TCC_REQUESTED),)
ifneq ($(CC),tcc)
	# The external vc bootstrap snapshot may still emit Windows-only stdio
	# declarations for non-Windows TCC. Use the system compiler just for v1 -> v2.
	BOOTSTRAP_VC_CCOMPILER_VFLAG := -cc "$(CC)"
endif
endif
endif
ifdef ANDROID
ifneq ($(BOOTSTRAP_TCC_REQUESTED),)
ifneq ($(CC),tcc)
	# There is no Android TCC bundle yet. If `-cc tcc` was requested anyway,
	# keep both bootstrap stages on the system compiler.
	BOOTSTRAP_VC_CCOMPILER_VFLAG := -cc "$(CC)"
	BOOTSTRAP_CCOMPILER_VFLAG := -cc "$(CC)"
	POST_BOOTSTRAP_CCOMPILER_VFLAG := -cc "$(CC)"
endif
endif
endif
BOOTSTRAP_VC_VFLAGS := $(BOOTSTRAP_VC_CCOMPILER_VFLAG) $(if $(strip $(BOOTSTRAP_VC_CFLAGS)),-cflags "$(BOOTSTRAP_VC_CFLAGS)") $(if $(strip $(BOOTSTRAP_LDFLAGS)),-ldflags "$(BOOTSTRAP_LDFLAGS)")
BOOTSTRAP_VFLAGS := $(BOOTSTRAP_CCOMPILER_VFLAG) $(if $(strip $(BOOTSTRAP_CFLAGS)),-cflags "$(BOOTSTRAP_CFLAGS)") $(if $(strip $(BOOTSTRAP_LDFLAGS)),-ldflags "$(BOOTSTRAP_LDFLAGS)")

all: latest_vc latest_tcc latest_legacy
ifdef WIN32
	powershell -NoProfile -ExecutionPolicy Bypass -File "$(VROOT)/cmd/tools/vc_compat_uint.ps1" -Source "$(VC)/$(VCFILE)" -Destination "$(VC)/v_win_compat.c"
	$(CC) $(CPPFLAGS) $(BOOTSTRAP_VC_CC_CFLAGS) $(VC_BOOTSTRAP_DEFINE) -std=c99 -municode -w -o v1$(EXE_EXT) "$(VC)/v_win_compat.c" $(LDFLAGS) -lws2_32 -lbcrypt || cmd/tools/cc_compilation_failed_windows.sh
	$(RM) "$(VC)/v_win_compat.c"
	./v1$(EXE_EXT) -no-parallel -o v2$(EXE_EXT) $(BOOTSTRAP_GC_VFLAG) $(VFLAGS) $(BOOTSTRAP_VC_VFLAGS) cmd/v
	./v2$(EXE_EXT) -o $(VEXE)$(EXE_EXT) $(BOOTSTRAP_GC_VFLAG) $(VFLAGS) $(BOOTSTRAP_VFLAGS) cmd/v
	$(RM) v1$(EXE_EXT)
	$(RM) v2$(EXE_EXT)
else
ifdef LEGACY
	'$(MAKE)' -C $(TMPLEGACY) CPPFLAGS='$(CPPFLAGS)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)'
	'$(MAKE)' -C $(TMPLEGACY) PREFIX=$(realpath $(LEGACYLIBS)) CPPFLAGS='$(CPPFLAGS)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' install
	rm -rf $(TMPLEGACY)
	$(eval override LDFLAGS+=-L$(realpath $(LEGACYLIBS))/lib -lMacportsLegacySupport)
endif
# Stream compatibility fixes for stale snapshots to the compiler, keeping one v.c.
	sh "$(VROOT)/cmd/tools/vc_compat.sh" "$(VC)/$(VCFILE)" $(CC) $(CPPFLAGS) $(BOOTSTRAP_VC_CC_CFLAGS) $(VC_BOOTSTRAP_DEFINE) -std=c99 -w -o v1$(EXE_EXT) -- $(BOOTSTRAP_VC_EXTRA_SOURCES) -lm -lpthread $(BOOTSTRAP_LDFLAGS) || sh cmd/tools/cc_compilation_failed_non_windows.sh
ifdef NETBSD
	paxctl +m v1$(EXE_EXT)
endif
	./v1$(EXE_EXT) -no-parallel -o v2$(EXE_EXT) $(BOOTSTRAP_GC_VFLAG) $(VFLAGS) $(BOOTSTRAP_VC_VFLAGS) cmd/v
ifdef NETBSD
	paxctl +m v2$(EXE_EXT)
endif
	./v2$(EXE_EXT) -nocache -o $(VEXE)$(EXE_EXT) $(BOOTSTRAP_GC_VFLAG) $(VFLAGS) $(BOOTSTRAP_VFLAGS) cmd/v
ifdef NETBSD
	paxctl +m $(VEXE)$(EXE_EXT)
endif
	rm -rf v1$(EXE_EXT) v2$(EXE_EXT)
endif
	@$(VEXE)$(EXE_EXT) $(POST_BOOTSTRAP_CCOMPILER_VFLAG) -new-compiler -gc none run cmd/tools/detect_tcc.v
	@echo "V has been successfully built"
	@$(VEXE)$(EXE_EXT) -version
	@$(VEXE)$(EXE_EXT) $(POST_BOOTSTRAP_CCOMPILER_VFLAG) -new-compiler -gc none run .github/problem-matchers/register_all.vsh

v1:
ifdef LEGACY
	@set -e; \
	if [ ! -f "$(LEGACYLIBS)/lib/libMacportsLegacySupport.a" ]; then \
		'$(MAKE)' latest_legacy; \
		'$(MAKE)' -C "$(TMPLEGACY)" CPPFLAGS='$(CPPFLAGS)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)'; \
		'$(MAKE)' -C "$(TMPLEGACY)" PREFIX="$(abspath $(LEGACYLIBS))" CPPFLAGS='$(CPPFLAGS)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' install; \
		rm -rf "$(TMPLEGACY)"; \
	fi
endif
	@set -e; \
	CC='$(CC)' OLDV_CCOPTIONS='$(CPPFLAGS) $(BOOTSTRAP_VC_CC_CFLAGS)' \
		OLDV_LDFLAGS='$(BOOTSTRAP_LDFLAGS)' \
		cmd/tools/install_v1_fallback.sh '$(VEXE)$(EXE_EXT)' '$(V1_FALLBACK_EXE)'
ifdef NETBSD
	paxctl +m "$${V1_FALLBACK_OUTPUT:-$(V1_FALLBACK_EXE)}"
endif
	@echo "Built V1 compatibility compiler: $(V1_FALLBACK_EXE)"

clean:
	rm -rf $(TMPTCC)
	rm -rf $(LEGACYLIBS)
	rm -rf $(VC)

rebuild: clean all

ifndef local
latest_vc: $(VC)/.git/config
ifeq ($(TCCOS),linux)
	@if bash '$(GIT_ARGV_RUNNER)' check > /dev/null 2>&1; then \
		bash '$(GIT_ARGV_RUNNER)' run -C '$(VC)' clean -xf \
			&& bash '$(GIT_ARGV_RUNNER)' run -C '$(VC)' pull --rebase --quiet; \
	else \
		echo "git not found; using existing $(VC)/$(VCFILE)"; \
	fi
else
ifeq ($(HAS_GIT),1)
	cd $(VC) && $(GITCLEANPULL)
else
	@echo "git not found; using existing $(VC)/$(VCFILE)"
endif
endif
else
latest_vc:
	@echo "Using local vc"
endif

check_for_working_tcc:
	@$(TMPTCC)/tcc.exe --version > /dev/null 2> /dev/null || echo "The executable '$(TMPTCC)/tcc.exe' does not work."

fresh_vc:
ifeq ($(TCCOS),linux)
	@bash '$(GIT_ARGV_RUNNER)' check
	rm -rf $(VC)
	@bash '$(GIT_ARGV_RUNNER)' run clone --filter=blob:none --quiet '$(VCREPO)' '$(VC)'
else
	rm -rf $(VC)
ifeq ($(HAS_GIT),1)
	$(GITFASTCLONE) $(VCREPO) $(VC)
else
	@echo "git is required to clone $(VCREPO) into $(VC)"
	@exit 1
endif
endif

ifndef local
ifeq ($(TCCOS),linux)
latest_tcc:
else
latest_tcc: $(TMPTCC)/.git/config
endif
ifeq ($(TCCOS),linux)
	@TMPDIR='$(TMPDIR)' VFLAGS='$(VFLAGS)' \
		bash '$(LINUX_TCC_SELECTOR)' latest '$(TMPTCC)' '$(TCCREPO)' '$(TCCARCH)' '$(VROOT)'
else
ifeq ($(HAS_GIT),1)
ifdef WIN32
	@if [ -f "$(TMPTCC)/lib/advapi32.def" ]; then \
		cd "$(TMPTCC)" && $(GIT) checkout -- lib/advapi32.def > /dev/null 2> /dev/null || true; \
	fi
endif
	cd $(TMPTCC) && $(GITCLEANPULL)
ifdef WIN32
	@if [ -f "$(TMPTCC)/lib/advapi32.def" ]; then \
		for sym in RegEnumKeyExW RegEnumValueW RegQueryInfoKeyW; do \
			grep -qx "$$sym" "$(TMPTCC)/lib/advapi32.def" || printf '%s\n' "$$sym" >> "$(TMPTCC)/lib/advapi32.def"; \
		done; \
	fi
endif
else
	@echo "git not found; skipping update of $(TMPTCC)"
endif
endif
ifneq (,$(wildcard ./tcc.exe))
	@'$(MAKE)' --quiet check_for_working_tcc 2> /dev/null
endif

else
latest_tcc:
	@echo "Using local tcc"
	@'$(MAKE)' --quiet check_for_working_tcc 2> /dev/null
endif

# Rebuild the bundled TCC in-place from upstream tinycc, while preserving the
# V-specific libgc/openlibm files already stored in $(TMPTCC).
latest_tcc_source: $(TMPTCC)/.git/config
ifeq ($(TCCOS),linux)
	@bash '$(GIT_ARGV_RUNNER)' check
else
ifneq ($(HAS_GIT),1)
	@echo "git is required to bootstrap $(TMPTCC) before rebuilding it from source"
	@exit 1
endif
endif
ifneq (,$(wildcard $(TCCBUILDSCRIPT)))
ifeq ($(TCCOS),linux)
	@GIT_ARGV_RUNNER='$(GIT_ARGV_RUNNER)' TCC_FOLDER='$(TMPTCC)' $(if $(strip $(TCC_COMMIT)),TCC_COMMIT='$(TCC_COMMIT)') CC='$(CC)' bash '$(TCCBUILDSCRIPT)'
else
	@TCC_FOLDER='$(TMPTCC)' $(if $(strip $(TCC_COMMIT)),TCC_COMMIT='$(TCC_COMMIT)') CC='$(CC)' bash '$(TCCBUILDSCRIPT)'
endif
	@'$(MAKE)' --quiet check_for_working_tcc 2> /dev/null
else
	@echo 'No upstream TinyCC build script is available for thirdparty-$(TCCOS)-$(TCCARCH).'
	@echo 'Use `make latest_tcc` to refresh the prebuilt bundle from $(TCCREPO).'
	@exit 1
endif

fresh_tcc:
	rm -rf $(TMPTCC)
ifndef local
ifeq ($(TCCOS),linux)
	@TMPDIR='$(TMPDIR)' VFLAGS='$(VFLAGS)' \
		bash '$(LINUX_TCC_SELECTOR)' fresh '$(TMPTCC)' '$(TCCREPO)' '$(TCCARCH)' '$(VROOT)'
else
ifeq ($(HAS_GIT),1)
	@set -e; \
	branches="$$( $(GIT) ls-remote --heads $(TCCREPO) 2> /dev/null | awk '{sub("refs/heads/","",$$2); print $$2}' || true )"; \
	preferred_branch='thirdparty-$(TCCOS)-$(TCCARCH)'; \
	fallback_branch=''; \
	if [ "$(LINUX)" = "1" ]; then \
		fallback_branch='thirdparty-linuxmusl-$(TCCARCH)'; \
	fi; \
	selected_branch=''; \
	if printf '%s\n' "$$branches" | grep -Fx "$$preferred_branch" > /dev/null; then \
		selected_branch="$$preferred_branch"; \
	elif [ "$$fallback_branch" != '' ] && [ "$$fallback_branch" != "$$preferred_branch" ] \
		&& printf '%s\n' "$$branches" | grep -Fx "$$fallback_branch" > /dev/null; then \
		selected_branch="$$fallback_branch"; \
	fi; \
	if [ "$$selected_branch" = '' ]; then \
		echo "Pre-built TCC not available for $$preferred_branch at $(TCCREPO), will use the system compiler: $(CC)"; \
		$(GITFASTCLONE) --branch thirdparty-unknown-unknown $(TCCREPO) "$(TMPTCC)"; \
	else \
		$(GITFASTCLONE) --branch "$$selected_branch" $(TCCREPO) "$(TMPTCC)"; \
		if [ -f "$(TMPTCC)/lib/advapi32.def" ]; then \
			for sym in RegEnumKeyExW RegEnumValueW RegQueryInfoKeyW; do \
				grep -qx "$$sym" "$(TMPTCC)/lib/advapi32.def" || printf '%s\n' "$$sym" >> "$(TMPTCC)/lib/advapi32.def"; \
			done; \
		fi; \
		if ! "$(TMPTCC)/tcc.exe" --version > /dev/null 2> /dev/null; then \
			echo "Pre-built TCC bundle $$selected_branch did not run; V will use the system compiler: $(CC)"; \
			'$(MAKE)' --quiet check_for_working_tcc 2> /dev/null; \
		else \
			'$(MAKE)' --quiet check_for_working_tcc 2> /dev/null; \
		fi; \
	fi
else
	@echo "git is required to clone $(TCCREPO)"
	@exit 1
endif
endif
else
	@echo "Using local tccbin"
	@'$(MAKE)' --quiet check_for_working_tcc 2> /dev/null
endif

ifndef local
latest_legacy: $(TMPLEGACY)/.git/config
ifdef LEGACY
ifeq ($(TCCOS),linux)
	@if bash '$(GIT_ARGV_RUNNER)' check > /dev/null 2>&1; then \
		bash '$(GIT_ARGV_RUNNER)' run -C '$(TMPLEGACY)' clean -xf \
			&& bash '$(GIT_ARGV_RUNNER)' run -C '$(TMPLEGACY)' pull --rebase --quiet; \
	else \
		echo "git not found; using existing $(TMPLEGACY)"; \
	fi
else
ifeq ($(HAS_GIT),1)
	cd $(TMPLEGACY) && $(GITCLEANPULL)
else
	@echo "git not found; using existing $(TMPLEGACY)"
endif
endif
endif
else
latest_legacy:
ifdef LEGACY
	@echo "Using local legacysupport"
endif
endif

fresh_legacy:
ifeq ($(TCCOS),linux)
	@bash '$(GIT_ARGV_RUNNER)' check
	rm -rf $(LEGACYLIBS)
	@bash '$(GIT_ARGV_RUNNER)' run clone --filter=blob:none --quiet '$(LEGACYREPO)' '$(TMPLEGACY)'
else
	rm -rf $(LEGACYLIBS)
ifeq ($(HAS_GIT),1)
	$(GITFASTCLONE) $(LEGACYREPO) $(TMPLEGACY)
else
	@echo "git is required to download legacy support sources ($(LEGACYREPO))"
	@exit 1
endif
endif

$(TMPTCC)/.git/config:
ifeq ($(TCCOS),linux)
	@bash '$(GIT_ARGV_RUNNER)' check
	'$(MAKE)' fresh_tcc
else
ifeq ($(HAS_GIT),1)
	'$(MAKE)' fresh_tcc
else
	@echo "git not found; skipping bootstrap of $(TMPTCC), system compiler $(CC) will be used"
endif
endif

$(VC)/.git/config:
ifeq ($(TCCOS),linux)
	@if bash '$(GIT_ARGV_RUNNER)' check > /dev/null 2>&1; then \
		'$(MAKE)' fresh_vc; \
	elif [ -f "$(VC)/$(VCFILE)" ]; then \
		echo "git not found; using existing $(VC)/$(VCFILE)"; \
	else \
		echo "git is required to download $(VC)/$(VCFILE). Install git or provide the file manually."; \
		exit 1; \
	fi
else
ifeq ($(HAS_GIT),1)
	'$(MAKE)' fresh_vc
else
	@if [ -f "$(VC)/$(VCFILE)" ]; then \
		echo "git not found; using existing $(VC)/$(VCFILE)"; \
	else \
		echo "git is required to download $(VC)/$(VCFILE). Install git or provide the file manually."; \
		exit 1; \
	fi
endif
endif

$(TMPLEGACY)/.git/config:
ifdef LEGACY
ifeq ($(TCCOS),linux)
	@if bash '$(GIT_ARGV_RUNNER)' check > /dev/null 2>&1; then \
		'$(MAKE)' fresh_legacy; \
	elif [ -d "$(TMPLEGACY)" ]; then \
		echo "git not found; using existing $(TMPLEGACY)"; \
	else \
		echo "git is required to download legacy support sources ($(LEGACYREPO))"; \
		exit 1; \
	fi
else
ifeq ($(HAS_GIT),1)
	'$(MAKE)' fresh_legacy
else
	@if [ -d "$(TMPLEGACY)" ]; then \
		echo "git not found; using existing $(TMPLEGACY)"; \
	else \
		echo "git is required to download legacy support sources ($(LEGACYREPO))"; \
		exit 1; \
	fi
endif
endif
endif

asan:
	'$(MAKE)' all CFLAGS='-fsanitize=address,undefined'

selfcompile:
	$(VEXE)$(EXE_EXT) -cg -o v cmd/v

selfcompile-static:
	$(VEXE)$(EXE_EXT) -cg -cflags '--static' -o v-static cmd/v

### NB: Please keep this Makefile and makev.bat simple.
install:
	@echo 'Please use `sudo ./v symlink` instead, or manually add the current directory to your PATH.'

check:
	$(VEXE)$(EXE_EXT) test-all

etags:
	./v$(EXE_EXT) -print-v-files cmd/v | grep -v :parse_text| etags -L -

ctags:
	./v$(EXE_EXT) -print-v-files cmd/v | grep -v :parse_text| ctags -L -
