size_compare.sh 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. # SPDX-License-Identifier: GPL-2.0-or-later
  2. #
  3. # Copyright (C) 2020 Paul Spooren <[email protected]>
  4. #
  5. ###
  6. ### size_compare - compare size of OpenWrt packages against upstream
  7. ###
  8. ### The script compares locally compiled package with the package indexes
  9. ### available upstream. This way the storage impact of optimizations or
  10. ### feature modifications is easy to see.
  11. ###
  12. ### If no environmental variables are set the script reads the current
  13. ### .config file. The evaluated env variables are the following:
  14. ###
  15. ### TARGET SUBTARGET ARCH PACKAGES BIN_DIR BASE_URL CHECK_INSTALLED
  16. ###
  17. ### Usage:
  18. ### ./scripts/size_compare.sh
  19. ###
  20. ### Options:
  21. ### -p --package-size Check IPK package size and not installed size
  22. ### -h --help This message
  23. CONFIG_TARGET=$(sed -n 's/^CONFIG_TARGET_BOARD="\(.*\)"$/\1/p' .config)
  24. CONFIG_SUBTARGET=$(sed -n 's/^CONFIG_TARGET_SUBTARGET="\(.*\)"$/\1/p' .config)
  25. CONFIG_ARCH=$(sed -n 's/^CONFIG_TARGET_ARCH_PACKAGES="\(.*\)"$/\1/p' .config)
  26. CONFIG_PACKAGES=$(sed -n 's/^CONFIG_PACKAGE_\(.*\)=y$/\1/p' .config | tr '\n' ' ')
  27. CONFIG_BIN_DIR=$(sed -n 's/^CONFIG_BINARY_DIR="\(.*\)"$/\1/p' .config)
  28. TARGET=${TARGET:-$CONFIG_TARGET}
  29. SUBTARGET=${SUBTARGET:-$CONFIG_SUBTARGET}
  30. ARCH=${ARCH:-$CONFIG_ARCH}
  31. PACKAGES=${PACKAGES:-$CONFIG_PACKAGES}
  32. BIN_DIR=${CONFIG_BIN_DIR:-./bin}
  33. BASE_URL="${BASE_URL:-https://downloads.openwrt.org/snapshots}"
  34. CHECK_INSTALLED="${CHECK_INSTALLED:-y}"
  35. TARGET_URL="$BASE_URL/targets/$TARGET/$SUBTARGET/packages/Packages.gz"
  36. CONFIG_URL="$BASE_URL/targets/$TARGET/$SUBTARGET/config.buildinfo"
  37. PACKAGES_URL="$BASE_URL/packages/$ARCH/base/Packages.gz"
  38. if command -v curl > /dev/null; then
  39. DOWNLOAD_METHOD="curl"
  40. else
  41. DOWNLOAD_METHOD="wget --output-document=-"
  42. fi
  43. help() {
  44. sed -rn 's/^### ?//;T;p' "$0"
  45. }
  46. package_size () {
  47. FOUND_PACKAGE=
  48. if [ -z "$CHECK_INSTALLED" ]; then
  49. SEARCH_PATTERN="Size"
  50. else
  51. SEARCH_PATTERN="Installed-Size"
  52. fi
  53. while IFS= read -r line; do
  54. if [ "$line" = "Package: $2" ]; then
  55. FOUND_PACKAGE=y
  56. fi
  57. if [ -n "$FOUND_PACKAGE" ]; then
  58. case $line in
  59. "$SEARCH_PATTERN"*)
  60. echo "$line" | cut -d ' ' -f 2
  61. break
  62. ;;
  63. esac
  64. fi
  65. done < "$1"
  66. }
  67. compare_sizes () {
  68. for PACKAGE in $PACKAGES; do
  69. if [ "$PACKAGE" = "libc" ]; then
  70. continue
  71. fi
  72. PACKAGE_FILE=$(find "$BIN_DIR/packages/$ARCH/" \
  73. "$BIN_DIR/targets/$TARGET/$SUBTARGET/" \
  74. -name "${PACKAGE}_*.ipk" 2>/dev/null | head -n1)
  75. if [ -z "$PACKAGE_FILE" ]; then
  76. continue
  77. fi
  78. if [ -z "$CHECK_INSTALLED" ]; then
  79. SIZE_LOCAL=$(stat -c '%s' "$PACKAGE_FILE")
  80. else
  81. SIZE_LOCAL=$(tar tzvf "$PACKAGE_FILE" ./data.tar.gz | awk '{ print $3 }')
  82. fi
  83. SIZE_UPSTREAM=$(package_size "$TMP_INDEX" "$PACKAGE")
  84. SIZE_DIFF="$((SIZE_LOCAL-SIZE_UPSTREAM))"
  85. if [ "$SIZE_DIFF" -gt 0 ]; then
  86. SIZE_DIFF="+$SIZE_DIFF"
  87. fi
  88. if [ -n "$SIZE_UPSTREAM" ]; then
  89. echo "${SIZE_DIFF} ${SIZE_LOCAL} ${SIZE_UPSTREAM} $PACKAGE"
  90. else
  91. echo "$PACKAGE is missing upstream"
  92. fi
  93. done
  94. }
  95. if [ "$1" = "-h" ]; then
  96. help
  97. exit 0
  98. fi
  99. if [ "$1" = "-p" ]; then
  100. CHECK_INSTALLED=
  101. fi
  102. echo "Compare packages of $TARGET/$SUBTARGET/$ARCH":
  103. echo "$PACKAGES"
  104. echo
  105. echo "Checking configuration difference"
  106. TMP_CONFIG=$(mktemp /tmp/config.XXXXXX)
  107. sed -n 's/^ \+config \(.*\)/\1/p' config/Config-build.in config/Config-devel.in > "${TMP_CONFIG}-FOCUS"
  108. sort .config | grep -f "${TMP_CONFIG}-FOCUS" | grep -v "^#" | sort > "${TMP_CONFIG}-LOCAL"
  109. mv .config .config.bak
  110. "$DOWNLOAD_METHOD" "$CONFIG_URL" > .config
  111. make defconfig > /dev/null 2> /dev/null
  112. grep -f "${TMP_CONFIG}-FOCUS" .config | grep -v "^#" | sort > "${TMP_CONFIG}-UPSTREAM"
  113. mv .config.bak .config
  114. echo
  115. echo " --- start config diff ---"
  116. diff -u "${TMP_CONFIG}-LOCAL" "${TMP_CONFIG}-UPSTREAM"
  117. echo " --- end config diff ---"
  118. rm "${TMP_CONFIG}-FOCUS" "${TMP_CONFIG}-UPSTREAM" "${TMP_CONFIG}-LOCAL"
  119. echo
  120. if [ -z "$CHECK_INSTALLED" ]; then
  121. echo "Checking IPK package size"
  122. else
  123. echo "Checking installed size"
  124. fi
  125. echo
  126. echo "Fetching latest package indexes..."
  127. TMP_INDEX=$(mktemp /tmp/size_compare_package_index.XXXXXX)
  128. "$DOWNLOAD_METHOD" "$TARGET_URL" | gzip -d > "$TMP_INDEX" || exit 1
  129. "$DOWNLOAD_METHOD" "$PACKAGES_URL" | gzip -d >> "$TMP_INDEX" || exit 1
  130. echo
  131. echo "Comparing package sizes..."
  132. echo "Change Local Remote Package"
  133. compare_sizes | sort -g -r
  134. rm "$TMP_INDEX"