size_compare.sh 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. # SPDX-License-Identifier: GPL-2.0-or-later
  2. #
  3. # Copyright (C) 2020 Paul Spooren <mail@aparcar.org>
  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. eval "$(grep \
  24. -e ^CONFIG_TARGET_BOARD= \
  25. -e ^CONFIG_TARGET_SUBTARGET= \
  26. -e ^CONFIG_TARGET_ARCH_PACKAGES= \
  27. -e ^CONFIG_BINARY_FOLDER= \
  28. .config 2>/dev/null \
  29. )"
  30. CONFIG_PACKAGES=$(sed -n 's/^CONFIG_PACKAGE_\(.*\)=y$/\1/p' .config | tr '\n' ' ')
  31. TARGET=${TARGET:-$CONFIG_TARGET_BOARD}
  32. SUBTARGET=${SUBTARGET:-$CONFIG_TARGET_SUBTARGET}
  33. ARCH=${ARCH:-$CONFIG_TARGET_ARCH_PACKAGES}
  34. PACKAGES=${PACKAGES:-$CONFIG_PACKAGES}
  35. BIN_DIR=${CONFIG_BINARY_FOLDER:-./bin}
  36. BASE_URL="${BASE_URL:-https://downloads.openwrt.org/snapshots}"
  37. CHECK_INSTALLED="${CHECK_INSTALLED:-y}"
  38. TARGET_URL="$BASE_URL/targets/$TARGET/$SUBTARGET/packages/Packages.gz"
  39. CONFIG_URL="$BASE_URL/targets/$TARGET/$SUBTARGET/config.buildinfo"
  40. PACKAGES_URL="$BASE_URL/packages/$ARCH/base/Packages.gz"
  41. if command -v curl > /dev/null; then
  42. DOWNLOAD_METHOD="curl"
  43. else
  44. DOWNLOAD_METHOD="wget --output-document=-"
  45. fi
  46. help() {
  47. sed -rn 's/^### ?//;T;p' "$0"
  48. }
  49. package_size () {
  50. FOUND_PACKAGE=
  51. if [ -z "$CHECK_INSTALLED" ]; then
  52. SEARCH_PATTERN="Size"
  53. else
  54. SEARCH_PATTERN="Installed-Size"
  55. fi
  56. while IFS= read -r line; do
  57. if [ "$line" = "Package: $2" ]; then
  58. FOUND_PACKAGE=y
  59. fi
  60. if [ -n "$FOUND_PACKAGE" ]; then
  61. case $line in
  62. "$SEARCH_PATTERN"*)
  63. echo "$line" | cut -d ' ' -f 2
  64. break
  65. ;;
  66. esac
  67. fi
  68. done < "$1"
  69. }
  70. compare_sizes () {
  71. TOTAL_DIFF="0"
  72. for PACKAGE in $PACKAGES; do
  73. if [ "$PACKAGE" = "libc" ]; then
  74. continue
  75. fi
  76. PACKAGE_FILE=$(find "$BIN_DIR/packages/$ARCH/" \
  77. "$BIN_DIR/targets/$TARGET/$SUBTARGET/" \
  78. -name "${PACKAGE}_*.ipk" 2>/dev/null | head -n1)
  79. if [ -z "$PACKAGE_FILE" ]; then
  80. continue
  81. fi
  82. if [ -z "$CHECK_INSTALLED" ]; then
  83. SIZE_LOCAL=$(stat -c '%s' "$PACKAGE_FILE")
  84. else
  85. SIZE_LOCAL=$(tar tzvf "$PACKAGE_FILE" ./data.tar.gz | awk '{ print $3 }')
  86. fi
  87. SIZE_UPSTREAM=$(package_size "$TMP_INDEX" "$PACKAGE")
  88. SIZE_DIFF="$((SIZE_LOCAL - SIZE_UPSTREAM))"
  89. TOTAL_DIFF="$((TOTAL_DIFF + SIZE_DIFF))"
  90. if [ "$SIZE_DIFF" -gt 0 ]; then
  91. SIZE_DIFF="+$SIZE_DIFF"
  92. fi
  93. if [ -n "$SIZE_UPSTREAM" ]; then
  94. echo "${SIZE_DIFF} ${SIZE_LOCAL} ${SIZE_UPSTREAM} $PACKAGE"
  95. else
  96. echo "$PACKAGE is missing upstream"
  97. fi
  98. done
  99. echo "~~~~~~~ total change ${TOTAL_DIFF}"
  100. }
  101. if [ "$1" = "-h" ]; then
  102. help
  103. exit 0
  104. fi
  105. if [ "$1" = "-p" ]; then
  106. CHECK_INSTALLED=
  107. fi
  108. echo "Compare packages of $TARGET/$SUBTARGET/$ARCH":
  109. echo "$PACKAGES"
  110. echo
  111. echo "Checking configuration difference"
  112. TMP_CONFIG=$(mktemp /tmp/config.XXXXXX)
  113. sed -n 's/^ \+config \(.*\)/\1/p' config/Config-build.in config/Config-devel.in > "${TMP_CONFIG}-FOCUS"
  114. sort .config | grep -f "${TMP_CONFIG}-FOCUS" | grep -v "^#" | sort > "${TMP_CONFIG}-LOCAL"
  115. mv .config .config.bak
  116. "$DOWNLOAD_METHOD" "$CONFIG_URL" > .config
  117. make defconfig > /dev/null 2> /dev/null
  118. grep -f "${TMP_CONFIG}-FOCUS" .config | grep -v "^#" | sort > "${TMP_CONFIG}-UPSTREAM"
  119. mv .config.bak .config
  120. echo
  121. echo " --- start config diff ---"
  122. diff -u "${TMP_CONFIG}-LOCAL" "${TMP_CONFIG}-UPSTREAM"
  123. echo " --- end config diff ---"
  124. rm "${TMP_CONFIG}-FOCUS" "${TMP_CONFIG}-UPSTREAM" "${TMP_CONFIG}-LOCAL"
  125. echo
  126. if [ -z "$CHECK_INSTALLED" ]; then
  127. echo "Checking IPK package size"
  128. else
  129. echo "Checking installed size"
  130. fi
  131. echo
  132. echo "Fetching latest package indexes..."
  133. TMP_INDEX=$(mktemp /tmp/size_compare_package_index.XXXXXX)
  134. "$DOWNLOAD_METHOD" "$TARGET_URL" | gzip -d > "$TMP_INDEX" || exit 1
  135. "$DOWNLOAD_METHOD" "$PACKAGES_URL" | gzip -d >> "$TMP_INDEX" || exit 1
  136. echo
  137. echo "Comparing package sizes..."
  138. echo "Change Local Remote Package"
  139. compare_sizes | sort -g -r
  140. rm "$TMP_INDEX"