| #!/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)) |
| |
| # 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=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. |
| ${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//... |
| cp -R $(${BAZEL_AIRGAPPED_DIR}/bazel info output_base)/external/${BAZEL_PYTHON_WHEEL_REPO} \ |
| ${BAZEL_AIRGAPPED_DIR}/ |
| 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_CACHEDIR} <label>" |
| fi |