| #!/bin/bash | |
| # | |
| # Copyright (c) 2019, The OpenThread Authors. | |
| # All rights reserved. | |
| # | |
| # Redistribution and use in source and binary forms, with or without | |
| # modification, are permitted provided that the following conditions are met: | |
| # 1. Redistributions of source code must retain the above copyright | |
| # notice, this list of conditions and the following disclaimer. | |
| # 2. Redistributions in binary form must reproduce the above copyright | |
| # notice, this list of conditions and the following disclaimer in the | |
| # documentation and/or other materials provided with the distribution. | |
| # 3. Neither the name of the copyright holder nor the | |
| # names of its contributors may be used to endorse or promote products | |
| # derived from this software without specific prior written permission. | |
| # | |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
| # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| # POSSIBILITY OF SUCH DAMAGE. | |
| # | |
| set -euo pipefail | |
| OT_TMP_DIR=/tmp/ot-size-report | |
| readonly OT_TMP_DIR | |
| OT_SHA_NEW=${GITHUB_SHA:-$(git rev-parse HEAD)} | |
| readonly OT_SHA_NEW | |
| OT_SHA_OLD="$(git cat-file -p "${OT_SHA_NEW}" | grep 'parent ' | head -n1 | cut -d' ' -f2)" | |
| readonly OT_SHA_OLD | |
| OT_REPORT_FILE_TABLE="${OT_TMP_DIR}/report_table" | |
| readonly OT_REPORT_FILE_TABLE | |
| OT_REPORT_FILE_PR="${OT_TMP_DIR}/report_pr" | |
| readonly OT_REPORT_FILE_TABLE | |
| OT_REPORTER="${OT_SIZE_REPORTER-}" | |
| readonly OT_REPORTER | |
| setup_arm_gcc_7() | |
| { | |
| if arm-none-eabi-gcc --version | grep -q 'Arm Embedded Processors 7'; then | |
| return 0 | |
| fi | |
| (cd /tmp/ \ | |
| && 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 \ | |
| && tar xjf gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2) | |
| export PATH=/tmp/gcc-arm-none-eabi-7-2018-q2-update/bin:$PATH | |
| arm-none-eabi-gcc --version | |
| } | |
| setup_ninja_build() | |
| { | |
| sudo apt-get --no-install-recommends install -y ninja-build | |
| } | |
| setup() | |
| { | |
| setup_arm_gcc_7 | |
| setup_ninja_build | |
| } | |
| nm_size() | |
| { | |
| arm-none-eabi-nm --print-size --defined-only -C "$1" | cut -d' ' -f2- >nmsize_old | |
| arm-none-eabi-nm --print-size --defined-only -C "$2" | cut -d' ' -f2- >nmsize_new | |
| diff -Nuar nmsize_old nmsize_new || true | |
| } | |
| build_nrf52840() | |
| { | |
| case "$1" in | |
| ftd) | |
| local ot_ftd=ON | |
| local ot_mtd=OFF | |
| local ot_rcp=ON | |
| ;; | |
| mtd) | |
| local ot_ftd=OFF | |
| local ot_mtd=ON | |
| local ot_rcp=ON | |
| ;; | |
| br) | |
| local ot_ftd=ON | |
| local ot_mtd=OFF | |
| local ot_rcp=OFF | |
| ;; | |
| *) | |
| exit 128 | |
| ;; | |
| esac | |
| case "$2" in | |
| new) | |
| local sha=${OT_SHA_NEW} | |
| local clone_options=("clone") | |
| ;; | |
| old) | |
| local sha=${OT_SHA_OLD} | |
| local clone_options=("clone" "no-depend") | |
| ;; | |
| *) | |
| exit 128 | |
| ;; | |
| esac | |
| local folder="$1_$2" | |
| local config_name="ot-core-config-check-size-$1.h" | |
| local config_file="../examples/config/${config_name}" | |
| mkdir -p "${OT_TMP_DIR}/${folder}" | |
| script/git-tool "${clone_options[@]}" https://github.com/openthread/ot-nrf528xx.git "${OT_TMP_DIR}/${folder}" | |
| rm -rf "${OT_TMP_DIR}/${folder}/openthread/*" # replace openthread submodule with latest commit | |
| git archive "${sha}" | tar x -C "${OT_TMP_DIR}/${folder}/openthread" | |
| if [ ! -e "${OT_TMP_DIR}/${folder}/openthread/examples/config/${config_name}" ]; then | |
| # Check if the the config headers are not present, copy from | |
| # the main sha. | |
| case "$1" in | |
| br) | |
| rm -rf "${OT_TMP_DIR}/${folder}/openthread/*" | |
| git archive "${OT_SHA_NEW}" | tar x -C "${OT_TMP_DIR}/${folder}/openthread" | |
| ;; | |
| *) | |
| mkdir -p "${OT_TMP_DIR}/${folder}/openthread/examples/config" | |
| cp "./examples/config/${config_name}" "${OT_TMP_DIR}/${folder}/openthread/examples/config" | |
| ;; | |
| esac | |
| fi | |
| local cur_dir | |
| cur_dir=$(pwd) | |
| cd "${OT_TMP_DIR}/${folder}" | |
| OT_CMAKE_BUILD_DIR=build script/build nrf52840 UART_trans \ | |
| -DOT_APP_CLI=ON -DOT_APP_NCP=ON -DOT_APP_RCP=${ot_rcp} \ | |
| -DOT_FTD=${ot_ftd} -DOT_MTD=${ot_mtd} -DOT_RCP=${ot_rcp} \ | |
| -DBUILD_TESTING=OFF \ | |
| -DOT_PROJECT_CONFIG="${config_file}" | |
| if [[ $1 == "br" ]]; then | |
| mv ./build/bin/ot-cli-ftd ./build/bin/ot-cli-ftd-br | |
| mv ./build/lib/libopenthread-ftd.a ./build/lib/libopenthread-ftd-br.a | |
| mv ./build/lib/libopenthread-cli-ftd.a ./build/lib/libopenthread-cli-ftd-br.a | |
| fi | |
| cd "${cur_dir}" | |
| } | |
| generate_table_header() | |
| { | |
| { | |
| printf "+----------------------------+----------+----------+----------+----------+----------+\n" | |
| printf "| name | branch | text | data | bss | total |\n" | |
| printf "+============================+==========+==========+==========+==========+==========+\n" | |
| } >>"${OT_REPORT_FILE_TABLE}" | |
| { | |
| printf "# Size Report of **OpenThread**\n" | |
| printf "Merging PR into main\n\n" | |
| printf "| name | branch | text | data | bss | total |\n" | |
| printf "| :----: | :------: | -----: | ----: | ---: | ----: |\n" | |
| } >>"${OT_REPORT_FILE_PR}" | |
| { | |
| printf "\n<details><summary>Library files</summary>\n\n\n" | |
| printf "| name | branch | text | data | bss | total |\n" | |
| printf "| :----: | :------: | -----: | ----: | ---: | ----: |\n" | |
| } >>"${OT_REPORT_FILE_PR}_libs" | |
| if [ -n "${OT_REPORTER}" ]; then | |
| "${OT_REPORTER}" init OpenThread | |
| fi | |
| } | |
| generate_size_diff() | |
| { | |
| local name | |
| local old_file | |
| local new_file | |
| old_file="$1" | |
| new_file="$2" | |
| name=$(basename "${old_file}") | |
| case "${name}" in | |
| lib*) | |
| table_report_file="${OT_REPORT_FILE_TABLE}_libs" | |
| pr_report_file="${OT_REPORT_FILE_PR}"_libs | |
| ;; | |
| *) | |
| table_report_file="${OT_REPORT_FILE_TABLE}" | |
| pr_report_file="${OT_REPORT_FILE_PR}" | |
| ;; | |
| esac | |
| 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}')" | |
| 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}')" | |
| local -a size_diff | |
| for i in 0 1 2 3; do | |
| size_diff[$i]="$((size_new["$i"] - size_old["$i"]))" | |
| if [[ ${size_diff["$i"]} != 0 ]]; then | |
| size_diff["$i"]=$(printf '%+d' "${size_diff["$i"]}") | |
| fi | |
| done | |
| # Generate table format report | |
| { | |
| printf "| %-26s | %-8s " "${name}" "${OT_SHA_OLD:0:8}" | |
| printf "| %8u | %8u | %8u | %8u |" "${size_old[0]}" "${size_old[1]}" "${size_old[2]}" "${size_old[3]}" | |
| printf "\n" | |
| printf "| %-26s | %-8s " "" "${OT_SHA_NEW:0:8}" | |
| printf "| %8u | %8u | %8u | %8u |" "${size_new[0]}" "${size_new[1]}" "${size_new[2]}" "${size_new[3]}" | |
| printf "\n" | |
| printf "| %-26s | %-8s " "" "+/-" | |
| printf "| %+8d | %+8d | %+8d | %+8d |" "${size_diff[0]}" "${size_diff[1]}" "${size_diff[2]}" "${size_diff[3]}" | |
| printf "\n" >>"${table_report_file}" | |
| printf "+----------------------------+----------+----------+----------+----------+----------+\n" | |
| } >>"${table_report_file}" | |
| # Generate PR post format report | |
| { | |
| printf "| %s | %s " "${name}" "${OT_SHA_OLD:0:8}" | |
| printf "| %u | %u | %u | %u |" "${size_old[0]}" "${size_old[1]}" "${size_old[2]}" "${size_old[3]}" | |
| printf "\n" | |
| printf "| | %s " "${OT_SHA_NEW:0:8}" | |
| printf "| %u | %u | %u | %u |" "${size_new[0]}" "${size_new[1]}" "${size_new[2]}" "${size_new[3]}" | |
| printf "\n" | |
| printf "| | %s " "+/-" | |
| printf "| %+d | %+d | %+d | %+d |" "${size_diff[0]}" "${size_diff[1]}" "${size_diff[2]}" "${size_diff[3]}" | |
| printf "\n" | |
| } >>"${pr_report_file}" | |
| if [ -n "${OT_REPORTER}" ]; then | |
| "${OT_REPORTER}" size "${old_file}" "${new_file}" | |
| fi | |
| } | |
| generate_report() | |
| { | |
| local type="${1}" | |
| shift | |
| local old_file | |
| local new_file | |
| for file in "$@"; do | |
| case "${file}" in | |
| lib*) | |
| old_file="${OT_TMP_DIR}"/${type}_old/build/lib/"${file}" | |
| new_file="${OT_TMP_DIR}"/${type}_new/build/lib/"${file}" | |
| ;; | |
| *) | |
| old_file="${OT_TMP_DIR}"/${type}_old/build/bin/"${file}" | |
| new_file="${OT_TMP_DIR}"/${type}_new/build/bin/"${file}" | |
| ;; | |
| esac | |
| generate_size_diff "${old_file}" "${new_file}" | |
| echo "nm_size ${old_file} ${new_file}" | |
| nm_size "${old_file}" "${new_file}" | |
| done | |
| } | |
| finalize_report() | |
| { | |
| cat "${OT_REPORT_FILE_TABLE}" | |
| cat "${OT_REPORT_FILE_TABLE}_libs" | |
| printf "</details>" >>${OT_REPORT_FILE_PR}_libs | |
| cat "${OT_REPORT_FILE_PR}_libs" >>${OT_REPORT_FILE_PR} | |
| if [ -n "${OT_REPORTER}" ]; then | |
| "${OT_REPORTER}" post | |
| fi | |
| } | |
| size_nrf52840() | |
| { | |
| export OT_SHA_NEW OT_SHA_OLD | |
| rm -rf "${OT_TMP_DIR}" | |
| mkdir -p "${OT_TMP_DIR}" | |
| if [[ "${GITHUB_ACTIONS+x}" ]]; then | |
| git fetch --depth 1 --no-recurse-submodules origin "${OT_SHA_OLD}" | |
| fi | |
| generate_table_header | |
| build_nrf52840 ftd new | |
| build_nrf52840 mtd new | |
| build_nrf52840 br new | |
| build_nrf52840 ftd old | |
| build_nrf52840 mtd old | |
| build_nrf52840 br old | |
| local ftd_files=( | |
| "ot-cli-ftd" | |
| "ot-ncp-ftd" | |
| "libopenthread-ftd.a" | |
| "libopenthread-cli-ftd.a" | |
| "libopenthread-ncp-ftd.a" | |
| ) | |
| local mtd_files=( | |
| "ot-cli-mtd" | |
| "ot-ncp-mtd" | |
| "libopenthread-mtd.a" | |
| "libopenthread-cli-mtd.a" | |
| "libopenthread-ncp-mtd.a" | |
| ) | |
| local br_files=( | |
| "ot-cli-ftd-br" | |
| "libopenthread-ftd-br.a" | |
| "libopenthread-cli-ftd-br.a" | |
| ) | |
| # `rcp`` is using same config as `ftd`. | |
| local rcp_files=( | |
| "ot-rcp" | |
| "libopenthread-rcp.a" | |
| "libopenthread-radio.a" | |
| ) | |
| generate_report ftd "${ftd_files[@]}" | |
| generate_report mtd "${mtd_files[@]}" | |
| generate_report br "${br_files[@]}" | |
| generate_report ftd "${rcp_files[@]}" | |
| finalize_report | |
| } | |
| main() | |
| { | |
| if [[ $# == 0 ]]; then | |
| setup | |
| size_nrf52840 | |
| cd | |
| elif [[ $1 == setup ]]; then | |
| setup | |
| elif [[ $1 == nrf52840 ]]; then | |
| size_nrf52840 | |
| else | |
| echo "USAGE: $0 [setup|nrf52840]" | |
| exit 128 | |
| fi | |
| } | |
| main "$@" |