Makefile: Add $(xcompile) to specify where to write xcompile

This file was being written to the root src directory. It is the only
file being written to src during a normal build, while all others are
being written to $(obj). I added a new variable to allow specifying the
xcompile path. This allows generating a single file if building multiple
boards. I also moved the default location into $(obj) so we don't
pollute the src directory by default.

I also cleaned up the generation of xcompile by removing the unnecessary
eval and NOCOMPILE check.

I also left .xcompile in distclean so it cleans up stale files.

Since .xcompile is written into $(obj), `make clean` will now remove it.

The tegra Makefiles are outside of the normal build process, so I just
updated those Makefiles to point to the default xcompile location of a
normal build. The what-jenkins-does target had to be updated to support
these special targets. We generate an xcompile specifically for these
targets and pass it into the Makefile. Ideally we should get these
targets added to the main build.

BUG=b:112267918
TEST=ran `emerge-grunt coreboot` and `make what-jenkins-does`

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Change-Id: Ia83f234447b977efa824751c9674154b77d606b0
Reviewed-on: https://review.coreboot.org/c/coreboot/+/28101
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
diff --git a/Makefile b/Makefile
index 1b7cb9b..ec0f95b 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@
 srck := $(top)/util/kconfig
 obj ?= build
 override obj := $(subst $(top)/,,$(abspath $(obj)))
+xcompile ?= $(obj)/xcompile
 objutil ?= $(obj)/util
 objk := $(objutil)/kconfig
 absobj := $(abspath $(obj))
@@ -119,7 +120,7 @@
 NOCOMPILE:=
 endif
 
-.xcompile: util/xcompile/xcompile
+$(xcompile): util/xcompile/xcompile
 	rm -f $@
 	$< $(XGCCPATH) > $@.tmp
 	\mv -f $@.tmp $@ 2> /dev/null
@@ -146,15 +147,17 @@
 include $(DOTCONFIG)
 endif
 
-# in addition to the dependency below, create the file if it doesn't exist
-# to silence stupid warnings about a file that would be generated anyway.
-$(if $(wildcard .xcompile)$(NOCOMPILE),,$(eval $(shell util/xcompile/xcompile $(XGCCPATH) > .xcompile || rm -f .xcompile)))
+# The toolchain requires xcompile to determine the ARCH_SUPPORTED, so we can't
+# wait for make to generate the file.
+$(if $(wildcard $(xcompile)),, $(shell \
+	mkdir -p $(dir $(xcompile)) && \
+	util/xcompile/xcompile $(XGCCPATH) > $(xcompile) || rm -f $(xcompile)))
 
--include .xcompile
+include $(xcompile)
 
 ifneq ($(XCOMPILE_COMPLETE),1)
-$(shell rm -f .xcompile)
-$(error .xcompile deleted because it's invalid. \
+$(shell rm -f $(xcompile))
+$(error $(xcompile) deleted because it's invalid. \
 	Restarting the build should fix that, or explain the problem)
 endif
 
diff --git a/Makefile.inc b/Makefile.inc
index 1212dae..2b9d58d 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -520,7 +520,8 @@
 # Report new `build.ht` as dependency if `build.h` differs.
 build_h_check := \
 	export $(foreach exp,$(build_h_exports),$(exp)="$($(exp))"); \
-	util/genbuild_h/genbuild_h.sh .xcompile >$(build_h)t 2>/dev/null; \
+	util/genbuild_h/genbuild_h.sh $(xcompile) \
+		>$(build_h)t 2>/dev/null; \
 	cmp -s $(build_h)t $(build_h) >/dev/null 2>&1 || echo $(build_h)t
 
 $(build_h): $$(shell $$(build_h_check))
diff --git a/src/soc/nvidia/tegra124/lp0/Makefile b/src/soc/nvidia/tegra124/lp0/Makefile
index 68a3cb6..dc33909 100644
--- a/src/soc/nvidia/tegra124/lp0/Makefile
+++ b/src/soc/nvidia/tegra124/lp0/Makefile
@@ -1,6 +1,8 @@
 ## SPDX-License-Identifier: GPL-2.0-only
 
--include ../../../../../.xcompile
+xcompile ?= ../../../../../build/xcompile
+-include $(xcompile)
+
 GCC_PREFIX?=$(CROSS_COMPILE_arm)
 
 CC = $(GCC_PREFIX)gcc
diff --git a/src/soc/nvidia/tegra210/lp0/Makefile b/src/soc/nvidia/tegra210/lp0/Makefile
index 68a3cb6..dc33909 100644
--- a/src/soc/nvidia/tegra210/lp0/Makefile
+++ b/src/soc/nvidia/tegra210/lp0/Makefile
@@ -1,6 +1,8 @@
 ## SPDX-License-Identifier: GPL-2.0-only
 
--include ../../../../../.xcompile
+xcompile ?= ../../../../../build/xcompile
+-include $(xcompile)
+
 GCC_PREFIX?=$(CROSS_COMPILE_arm)
 
 CC = $(GCC_PREFIX)gcc
diff --git a/util/abuild/abuild b/util/abuild/abuild
index 2ba2f72..408de12 100755
--- a/util/abuild/abuild
+++ b/util/abuild/abuild
@@ -354,7 +354,6 @@
 	eval "$BUILDPREFIX" "$MAKE" "$verboseopt" DOTCONFIG="${build_dir}/config.build" obj="${build_dir}" objutil="$TARGET/sharedutils" BUILD_TIMELESS=$TIMELESS \
 		&> "${build_dir}/make.log" ; \
 		MAKE_FAILED=$?
-	cp "${ROOT}/.xcompile" "${build_dir}/xcompile.build"
 	cd "${build_dir}" || return $?
 
 	etime=$(perl -e 'print time();' 2>/dev/null || date +%s)
@@ -466,10 +465,10 @@
 
 	missing_arches="$($MAKE --no-print-directory -f - \
 		REQUIRED_ARCHES="$required_arches" <<'EOF'
-include .xcompile
+include $(xcompile)
 .PHONY: missing_arches
 missing_arches:
-	$(if $(XCOMPILE_COMPLETE),,$(error .xcompile is invalid.))
+	$(if $(XCOMPILE_COMPLETE),,$(error $(xcompile) is invalid.))
 	@echo $(foreach arch,$(REQUIRED_ARCHES),$(if $(filter $(arch),$(SUBARCH_SUPPORTED)),,$(arch)))
 EOF
 )"
@@ -767,7 +766,9 @@
 	exit 1
 fi
 
-$MAKE -C"${ROOT}" UPDATED_SUBMODULES=1 .xcompile || exit 1
+# Generate a single xcompile for all boards
+export xcompile="${TARGET}/xcompile"
+$MAKE -C"${ROOT}" UPDATED_SUBMODULES=1 "${xcompile}" || exit 1
 
 customizing=$(echo "$customizing" | cut -c3-)
 if [ "$customizing" = "" ]; then
diff --git a/util/crossgcc/Makefile.inc b/util/crossgcc/Makefile.inc
index 582e600..74de5bd 100644
--- a/util/crossgcc/Makefile.inc
+++ b/util/crossgcc/Makefile.inc
@@ -65,7 +65,5 @@
 	$(MAKE) crossgcc clang KEEP_SOURCES=1 BUILDGCC_OPTIONS='$(BUILDGCC_OPTIONS)'
 	#TODO: Re-enable gdb build after the builders can build it again.
 	#$(MAKE) crosstools clang KEEP_SOURCES=1 BUILDGCC_OPTIONS='$(BUILDGCC_OPTIONS)'
-	rm -f .xcompile
 	PATH=$(if $(DEST),$(DEST)/bin,$(top)/util/crossgcc/xgcc/bin):$$PATH; $(MAKE) what-jenkins-does
-	-cat .xcompile
 	PATH=$(if $(DEST),$(DEST)/bin,$(top)/util/crossgcc/xgcc/bin):$$PATH; $(MAKE) test-toolchain
diff --git a/util/docker/Makefile b/util/docker/Makefile
index cf14c0d..a8fb571 100644
--- a/util/docker/Makefile
+++ b/util/docker/Makefile
@@ -110,11 +110,11 @@
 
 docker-build-coreboot: docker-run-local
 docker-build-coreboot: override DOCKER_RUN_LOCAL := \
-	make clean && make $(BUILD_CMD); rm -f .xcompile
+	make clean && make $(BUILD_CMD)
 
 docker-abuild: docker-run-local
 docker-abuild: override DOCKER_RUN_LOCAL := \
-	make clean && util/abuild/abuild $(ABUILD_ARGS); rm -f .xcompile
+	make clean && util/abuild/abuild $(ABUILD_ARGS)
 
 docker-what-jenkins-does: docker-run-local
 docker-what-jenkins-does: override DOCKER_RUN_LOCAL := \
diff --git a/util/testing/Makefile.inc b/util/testing/Makefile.inc
index d094196..989fe69 100644
--- a/util/testing/Makefile.inc
+++ b/util/testing/Makefile.inc
@@ -89,8 +89,10 @@
 	unset COREBOOT_BUILD_DIR;$(MAKE) CPUS=$(CPUS) V=$(V) Q=$(Q) BLD_DIR=payloads/nvramcui BLD=nvramcui MFLAGS= MAKEFLAGS= MAKETARGET=all junit.xml
 	unset COREBOOT_BUILD_DIR;$(MAKE) CPUS=$(CPUS) V=$(V) Q=$(Q) BLD_DIR=payloads/coreinfo BLD=coreinfo MFLAGS= MAKEFLAGS= MAKETARGET=defaultbuild junit.xml
 	(cd payloads/libpayload; unset COREBOOT_BUILD_DIR; $(MAKE) $(if $(JENKINS_NOCCACHE),,CONFIG_LP_CCACHE=y) V=$(V) Q=$(Q) junit.xml)
-	$(MAKE) CPUS=$(CPUS) V=$(V) Q=$(Q) BLD_DIR=src/soc/nvidia/tegra124/lp0 BLD=tegra124_lp0 MFLAGS= MAKEFLAGS= MAKETARGET=all junit.xml
-	$(MAKE) CPUS=$(CPUS) V=$(V) Q=$(Q) BLD_DIR=src/soc/nvidia/tegra210/lp0 BLD=tegra120_lp0 MFLAGS= MAKEFLAGS= MAKETARGET=all junit.xml
+# These targets don't use the standard build system, so we need to provide an xcompile to them.
+	$(MAKE) xcompile=$(COREBOOT_BUILD_DIR)/xcompile $(COREBOOT_BUILD_DIR)/xcompile
+	$(MAKE) CPUS=$(CPUS) V=$(V) Q=$(Q) BLD_DIR=src/soc/nvidia/tegra124/lp0 BLD=tegra124_lp0 MFLAGS= MAKEFLAGS=xcompile=$(COREBOOT_BUILD_DIR)/xcompile MAKETARGET=all junit.xml
+	$(MAKE) CPUS=$(CPUS) V=$(V) Q=$(Q) BLD_DIR=src/soc/nvidia/tegra210/lp0 BLD=tegra120_lp0 MFLAGS= MAKEFLAGS=xcompile=$(COREBOOT_BUILD_DIR)/xcompile MAKETARGET=all junit.xml
 	$(MAKE) unit-tests JUNIT_OUTPUT=y
 
 test-basic: test-lint test-tools test-abuild test-payloads test-cleanup