| #!/usr/bin/env bash |
| |
| # Copyright 2018 The Fuchsia Authors |
| # |
| # Use of this source code is governed by a MIT-style |
| # license that can be found in the LICENSE file or at |
| # https://opensource.org/licenses/MIT |
| |
| readonly SCRIPT_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" |
| readonly ZIRCON_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" |
| readonly PREBUILTS_DIR="$(cd "${ZIRCON_ROOT}/prebuilt" && pwd)" |
| readonly DOWNLOAD_DIR="${PREBUILTS_DIR}/downloads" |
| readonly ENSURE_FILE="${PREBUILTS_DIR}/zircon.ensure" |
| readonly VERSIONS_FILE="${PREBUILTS_DIR}/zircon.versions" |
| readonly URL_PREFIX="https://storage.googleapis.com/fuchsia" |
| |
| # This script assumes that ENSURE_FILE and VERSIONS_FILE match up. |
| # The update-prebuilt-versions script ensures that they do. When a |
| # cipd binary is available, ENSURE_FILE controls the downloads. |
| # Otherwise, VERSIONS_FILE controls the downloads. In both cases we |
| # write $DOWNLOAD_DIR/$PACKAGE.stamp files with the versions from |
| # VERSIONS_FILE on faith that that's what we just unpacked. |
| |
| cipd_ok=true |
| case "$#:$1" in |
| 0:) |
| mode=update |
| ;; |
| 1:--verify) |
| mode=verify |
| ;; |
| 1:--list) |
| mode=list |
| ;; |
| 1:--no-cipd) |
| mode=update |
| cipd_ok=false |
| ;; |
| *) |
| echo >&2 "Usage: $0 [--verify|--list|--no-cipd]" |
| exit 1 |
| ;; |
| esac |
| readonly cipd_ok |
| |
| case "$(uname)-$(uname -m)" in |
| Darwin-x86_64) |
| PLATFORM=mac-amd64 |
| ;; |
| Linux-x86_64) |
| PLATFORM=linux-amd64 |
| ;; |
| Linux-aarch64) |
| PLATFORM=linux-arm64 |
| ;; |
| *) |
| echo 'Unknown operating system.' |
| exit 1 |
| ;; |
| esac |
| readonly PLATFORM |
| |
| update_stamp() { |
| local -r package="$1" version="$2" download_file="$3" |
| local -r stamp="${DOWNLOAD_DIR}/${download_file%.*}.stamp" |
| mkdir -p "$(dirname "$stamp")" && echo "$version" > "$stamp" |
| } |
| |
| verify_stamp() { |
| local verbose=false |
| if [[ "$1" = "--verbose" ]]; then |
| verbose=true |
| shift |
| fi |
| local -r package="$1" version="$2" download_file="$3" |
| local -r stamp="${DOWNLOAD_DIR}/${download_file%.*}.stamp" |
| local stamp_version |
| if [[ -r "$stamp" ]]; then |
| stamp_version="$(< "$stamp")" |
| else |
| stamp_version="missing" |
| fi |
| if [[ "$stamp_version" = "$version" ]]; then |
| return 0 |
| fi |
| if $verbose; then |
| echo "WARNING: unpacked $package $stamp_version != current $version" |
| fi |
| return 1 |
| } |
| |
| list_package() { |
| local -r package="$1" version="$2" download_file="$3" single_file="$4" |
| local -r package_suffix="$5" |
| local -r stamp="${DOWNLOAD_DIR}/${download_file%.*}.stamp" |
| local stamp_version |
| if [[ -r "$stamp" ]]; then |
| stamp_version="$(< "$stamp")" |
| else |
| stamp_version="missing" |
| fi |
| local installed="${stamp_version:-missing}" |
| if [[ "$installed" = "$version" ]]; then |
| installed="current" |
| fi |
| echo "$package$package_suffix" "installed=$installed" "current=$version" |
| } |
| |
| verify_file() { |
| local -r file="$1" |
| local -r sum="$2" |
| shasum --binary --check --status <<EOF |
| $sum *$file |
| EOF |
| } |
| |
| download_package() { |
| local -r package="$1" version="$2" download_file="$3" single_file="$4" |
| local -r package_suffix="$5" |
| local -r url="${URL_PREFIX}/${package}${package_suffix}/${version}" |
| local -r download_file_with_dir="${DOWNLOAD_DIR}/${download_file}" |
| |
| # If the stamp file says it's already in place, do nothing more. |
| verify_stamp "$package" "$version" "$download_file" && return |
| |
| rm -f -- "$download_file_with_dir" |
| echo "Downloading $url" |
| curl --progress-bar -continue-at=- --location \ |
| --create-dirs --output "$download_file_with_dir" "$url" || return |
| |
| verify_file "$download_file_with_dir" "$version" || { |
| echo >&2 "*** VERIFICATION ERROR ***" |
| echo >&2 "*** VERIFICATION ERROR *** $download_file from $url" |
| echo >&2 "*** VERIFICATION ERROR *** Not using the file!" |
| return 1 |
| } |
| |
| echo "Unpacking $download_file" |
| if $single_file; then |
| # The archive contains .cipd* metadata files and a single real file |
| # whose name is the same as the basename of the package. |
| unzip -q -o -d "$DOWNLOAD_DIR" "$download_file_with_dir" \ |
| "${package##*/}" || return |
| else |
| local -r dir="${download_file_with_dir%.zip}" |
| rm -rf -- "$dir" |
| unzip -q -d "$dir" "$download_file_with_dir" || return |
| fi |
| |
| update_stamp "$package" "$version" "$download_file" |
| } |
| |
| for_each_package() { |
| local package version download_file single_file package_suffix status=0 |
| while read package version; do |
| case "$package" in |
| ''|\#*) |
| continue |
| ;; |
| tools/*/${PLATFORM}) |
| # These are standalone executables contained in a .zip file. |
| package="${package%/*}" |
| download_file="${package#tools/}.zip" |
| single_file=true |
| package_suffix="/${PLATFORM}" |
| ;; |
| */${PLATFORM}) |
| package="${package%/*}" |
| # Subdirectories are packed in .zip files. |
| download_file="${package}.zip" |
| single_file=false |
| package_suffix="/${PLATFORM}" |
| ;; |
| firmware/*) |
| # These are the same for every host platform. |
| download_file="${package}.zip" |
| single_file=false |
| package_suffix='' |
| ;; |
| *) |
| # Skip lines for other platforms. |
| continue |
| ;; |
| esac |
| "$@" "$package" "$version" "$download_file" $single_file "$package_suffix" || |
| status=$? |
| done |
| return $status |
| } |
| |
| find_cipd() { |
| # If the Zircon checkout is part of a jiri checkout that includes |
| # //buildtools, then find cipd there. Otherwise, if cipd is in |
| # the PATH, take it from there. |
| type -p "${ZIRCON_ROOT}/../buildtools/cipd" || type -p cipd |
| } |
| |
| update_via_cipd() { |
| local -r CIPD="$1" internal_access="$2" |
| |
| ensure_files="${PREBUILTS_DIR}/zircon.ensure" |
| if $internal_access; then |
| ensure_files+=" ${PREBUILTS_DIR}/zircon_internal.ensure" |
| fi |
| |
| cat $ensure_files | "$CIPD" ensure -ensure-file - \ |
| -root "$DOWNLOAD_DIR" \ |
| -log-level warning |
| rc=$? |
| if [[ $rc -ne 0 ]]; then |
| echo >&2 "$0: $CIPD failed. For direct downloads, remove cipd from PATH." |
| return $rc |
| fi |
| |
| "$(dirname $0)/update-prebuilt-versions" --verify || { |
| echo >&2 "$0: update-prebuilt-versions not run after ensure file changed!" |
| return 2 |
| } |
| |
| # Now update the .stamp files so that --verify will be happy. |
| for_each_package update_stamp < "$VERSIONS_FILE" |
| } |
| |
| write_sysroot_path() { |
| local -r package="$1" version="$2" |
| if [[ "$package" = sysroot ]]; then |
| echo "SYSROOT_${PLATFORM}_PATH = \$(LKMAKEROOT)/prebuilt/downloads/sysroot" |
| fi |
| } |
| |
| write_config_mk() { |
| local -r internal_access="$1" |
| local -r config_mk="${PREBUILTS_DIR}/config.mk" |
| rm -f -- "$config_mk" |
| echo > "$config_mk" "# Generated by $0. DO NOT EDIT!"' |
| |
| PREBUILT_CHECK := $(shell $(LKMAKEROOT)/scripts/download-prebuilt --verify) |
| ifneq (,$(strip $(PREBUILT_CHECK))) |
| $(warning) |
| $(warning $(PREBUILT_CHECK)) |
| $(warning run scripts/download-prebuilt) |
| $(warning) |
| endif |
| |
| ARCH_x86_64_TOOLCHAIN_PREFIX = $(LKMAKEROOT)/prebuilt/downloads/gcc/bin/x86_64-elf- |
| ARCH_arm64_TOOLCHAIN_PREFIX = $(LKMAKEROOT)/prebuilt/downloads/gcc/bin/aarch64-elf- |
| CLANG_TOOLCHAIN_PREFIX = $(LKMAKEROOT)/prebuilt/downloads/clang/bin/' |
| |
| for_each_package write_sysroot_path < "$VERSIONS_FILE" >> "$config_mk" |
| |
| echo >> "$config_mk" "INTERNAL_ACCESS := ${internal_access}" |
| } |
| |
| update() { |
| local CIPD |
| local internal_access=false |
| if $cipd_ok && CIPD="$(find_cipd)"; then |
| # We have CIPD, so use it. |
| if [[ "$("$CIPD" ls fuchsia_internal)" != "No matching packages." ]]; then |
| internal_access=true |
| fi |
| update_via_cipd "$CIPD" "$internal_access" || return |
| else |
| # We don't have CIPD, so don't use it. |
| for_each_package download_package < "$VERSIONS_FILE" || return |
| fi |
| write_config_mk "$internal_access" |
| } |
| |
| verify() { |
| for_each_package verify_stamp --verbose < "$VERSIONS_FILE" |
| } |
| |
| list() { |
| for_each_package list_package < "$VERSIONS_FILE" |
| } |
| |
| $mode |