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