1#!/bin/bash 2# 3# Copyright (c) 2019, The OpenThread Authors. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of the copyright holder nor the 14# names of its contributors may be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30set -euo pipefail 31 32OT_TMP_DIR=/tmp/ot-size-report 33readonly OT_TMP_DIR 34 35OT_SHA_NEW=${GITHUB_SHA:-$(git rev-parse HEAD)} 36readonly OT_SHA_NEW 37 38OT_SHA_OLD="$(git cat-file -p "${OT_SHA_NEW}" | grep 'parent ' | head -n1 | cut -d' ' -f2)" 39readonly OT_SHA_OLD 40 41OT_REPORT_FILE_TABLE="${OT_TMP_DIR}/report_table" 42readonly OT_REPORT_FILE_TABLE 43 44OT_REPORT_FILE_PR="${OT_TMP_DIR}/report_pr" 45readonly OT_REPORT_FILE_TABLE 46 47OT_REPORTER="${OT_SIZE_REPORTER-}" 48readonly OT_REPORTER 49 50setup_arm_gcc_7() 51{ 52 if arm-none-eabi-gcc --version | grep -q 'Arm Embedded Processors 7'; then 53 return 0 54 fi 55 56 (cd /tmp/ \ 57 && wget --tries 4 --no-check-certificate --quiet https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2 \ 58 && tar xjf gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2) 59 export PATH=/tmp/gcc-arm-none-eabi-7-2018-q2-update/bin:$PATH 60 61 arm-none-eabi-gcc --version 62} 63 64setup_ninja_build() 65{ 66 sudo apt-get --no-install-recommends install -y ninja-build 67} 68 69setup() 70{ 71 setup_arm_gcc_7 72 setup_ninja_build 73} 74 75nm_size() 76{ 77 arm-none-eabi-nm --print-size --defined-only -C "$1" | cut -d' ' -f2- >nmsize_old 78 arm-none-eabi-nm --print-size --defined-only -C "$2" | cut -d' ' -f2- >nmsize_new 79 diff -Nuar nmsize_old nmsize_new || true 80} 81 82build_nrf52840() 83{ 84 case "$1" in 85 ftd) 86 local ot_ftd=ON 87 local ot_mtd=OFF 88 local ot_rcp=ON 89 ;; 90 mtd) 91 local ot_ftd=OFF 92 local ot_mtd=ON 93 local ot_rcp=ON 94 ;; 95 br) 96 local ot_ftd=ON 97 local ot_mtd=OFF 98 local ot_rcp=OFF 99 ;; 100 *) 101 exit 128 102 ;; 103 esac 104 105 case "$2" in 106 new) 107 local sha=${OT_SHA_NEW} 108 local clone_options=("clone") 109 ;; 110 old) 111 local sha=${OT_SHA_OLD} 112 local clone_options=("clone" "no-depend") 113 ;; 114 *) 115 exit 128 116 ;; 117 esac 118 119 local folder="$1_$2" 120 local config_name="ot-core-config-check-size-$1.h" 121 local config_file="../examples/config/${config_name}" 122 123 mkdir -p "${OT_TMP_DIR}/${folder}" 124 script/git-tool "${clone_options[@]}" https://github.com/openthread/ot-nrf528xx.git "${OT_TMP_DIR}/${folder}" 125 rm -rf "${OT_TMP_DIR}/${folder}/openthread/*" # replace openthread submodule with latest commit 126 git archive "${sha}" | tar x -C "${OT_TMP_DIR}/${folder}/openthread" 127 128 if [ ! -e "${OT_TMP_DIR}/${folder}/openthread/examples/config/${config_name}" ]; then 129 # Check if the the config headers are not present, copy from 130 # the main sha. 131 case "$1" in 132 br) 133 rm -rf "${OT_TMP_DIR}/${folder}/openthread/*" 134 git archive "${OT_SHA_NEW}" | tar x -C "${OT_TMP_DIR}/${folder}/openthread" 135 ;; 136 *) 137 mkdir -p "${OT_TMP_DIR}/${folder}/openthread/examples/config" 138 cp "./examples/config/${config_name}" "${OT_TMP_DIR}/${folder}/openthread/examples/config" 139 ;; 140 esac 141 fi 142 143 local cur_dir 144 145 cur_dir=$(pwd) 146 147 cd "${OT_TMP_DIR}/${folder}" 148 OT_CMAKE_BUILD_DIR=build script/build nrf52840 UART_trans \ 149 -DOT_APP_CLI=ON -DOT_APP_NCP=ON -DOT_APP_RCP=${ot_rcp} \ 150 -DOT_FTD=${ot_ftd} -DOT_MTD=${ot_mtd} -DOT_RCP=${ot_rcp} \ 151 -DBUILD_TESTING=OFF \ 152 -DOT_PROJECT_CONFIG="${config_file}" \ 153 "$@" 154 155 if [[ $1 == "br" ]]; then 156 mv ./build/bin/ot-cli-ftd ./build/bin/ot-cli-ftd-br 157 mv ./build/lib/libopenthread-ftd.a ./build/lib/libopenthread-ftd-br.a 158 mv ./build/lib/libopenthread-cli-ftd.a ./build/lib/libopenthread-cli-ftd-br.a 159 fi 160 161 cd "${cur_dir}" 162} 163 164generate_table_header() 165{ 166 { 167 printf "+----------------------------+----------+----------+----------+----------+----------+\n" 168 printf "| name | branch | text | data | bss | total |\n" 169 printf "+============================+==========+==========+==========+==========+==========+\n" 170 } >>"${OT_REPORT_FILE_TABLE}" 171 172 { 173 printf "# Size Report of **OpenThread**\n" 174 printf "Merging PR into main\n\n" 175 printf "| name | branch | text | data | bss | total |\n" 176 printf "| :----: | :------: | -----: | ----: | ---: | ----: |\n" 177 } >>"${OT_REPORT_FILE_PR}" 178 179 { 180 printf "\n<details><summary>Library files</summary>\n\n\n" 181 printf "| name | branch | text | data | bss | total |\n" 182 printf "| :----: | :------: | -----: | ----: | ---: | ----: |\n" 183 } >>"${OT_REPORT_FILE_PR}_libs" 184 185 if [ -n "${OT_REPORTER}" ]; then 186 "${OT_REPORTER}" init OpenThread 187 fi 188 189} 190 191generate_size_diff() 192{ 193 local name 194 local old_file 195 local new_file 196 197 old_file="$1" 198 new_file="$2" 199 200 name=$(basename "${old_file}") 201 202 case "${name}" in 203 lib*) 204 table_report_file="${OT_REPORT_FILE_TABLE}_libs" 205 pr_report_file="${OT_REPORT_FILE_PR}"_libs 206 ;; 207 *) 208 table_report_file="${OT_REPORT_FILE_TABLE}" 209 pr_report_file="${OT_REPORT_FILE_PR}" 210 ;; 211 esac 212 213 read -r -a size_old <<<"$(size "${old_file}" | awk '{text+=$1} {bss+=$2} {data+=$3} {total+=$4} END {printf "%d %d %d %d", text, bss, data, total}')" 214 read -r -a size_new <<<"$(size "${new_file}" | awk '{text+=$1} {bss+=$2} {data+=$3} {total+=$4} END {printf "%d %d %d %d", text, bss, data, total}')" 215 216 local -a size_diff 217 218 for i in 0 1 2 3; do 219 size_diff[i]="$((size_new[i] - size_old[i]))" 220 if [[ ${size_diff[i]} != 0 ]]; then 221 size_diff[i]=$(printf '%+d' "${size_diff[i]}") 222 fi 223 done 224 225 # Generate table format report 226 227 { 228 printf "| %-26s | %-8s " "${name}" "${OT_SHA_OLD:0:8}" 229 printf "| %8u | %8u | %8u | %8u |" "${size_old[0]}" "${size_old[1]}" "${size_old[2]}" "${size_old[3]}" 230 printf "\n" 231 232 printf "| %-26s | %-8s " "" "${OT_SHA_NEW:0:8}" 233 printf "| %8u | %8u | %8u | %8u |" "${size_new[0]}" "${size_new[1]}" "${size_new[2]}" "${size_new[3]}" 234 printf "\n" 235 236 printf "| %-26s | %-8s " "" "+/-" 237 printf "| %+8d | %+8d | %+8d | %+8d |" "${size_diff[0]}" "${size_diff[1]}" "${size_diff[2]}" "${size_diff[3]}" 238 printf "\n" >>"${table_report_file}" 239 240 printf "+----------------------------+----------+----------+----------+----------+----------+\n" 241 } >>"${table_report_file}" 242 243 # Generate PR post format report 244 245 { 246 printf "| %s | %s " "${name}" "${OT_SHA_OLD:0:8}" 247 printf "| %u | %u | %u | %u |" "${size_old[0]}" "${size_old[1]}" "${size_old[2]}" "${size_old[3]}" 248 printf "\n" 249 250 printf "| | %s " "${OT_SHA_NEW:0:8}" 251 printf "| %u | %u | %u | %u |" "${size_new[0]}" "${size_new[1]}" "${size_new[2]}" "${size_new[3]}" 252 printf "\n" 253 254 printf "| | %s " "+/-" 255 printf "| %+d | %+d | %+d | %+d |" "${size_diff[0]}" "${size_diff[1]}" "${size_diff[2]}" "${size_diff[3]}" 256 printf "\n" 257 } >>"${pr_report_file}" 258 259 if [ -n "${OT_REPORTER}" ]; then 260 "${OT_REPORTER}" size "${old_file}" "${new_file}" 261 fi 262} 263 264generate_report() 265{ 266 local type="${1}" 267 shift 268 269 local old_file 270 local new_file 271 272 for file in "$@"; do 273 case "${file}" in 274 lib*) 275 old_file="${OT_TMP_DIR}"/${type}_old/build/lib/"${file}" 276 new_file="${OT_TMP_DIR}"/${type}_new/build/lib/"${file}" 277 ;; 278 *) 279 old_file="${OT_TMP_DIR}"/${type}_old/build/bin/"${file}" 280 new_file="${OT_TMP_DIR}"/${type}_new/build/bin/"${file}" 281 ;; 282 esac 283 284 generate_size_diff "${old_file}" "${new_file}" 285 286 echo "nm_size ${old_file} ${new_file}" 287 nm_size "${old_file}" "${new_file}" 288 done 289} 290 291finalize_report() 292{ 293 cat "${OT_REPORT_FILE_TABLE}" 294 cat "${OT_REPORT_FILE_TABLE}_libs" 295 296 printf "</details>" >>${OT_REPORT_FILE_PR}_libs 297 cat "${OT_REPORT_FILE_PR}_libs" >>${OT_REPORT_FILE_PR} 298 299 if [ -n "${OT_REPORTER}" ]; then 300 "${OT_REPORTER}" post 301 fi 302} 303 304size_nrf52840() 305{ 306 export OT_SHA_NEW OT_SHA_OLD 307 308 rm -rf "${OT_TMP_DIR}" 309 mkdir -p "${OT_TMP_DIR}" 310 311 if [[ "${GITHUB_ACTIONS+x}" ]]; then 312 git fetch --depth 1 --no-recurse-submodules origin "${OT_SHA_OLD}" 313 fi 314 315 generate_table_header 316 317 build_nrf52840 ftd new "$@" 318 build_nrf52840 mtd new "$@" 319 build_nrf52840 br new "$@" 320 321 build_nrf52840 ftd old "$@" 322 build_nrf52840 mtd old "$@" 323 build_nrf52840 br old "$@" 324 325 local ftd_files=( 326 "ot-cli-ftd" 327 "ot-ncp-ftd" 328 "libopenthread-ftd.a" 329 "libopenthread-cli-ftd.a" 330 "libopenthread-ncp-ftd.a" 331 ) 332 333 local mtd_files=( 334 "ot-cli-mtd" 335 "ot-ncp-mtd" 336 "libopenthread-mtd.a" 337 "libopenthread-cli-mtd.a" 338 "libopenthread-ncp-mtd.a" 339 ) 340 341 local br_files=( 342 "ot-cli-ftd-br" 343 "libopenthread-ftd-br.a" 344 "libopenthread-cli-ftd-br.a" 345 ) 346 347 # `rcp`` is using same config as `ftd`. 348 local rcp_files=( 349 "ot-rcp" 350 "libopenthread-rcp.a" 351 "libopenthread-radio.a" 352 ) 353 354 generate_report ftd "${ftd_files[@]}" 355 generate_report mtd "${mtd_files[@]}" 356 generate_report br "${br_files[@]}" 357 generate_report ftd "${rcp_files[@]}" 358 359 finalize_report 360} 361 362main() 363{ 364 if [[ $# == 0 ]]; then 365 setup 366 size_nrf52840 367 cd 368 elif [[ $1 == setup ]]; then 369 setup 370 elif [[ $1 == nrf52840 ]]; then 371 shift 372 size_nrf52840 "$@" 373 else 374 echo "USAGE: $0 [setup | nrf52840 [CMAKE_OPTION ...]]" 375 exit 128 376 fi 377} 378 379main "$@" 380