Files
v/GNUmakefile
Alexander Medvednikov 75365168ad cache: reuse bootstrap builtin objects in test builds (#31219)
* cache: retain builtin objects across test compilations

* checker: recognize builtin lifecycle attributes

* cache: stabilize ignored local names across source reparsing

* transform: preserve generic struct map return types

* cache: preserve error dispatch IDs and portable make warmups
2026-10-27 11:46:33 +03:00

598 lines
19 KiB
Makefile

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
@set -e; \
cache_gcflags=; \
if [ ! -f "$(TMPTCC)/lib/libgc.a" ] && [ ! -f "$(TMPTCC)/lib/libgc.dylib" ]; then \
cache_gcflags='-gc none'; \
fi; \
$(VEXE)$(EXE_EXT) $$cache_gcflags $(VFLAGS) $(POST_BOOTSTRAP_CCOMPILER_VFLAG) -new-compiler cmd/tools/cache_basic_modules_test.v
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 -