blob: c50ade344d392e73d20f73fe4a3d5527013a4ef6 [file] [log] [blame]
#!/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}
;;
old)
local sha=${OT_SHA_OLD}
;;
*)
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 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 "$@"