* 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
598 lines
19 KiB
Makefile
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 -
|