From 3881d541d0934bd35f26ef7b74672e755061efef Mon Sep 17 00:00:00 2001
From: Matt Jolly <kangie@gentoo.org>
Date: Mon, 9 Dec 2024 13:05:44 +1000
Subject: [PATCH] Add `RUSTC_SRC_PROVIDED` for sandboxed installs

Allows package managers to provide an extracted rustc
source to patch and build against. This effictively no-ops
the fetch and unpack steps of minicargo.mk entirely, and
adds some sanity checks to ensure that `RUSTCSRC` comes
from the environment and contains a `Cargo.toml`.

we also add a `/` after every `$(RUSTCSRC)` path fragment
just in case the path from the environment does not have one.

Signed-off-by: Matt Jolly <kangie@gentoo.org>
--- a/minicargo.mk
+++ b/minicargo.mk
@@ -16,6 +16,9 @@ endif
 RUSTC_VERSION_DEF := $(shell cat rust-version)
 RUSTC_VERSION ?= $(RUSTC_VERSION_DEF)
 
+# Distros may want to sandbox the build and provide the source themselves
+RUSTC_SRC_PROVIDED := 0
+
 # OUTDIR_SUF : Output directory suffix
 ifeq ($(RUSTC_VERSION),$(RUSTC_VERSION_DEF))
   OUTDIR_SUF_DEF :=
@@ -91,18 +94,26 @@ else
   RUSTC_OUT_BIN := rustc_main
 endif
 
-ifeq ($(RUSTC_CHANNEL),nightly)
-  RUSTCSRC := rustc-nightly-src/
+ifeq ($(RUSTC_SRC_PROVIDED),0)
+  ifeq ($(RUSTC_CHANNEL),nightly)
+    RUSTCSRC := rustc-nightly-src
+  else
+    RUSTCSRC := rustc-$(RUSTC_VERSION)-src
+  endif
 else
-  RUSTCSRC := rustc-$(RUSTC_VERSION)-src/
+  # Strip trailing slash from rustcsrc if present
+  RUSTCSRC := $(RUSTCSRC:/=)
+  ifeq ($(wildcard $(RUSTCSRC)/Cargo.toml),)
+    $(error "RUSTCSRC is not set to a valid directory: $(RUSTCSRC)/")
+  endif
 endif
 RUSTC_SRC_DL := $(RUSTCSRC)/dl-version
 ifeq ($(RUSTC_VERSION),1.19.0)
-  VENDOR_DIR := $(RUSTCSRC)src/vendor
+  VENDOR_DIR := $(RUSTCSRC)/src/vendor
 else ifeq ($(RUSTC_VERSION),1.29.0)
-  VENDOR_DIR := $(RUSTCSRC)src/vendor
+  VENDOR_DIR := $(RUSTCSRC)/src/vendor
 else
-  VENDOR_DIR := $(RUSTCSRC)vendor
+  VENDOR_DIR := $(RUSTCSRC)/vendor
   MINICARGO_FLAGS += --manifest-overrides rustc-$(RUSTC_VERSION)-overrides.toml
 endif
 ifeq ($(RUSTC_VERSION),1.54.0)
@@ -132,12 +143,12 @@ ifeq ($(RUSTC_VERSION),1.74.0)
   SRCDIR_RUSTC_DRIVER := compiler/rustc_driver
 endif
 
-SRCDIR_RUST_TESTS := $(RUSTCSRC)src/test/
+SRCDIR_RUST_TESTS := $(RUSTCSRC)/src/test/
 ifeq ($(RUSTC_VERSION),1.74.0)
-SRCDIR_RUST_TESTS := $(RUSTCSRC)tests/
+SRCDIR_RUST_TESTS := $(RUSTCSRC)/tests/
 endif
 
-LLVM_CONFIG := $(RUSTCSRC)build/bin/llvm-config
+LLVM_CONFIG := $(RUSTCSRC)/build/bin/llvm-config
 ifeq ($(shell uname -s || echo not),Darwin)
  # /usr/bin/uname because uname might call coreutils
  # which can make the arm64 uname called when
@@ -205,6 +216,7 @@ bin/testrunner$(EXESUF):
 # rustc (with std/cargo) source download
 #
 RUSTC_SRC_TARBALL := rustc-$(RUSTC_VERSION)-src.tar.gz
+ifeq ($(RUSTC_SRC_PROVIDED),0)
 $(RUSTC_SRC_TARBALL):
 	@echo [CURL] $@
 	@rm -f $@
@@ -212,15 +224,23 @@ $(RUSTC_SRC_TARBALL):
 rustc-$(RUSTC_VERSION)-src/extracted: $(RUSTC_SRC_TARBALL)
 	tar -xf $(RUSTC_SRC_TARBALL)
 	touch $@
-$(RUSTC_SRC_DL): rustc-$(RUSTC_VERSION)-src/extracted rustc-$(RUSTC_VERSION)-src.patch
-	cd $(RUSTCSRC) && patch -p0 < ../rustc-$(RUSTC_VERSION)-src.patch;
+else
+$(RUSTC_SRC_TARBALL):
+	@echo "RUSTC_SRC_PROVIDED is set, no need to fetch source"
+rustc-$(RUSTC_VERSION)-src/extracted: $(RUSTC_SRC_TARBALL)
+	touch $(RUSTCSRC)/extracted
+endif
+
+$(RUSTC_SRC_DL): $(RUSTC_SRC_TARBALL) rustc-$(RUSTC_VERSION)-src/extracted rustc-$(RUSTC_VERSION)-src.patch
+	PATCH_FILE=$(abspath rustc-$(RUSTC_VERSION)-src.patch); \
+	cd $(RUSTCSRC) && patch -p0 < $$PATCH_FILE;
 	touch $@
 
 # Standard library crates
 # - libstd, libpanic_unwind, libtest and libgetopts
 # - libproc_macro (mrustc)
 ifeq ($(USE_MERGED_BUILD),1)
-$(RUSTCSRC)mrustc-stdlib/Cargo.toml: $(RUSTC_SRC_DL) minicargo.mk
+$(RUSTCSRC)/mrustc-stdlib/Cargo.toml: $(RUSTC_SRC_DL) minicargo.mk
 	@mkdir -p $(dir $@)
 	@echo "#![no_core]" > $(dir $@)/lib.rs
 	@echo "[package]" > $@
@@ -232,23 +252,23 @@ $(RUSTCSRC)mrustc-stdlib/Cargo.toml: $(RUSTC_SRC_DL) minicargo.mk
 	@echo "std = { path = \"../$(RUST_LIB_PREFIX)std\" }" >> $@
 	@echo "panic_unwind = { path = \"../$(RUST_LIB_PREFIX)panic_unwind\" }" >> $@
 	@echo "test = { path = \"../$(RUST_LIB_PREFIX)test\" }" >> $@
-LIBS: $(RUSTCSRC)mrustc-stdlib/Cargo.toml $(MRUSTC) $(MINICARGO)
-	+$(MINICARGO) --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) $(RUSTCSRC)mrustc-stdlib/
+LIBS: $(RUSTCSRC)/mrustc-stdlib/Cargo.toml $(MRUSTC) $(MINICARGO)
+	+$(MINICARGO) --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) $(RUSTCSRC)/mrustc-stdlib/
 	+$(MINICARGO) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) lib/libproc_macro
 else
 LIBS: $(MRUSTC) $(MINICARGO) $(RUSTC_SRC_DL)
-	+$(MINICARGO) --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) $(RUSTCSRC)$(RUST_LIB_PREFIX)std
-	+$(MINICARGO) --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) $(RUSTCSRC)$(RUST_LIB_PREFIX)panic_unwind
-	+$(MINICARGO) --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) $(RUSTCSRC)$(RUST_LIB_PREFIX)test
+	+$(MINICARGO) --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) $(RUSTCSRC)/$(RUST_LIB_PREFIX)std
+	+$(MINICARGO) --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) $(RUSTCSRC)/$(RUST_LIB_PREFIX)panic_unwind
+	+$(MINICARGO) --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) $(RUSTCSRC)/$(RUST_LIB_PREFIX)test
 	+$(MINICARGO) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) lib/libproc_macro
 endif
 
 # Dynamically linked version of the standard library
 $(OUTDIR)test/libtest.so: $(RUSTC_SRC_DL)
 	mkdir -p $(dir $@)
-	+MINICARGO_DYLIB=1 $(MINICARGO) $(RUSTCSRC)$(RUST_LIB_PREFIX)std          --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(dir $@) $(MINICARGO_FLAGS)
-	+MINICARGO_DYLIB=1 $(MINICARGO) $(RUSTCSRC)$(RUST_LIB_PREFIX)panic_unwind --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(dir $@) $(MINICARGO_FLAGS)
-	+MINICARGO_DYLIB=1 $(MINICARGO) $(RUSTCSRC)$(RUST_LIB_PREFIX)test         --vendor-dir $(VENDOR_DIR) --output-dir $(dir $@) $(MINICARGO_FLAGS)
+	+MINICARGO_DYLIB=1 $(MINICARGO) $(RUSTCSRC)/$(RUST_LIB_PREFIX)std          --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(dir $@) $(MINICARGO_FLAGS)
+	+MINICARGO_DYLIB=1 $(MINICARGO) $(RUSTCSRC)/$(RUST_LIB_PREFIX)panic_unwind --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(dir $@) $(MINICARGO_FLAGS)
+	+MINICARGO_DYLIB=1 $(MINICARGO) $(RUSTCSRC)/$(RUST_LIB_PREFIX)test         --vendor-dir $(VENDOR_DIR) --output-dir $(dir $@) $(MINICARGO_FLAGS)
 	test -e $@
 
 RUSTC_ENV_VARS := CFG_COMPILER_HOST_TRIPLE=$(RUSTC_TARGET)
@@ -264,17 +284,17 @@ RUSTC_ENV_VARS += RUSTC_INSTALL_BINDIR=bin
 
 $(OUTDIR)rustc: $(MRUSTC) $(MINICARGO) LIBS $(LLVM_CONFIG)
 	mkdir -p $(OUTDIR)rustc-build
-	+$(RUSTC_ENV_VARS) $(MINICARGO) $(RUSTCSRC)$(SRCDIR_RUSTC) --vendor-dir $(VENDOR_DIR) --output-dir $(OUTDIR)rustc-build -L $(OUTDIR) $(MINICARGO_FLAGS) $(MINICARGO_FLAGS_$@)
+	+$(RUSTC_ENV_VARS) $(MINICARGO) $(RUSTCSRC)/$(SRCDIR_RUSTC) --vendor-dir $(VENDOR_DIR) --output-dir $(OUTDIR)rustc-build -L $(OUTDIR) $(MINICARGO_FLAGS) $(MINICARGO_FLAGS_$@)
 	test -e $@ -a ! $(OUTDIR)rustc-build/$(RUSTC_OUT_BIN) -nt $@ || cp $(OUTDIR)rustc-build/$(RUSTC_OUT_BIN) $@
 $(OUTDIR)rustc-build/librustc_driver.rlib: $(MRUSTC) $(MINICARGO) LIBS
 	mkdir -p $(OUTDIR)rustc-build
-	+$(RUSTC_ENV_VARS) $(MINICARGO) $(RUSTCSRC)$(SRCDIR_RUSTC_DRIVER) --vendor-dir $(VENDOR_DIR) --output-dir $(OUTDIR)rustc-build -L $(OUTDIR) $(MINICARGO_FLAGS) $(MINICARGO_FLAGS_$(OUTDIR)rustc)
+	+$(RUSTC_ENV_VARS) $(MINICARGO) $(RUSTCSRC)/$(SRCDIR_RUSTC_DRIVER) --vendor-dir $(VENDOR_DIR) --output-dir $(OUTDIR)rustc-build -L $(OUTDIR) $(MINICARGO_FLAGS) $(MINICARGO_FLAGS_$(OUTDIR)rustc)
 $(OUTDIR)cargo: $(MRUSTC) LIBS
 	mkdir -p $(OUTDIR)cargo-build
-	+$(CARGO_ENV_VARS) $(MINICARGO) $(RUSTCSRC)src/tools/cargo --vendor-dir $(VENDOR_DIR) --output-dir $(OUTDIR)cargo-build -L $(OUTDIR) $(MINICARGO_FLAGS) $(MINICARGO_FLAGS_$@)
+	+$(CARGO_ENV_VARS) $(MINICARGO) $(RUSTCSRC)/src/tools/cargo --vendor-dir $(VENDOR_DIR) --output-dir $(OUTDIR)cargo-build -L $(OUTDIR) $(MINICARGO_FLAGS) $(MINICARGO_FLAGS_$@)
 	test -e $@ -a ! $(OUTDIR)cargo-build/cargo -nt $@ || cp $(OUTDIR)cargo-build/cargo $@
 
-# Reference $(RUSTCSRC)src/bootstrap/native.rs for these values
+# Reference $(RUSTCSRC)/src/bootstrap/native.rs for these values
 LLVM_CMAKE_OPTS := LLVM_TARGET_ARCH=$(firstword $(subst -, ,$(RUSTC_TARGET))) LLVM_DEFAULT_TARGET_TRIPLE=$(RUSTC_TARGET)
 LLVM_CMAKE_OPTS += LLVM_TARGETS_TO_BUILD="$(LLVM_TARGETS)"
 LLVM_CMAKE_OPTS += LLVM_ENABLE_ASSERTIONS=OFF
@@ -286,22 +306,22 @@ LLVM_CMAKE_OPTS += CMAKE_BUILD_TYPE=Release
 LLVM_CMAKE_OPTS += $(LLVM_CMAKE_OPTS_EXTRA)
 
 
-$(RUSTCSRC)build/bin/llvm-config: $(RUSTCSRC)build/Makefile
-	$Vcd $(RUSTCSRC)build && $(MAKE) -j $(PARLEVEL)
+$(RUSTCSRC)/build/bin/llvm-config: $(RUSTCSRC)/build/Makefile
+	$Vcd $(RUSTCSRC)/build && $(MAKE) -j $(PARLEVEL)
 
-$(RUSTCSRC)build/Makefile: $(RUSTCSRC)$(LLVM_DIR)/CMakeLists.txt
-	@mkdir -p $(RUSTCSRC)build
-	$Vcd $(RUSTCSRC)build && cmake $(addprefix -D , $(LLVM_CMAKE_OPTS)) ../$(LLVM_DIR)
+$(RUSTCSRC)/build/Makefile: $(RUSTCSRC)/$(LLVM_DIR)/CMakeLists.txt
+	@mkdir -p $(RUSTCSRC)/build
+	$Vcd $(RUSTCSRC)/build && cmake $(addprefix -D , $(LLVM_CMAKE_OPTS)) ../$(LLVM_DIR)
 
 #
 # Developement-only targets
 #
 $(OUTDIR)libcore.rlib: $(MRUSTC) $(MINICARGO)
-	$(MINICARGO) $(RUSTCSRC)src/libcore --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS)
+	$(MINICARGO) $(RUSTCSRC)/src/libcore --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS)
 $(OUTDIR)liballoc.rlib: $(MRUSTC) $(MINICARGO)
-	$(MINICARGO) $(RUSTCSRC)src/liballoc --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS)
+	$(MINICARGO) $(RUSTCSRC)/src/liballoc --vendor-dir $(VENDOR_DIR) --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS)
 $(OUTDIR)rustc-build/librustdoc.rlib: $(MRUSTC) LIBS
-	$(MINICARGO) $(RUSTCSRC)src/librustdoc --vendor-dir $(VENDOR_DIR) --output-dir $(dir $@) -L $(OUTDIR) $(MINICARGO_FLAGS)
+	$(MINICARGO) $(RUSTCSRC)/src/librustdoc --vendor-dir $(VENDOR_DIR) --output-dir $(dir $@) -L $(OUTDIR) $(MINICARGO_FLAGS)
 #$(OUTDIR)cargo-build/libserde-1_0_6.rlib: $(MRUSTC) LIBS
 #	$(MINICARGO) $(VENDOR_DIR)/serde --vendor-dir $(VENDOR_DIR) --output-dir $(dir $@) -L $(OUTDIR) $(MINICARGO_FLAGS)
 $(OUTDIR)cargo-build/libgit2-0_6_6.rlib: $(MRUSTC) LIBS
@@ -349,9 +369,9 @@ $(OUTDIR)test/librust_test_helpers.a: $(OUTDIR)test/rust_test_helpers.o
 	@mkdir -p $(dir $@)
 	ar cur $@ $<
 ifeq ($(RUSTC_VERSION),1.19.0)
-RUST_TEST_HELPERS_C := $(RUSTCSRC)src/rt/rust_test_helpers.c
+RUST_TEST_HELPERS_C := $(RUSTCSRC)/src/rt/rust_test_helpers.c
 else
-RUST_TEST_HELPERS_C := $(RUSTCSRC)src/test/auxiliary/rust_test_helpers.c
+RUST_TEST_HELPERS_C := $(RUSTCSRC)/src/test/auxiliary/rust_test_helpers.c
 endif
 output$(OUTDIR_SUF)/test/rust_test_helpers.o: $(RUST_TEST_HELPERS_C)
 	@mkdir -p $(dir $@)
@@ -424,8 +444,8 @@ RUNTIME_ARGS_$(OUTDIR)stdtest/collectionstests += --skip ::vec::overaligned_allo
 #ENV_$(OUTDIR)stdtest/rustc-test := 
 #ENV_$(OUTDIR)stdtest/rustc-test += CFG_COMPILER_HOST_TRIPLE=$(RUSTC_TARGET)
 
-$(OUTDIR)stdtest/%-test: $(RUSTCSRC)src/lib%/lib.rs LIBS
-	+MRUSTC_LIBDIR=$(abspath $(OUTDIR)) $(MINICARGO) --test $(RUSTCSRC)src/lib$* --vendor-dir $(VENDOR_DIR) --output-dir $(dir $@) -L $(OUTDIR)
+$(OUTDIR)stdtest/%-test: $(RUSTCSRC)/src/lib%/lib.rs LIBS
+	+MRUSTC_LIBDIR=$(abspath $(OUTDIR)) $(MINICARGO) --test $(RUSTCSRC)/src/lib$* --vendor-dir $(VENDOR_DIR) --output-dir $(dir $@) -L $(OUTDIR)
 $(OUTDIR)stdtest/collectionstests: $(OUTDIR)stdtest/alloc-test
 	test -e $@
 $(OUTDIR)collectionstest_out.txt: $(OUTDIR)%
-- 
2.47.1