blob: 905771e54078a9051d92415e29c00c1cc58a7d96 [file] [log] [blame]
#!/bin/bash
# Copyright 2023 Google LLC
# Copyright lowRISC contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Prepare the airgapped bazel dependency for bazel build in an airgapped
# environment. It can run natively or in docker, e.g., to support CentOS7.
#
# To run in CentOS7 docker (assuming the docker image centos7_airgap is
# available):
# As CLI:
# $ mkdir -p /tmp/fake_home
# $ cat << EOF > /tmp/fake_home/.gitconfig
# [user]
# name = foo
# email = bar@example.com
# EOF
# $ docker run --mount type=bind,src=${PWD},dst=/workdir \
# --mount type=bind,src=/tmp/fake_home,dst=/root \
# --user="$(id -u):$(id -g)" \
# --env FORCE_REBUILD=true \
# centos7_airgap \
# bash -eo pipefail -c "cd hw/matcha && ./util/prep-bazel-airgapped-build.sh"
# Interactively:
# $ mkdir -p /tmp/fake_home
# $ docker run --interactive \
# --mount type=bind,src=${PWD},dst=/workdir \
# --mount type=bind,src=/tmp/fake_home,dst=/root \
# --tty --rm
# --user="$(id -u):$(id -g)" centos7_airgap
set -euo pipefail
: "${REPO_TOP:=$(git rev-parse --show-toplevel)}"
: "${BAZEL_VERSION:=$(cat ${REPO_TOP}/.bazelversion)}"
: "${BAZEL_AIRGAPPED_DIR:=bazel-airgapped-ot9d059106}"
: "${BAZEL_DISTDIR:=bazel-distdir}"
: "${BAZEL_CACHEDIR:=bazel-cache}"
: "${BAZEL_PYTHON_WHEEL_REPO:=ot_python_wheels}"
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 Matcha bazel workspace dependencies will be added.
USAGE
}
AIRGAPPED_DIR_CONTENTS=${AIRGAPPED_DIR_CONTENTS:-ALL}
FORCE_REBUILD=${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))
if [[ -z ${ROOTDIR} ]]; then
echo "source build/setup.sh first"
exit 1
fi
# 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 -b "${BAZEL_VERSION}" --depth 1 \
https://github.com/bazelbuild/bazel bazel-repo
cd bazel-repo
echo "Cloned bazel repo @ \"${BAZEL_VERSION}\" (commit $(git rev-parse HEAD))"
../bazel build @additional_distfiles//:archives.tar
tar xvf bazel-bin/external/additional_distfiles/archives.tar \
-C "../${BAZEL_DISTDIR}" \
--strip-components=2
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}
# Prepare airgap offline built cores
if [[ ! -f "${ROOTDIR}/out/matcha/hw/fastvdma_core/fastvdma.core" ]]; then
mkdir -p ${ROOTDIR}/out/matcha/hw/fastvdma_core
touch ${ROOTDIR}/out/matcha/hw/fastvdma_core/fastvdma.core
fi
if [[ ! -f "${ROOTDIR}/out/kelvin/hw/kelvin_core/kelvin.core" ]]; then
mkdir -p ${ROOTDIR}/out/kelvin/hw/kelvin_core
touch ${ROOTDIR}/out/kelvin/hw/kelvin_core/kelvin.core
fi
# Patch airgap build environment
git apply util/bazel_airgapped.patch
# Make bazel forget everything it knows, then download everything.
${BAZEL_AIRGAPPED_DIR}/bazel clean --expunge
# Only pick up the packages required by matcha
${BAZEL_AIRGAPPED_DIR}/bazel fetch \
--repository_cache=${BAZEL_AIRGAPPED_DIR}/${BAZEL_CACHEDIR} \
//... \
@bindgen_clang_linux//... \
@rules_rust_bindgen__bindgen-0.60.1//... \
@lowrisc_rv32imcb_files//... \
@local_config_cc_toolchains//... \
@local_config_platform//... \
@local_config_sh//... \
@python3_toolchains//... \
@remotejdk11_linux//... \
@rules_foreign_cc//toolchains/... \
@rust_analyzer_1.67.0_tools//... \
@rust_linux_x86_64__x86_64-unknown-linux-gnu__nightly_tools//... \
@org_chipsalliance_chisel_plugin//... \
@kelvin_hw//lib:chisel_lib
cp -R $(${BAZEL_AIRGAPPED_DIR}/bazel info output_base)/external/${BAZEL_PYTHON_WHEEL_REPO} \
${BAZEL_AIRGAPPED_DIR}/
echo "Done."
git reset --hard
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_CACHEDIR} <label>"
fi