[bazel] add script to prep for offline bazel builds
In order to build SW artifacts with bazel in an airgapped environment,
a distdir and cache must be prepared to hold a copy of bazel (and its
dependencies) and the OpenTitan bazel workspace dependencies. This adds
a script to prepare a directory to store both, so that both can be
easily transferred to the airgapped machine.
Signed-off-by: Timothy Trippel <ttrippel@google.com>
diff --git a/util/prep-bazel-airgapped-build.sh b/util/prep-bazel-airgapped-build.sh
new file mode 100755
index 0000000..c093e23
--- /dev/null
+++ b/util/prep-bazel-airgapped-build.sh
@@ -0,0 +1,163 @@
+#!/bin/bash
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+set -euo pipefail
+
+: "${REPO_TOP:=$(git rev-parse --show-toplevel)}"
+
+: "${BAZELISK:=${REPO_TOP}/bazelisk.sh}"
+: "${BAZEL_VERSION:=$(cat ${REPO_TOP}/.bazelversion)}"
+
+: "${BAZEL_AIRGAPPED_DIR:=bazel-airgapped}"
+: "${BAZEL_DISTDIR:=bazel-distdir}"
+: "${BAZEL_CACHEDIR:=bazel-cache}"
+
+LINE_SEP="====================================================================="
+
+################################################################################
+# Process cmd line args.
+################################################################################
+function usage() {
+ cat << USAGE
+Utility script to prepare a directory with all bazel dependencies needed to
+build project artifacts with bazel in an airgapped environment.
+
+Usage: $0 [-c all | distdir | cache]
+
+ - c: airgapped directory contents, set to either ALL or DISTDIR or CACHE.
+ - f: force rebuild of airgapped directory, overwriting any existing one.
+
+Airgapped directory contents (-b):
+ - ALL: both the distdir and cache will be added. (Default)
+ - DISTDIR: only the distdir, containing bazel and its dependencies will be added.
+ - CACHE: only the OpenTitan bazel workspace dependencies will be added.
+
+USAGE
+}
+
+AIRGAPPED_DIR_CONTENTS="ALL"
+FORCE_REBUILD=false
+
+while getopts ':c:f' flag; do
+ case "${flag}" in
+ c) AIRGAPPED_DIR_CONTENTS="${OPTARG}";;
+ f) FORCE_REBUILD=true;;
+ \?) echo "Unexpected option: -${OPTARG}" >&2
+ usage
+ exit 1
+ ;;
+ :) echo "Option -${OPTARG} requires an argument" >&2
+ usage
+ exit 1
+ ;;
+ *) echo "Internal Error: Unhandled option: -${flag}" >&2
+ exit 1
+ ;;
+ esac
+done
+shift $((OPTIND - 1))
+
+# We do not accept additional arguments.
+if [[ "$#" -gt 0 ]]; then
+ echo "Unexpected arguments:" "$@" >&2
+ exit 1
+fi
+
+if [[ ${AIRGAPPED_DIR_CONTENTS} != "ALL" && \
+ ${AIRGAPPED_DIR_CONTENTS} != "DISTDIR" && \
+ ${AIRGAPPED_DIR_CONTENTS} != "CACHE" ]]; then
+ echo "Invalid -c option: ${AIRGAPPED_DIR_CONTENTS}." >&2
+ echo "Expected ALL, DISTDIR, or CACHE." >&2
+ exit 1
+fi
+
+
+################################################################################
+# Check if a previous airgapped directory has been built.
+################################################################################
+if [[ -d ${BAZEL_AIRGAPPED_DIR} ]]; then
+ if [[ ${FORCE_REBUILD} = false ]]; then
+ while true; do
+ read -p "Airgapped directory exists, rebuild? [Y/n]" yn
+ case $yn in
+ "") rm -rf ${BAZEL_AIRGAPPED_DIR}; break;;
+ [Yy]*) rm -rf ${BAZEL_AIRGAPPED_DIR}; break;;
+ [Nn]*) exit;;
+ *) echo "Please enter [Yy] or [Nn]."
+ esac
+ done
+ else
+ rm -rf ${BAZEL_AIRGAPPED_DIR}
+ fi
+fi
+
+################################################################################
+# Setup the airgapped directory.
+################################################################################
+mkdir -p ${BAZEL_AIRGAPPED_DIR}
+
+################################################################################
+# Prepare the distdir.
+################################################################################
+if [[ ${AIRGAPPED_DIR_CONTENTS} == "ALL" || \
+ ${AIRGAPPED_DIR_CONTENTS} == "DISTDIR" ]]; then
+ echo $LINE_SEP
+ echo "Preparing bazel offline distdir ..."
+ mkdir -p ${BAZEL_AIRGAPPED_DIR}/${BAZEL_DISTDIR}
+ cd ${BAZEL_AIRGAPPED_DIR}
+ curl --silent --location \
+ https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-linux-x86_64 \
+ --output bazel
+ chmod +x bazel
+ git clone https://github.com/bazelbuild/bazel bazel-repo
+ cd bazel-repo
+ git checkout "$(cat ${REPO_TOP}/.bazelversion)"
+ ../bazel build @additional_distfiles//:archives.tar
+ tar xvf bazel-bin/external/additional_distfiles/archives.tar \
+ -C "../${BAZEL_DISTDIR}" \
+ --strip-components=3
+ cd ..
+ rm -rf bazel-repo
+ echo "Done."
+fi
+
+################################################################################
+# Prepare the cache.
+################################################################################
+if [[ ${AIRGAPPED_DIR_CONTENTS} == "ALL" || \
+ ${AIRGAPPED_DIR_CONTENTS} == "CACHE" ]]; then
+ echo $LINE_SEP
+ echo "Preparing bazel offline cachedir ..."
+ cd ${REPO_TOP}
+ mkdir -p ${BAZEL_AIRGAPPED_DIR}/${BAZEL_CACHEDIR}
+ # Make bazel forget everything it knows, then download everything.
+ ${BAZELISK} clean --expunge
+ ${BAZELISK} fetch \
+ --repository_cache=${BAZEL_AIRGAPPED_DIR}/${BAZEL_CACHEDIR} \
+ //... \
+ @bazel_embedded_upstream_toolchain//... \
+ @local_config_cc_toolchains//... \
+ @local_config_platform//... \
+ @local_config_sh//... \
+ @python3_9_toolchains//... \
+ @riscv-compliance//... \
+ @rust_darwin_aarch64_toolchains//... \
+ @rust_darwin_x86_64_toolchains//... \
+ @rust_freebsd_x86_64_toolchains//... \
+ @rust_linux_aarch64_toolchains//... \
+ @rust_linux_x86_64_toolchains//... \
+ @rust_windows_x86_64_toolchains//...
+ echo "Done."
+fi
+
+################################################################################
+# Print some usage instructions.
+################################################################################
+if [[ ${AIRGAPPED_DIR_CONTENTS} == "ALL" ]]; then
+ echo $LINE_SEP
+ echo "To perform an airgapped build, ship the contents of ${BAZEL_AIRGAPPED_DIR} to your airgapped environment and then:"
+ echo ""
+ echo "bazel build --distdir=${BAZEL_AIRGAPPED_DIR}/${BAZEL_DISTDIR} --repository_cache=${BAZEL_AIRGAPPED_DIR}/${BAZEL_DISTDIR} <label>"
+fi