| #!/usr/bin/env bash |
| set -e |
| |
| # Add hash files for packages with custom versions for |
| # BR2_DOWNLOAD_FORCE_CHECK_HASHES=y |
| # |
| # Run in a configured Buildroot directory, E.G. |
| # make foo_defconfig; ./utils/add-custom-hashes |
| |
| # print BR-style message |
| # message <info message> |
| message() { |
| tput smso 2>/dev/null |
| echo "$*" |
| tput rmso 2>/dev/null |
| } |
| |
| # print error message and exit |
| # die <error message> |
| die() { |
| echo "Error: $*" >&2 |
| exit 1 |
| } |
| |
| # get package(s) for download file, if any |
| # get_pkgs <json> <file> |
| get_pkgs() { |
| jq --arg file "$2" -r \ |
| 'to_entries[] | select(.value.downloads[0].source == $file) | .key | strings' "$1" |
| } |
| |
| # get download dir for package |
| # get_pkg_dl_dir <json> <package> |
| get_pkg_dl_dir() { |
| jq --arg pkg "$2" -r '.[$pkg].dl_dir | strings' "$1" |
| } |
| |
| # generate hash file for download file |
| # gen_hash <dir> <file> |
| gen_hash() { |
| ( |
| cd "$1" && printf '# Locally calculated\nsha256 ' && sha256sum "$2" |
| ) |
| } |
| |
| command -v jq >/dev/null || die 'Script needs jq' |
| |
| [ -e .config ] || \ |
| die "No .config found, please run this in a configured Buildroot (O=) directory" |
| |
| message Collecting data |
| |
| eval "$(make -s VARS='TOPDIR DL_DIR BR_NO_CHECK_HASH_FOR BR2_GLOBAL_PATCH_DIR' QUOTED_VARS=YES printvars)" |
| # global patch dir may already have quotes |
| BR2_GLOBAL_PATCH_DIR=$(echo "$BR2_GLOBAL_PATCH_DIR" | tr -d '"') |
| |
| [ -n "$BR2_GLOBAL_PATCH_DIR" ] || die "No BR2_GLOBAL_PATCH_DIR defined, nothing to do" |
| [ -n "$BR_NO_CHECK_HASH_FOR" ] || die "No packages without hashes found, nothing to do" |
| |
| [ -d "$TOPDIR" ] || die "TOPDIR ($TOPDIR) does not look correct" |
| [ -d "$DL_DIR" ] || die "DL_DIR ($DL_DIR) does not look correct" |
| |
| # patch dir may contain multiple dirs, use the last one |
| # shellcheck disable=SC2086 # we need the word splitting |
| set -- $BR2_GLOBAL_PATCH_DIR |
| if [ $# -gt 1 ]; then |
| BR2_GLOBAL_PATCH_DIR="${!#}"; |
| message BR2_GLOBAL_PATCH_DIR contains multiple directories, using "$BR2_GLOBAL_PATCH_DIR" |
| fi |
| |
| # patch dir may be relative to TOPDIR |
| case "$BR2_GLOBAL_PATCH_DIR" in |
| /*) ;; |
| *) BR2_GLOBAL_PATCH_DIR="$TOPDIR/$BR2_GLOBAL_PATCH_DIR" |
| ;; |
| esac |
| |
| [ -d "$BR2_GLOBAL_PATCH_DIR" ] \ |
| || die "BR2_GLOBAL_PATCH_DIR ($BR2_GLOBAL_PATCH_DIR) does not look correct" |
| |
| trap 'rm -f "$JSON"' EXIT |
| JSON=$(mktemp) |
| make show-info > "$JSON" |
| |
| # ensure files have been downloaded, but without checking |
| make BR2_DOWNLOAD_FORCE_CHECK_HASHES= source |
| |
| message Updating hashes |
| |
| for file in $BR_NO_CHECK_HASH_FOR; do |
| for pkg in $(get_pkgs "$JSON" "$file"); do |
| HASHFILE="$BR2_GLOBAL_PATCH_DIR/$pkg/$pkg.hash" |
| PKG_DL_DIR=$(get_pkg_dl_dir "$JSON" "$pkg") |
| message "Adding hash for $file to $HASHFILE" |
| mkdir -p "${HASHFILE%/*}" |
| gen_hash "$DL_DIR/$PKG_DL_DIR" "$file" > "$HASHFILE" |
| done |
| done |
| |
| # Symlink linux-headers to linux if identical |
| linux_hash="$BR2_GLOBAL_PATCH_DIR/linux/linux.hash" |
| linux_headers_hash="$BR2_GLOBAL_PATCH_DIR/linux-headers/linux-headers.hash" |
| if [ -e "$linux_hash" ] && [ -e "$linux_headers_hash" ] \ |
| && cmp -s "$linux_hash" "$linux_headers_hash"; then |
| ln -sf ../linux/linux.hash "$linux_headers_hash" |
| fi |
| |
| message Verifying hashes |
| |
| make clean |
| make BR2_DOWNLOAD_FORCE_CHECK_HASHES=y source |