1#!/bin/bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright(c) 2021 Intel Corporation. All rights reserved. 4 5# stop on most errors 6set -e 7 8SOF_TOP=$(cd "$(dirname "$0")" && cd .. && pwd) 9 10SUPPORTED_PLATFORMS=(apl cnl icl tgl-h) 11# Default value, can (and sometimes must) be overridden with -p 12WEST_TOP="${SOF_TOP}"/zephyrproject 13BUILD_JOBS=$(nproc --all) 14RIMAGE_KEY=modules/audio/sof/keys/otc_private_key.pem 15PLATFORMS=() 16 17die() 18{ 19 >&2 printf '%s ERROR: ' "$0" 20 # We want die() to be usable exactly like printf 21 # shellcheck disable=SC2059 22 >&2 printf "$@" 23 >&2 printf '\n' 24 exit 1 25} 26 27print_usage() 28{ 29 cat <<EOF 30Re-configures and re-builds SOF with Zephyr using a pre-installed Zephyr toolchain and 31the _defconfig file for that platform. 32 33usage: $0 [options] platform(s) 34 35 -a Build all platforms. 36 -j n Set number of make build jobs. Jobs=#cores by default. 37 Infinite when not specified. 38 -k Path to a non-default rimage signing key. 39 -c recursively clones Zephyr inside sof before building. 40 Incompatible with -p. 41 -p Existing Zephyr project directory. Incompatible with -c. If 42 zephyr-project/modules/audio/sof is missing then a 43 symbolic link pointing to ${SOF_TOP} will automatically be 44 created and west will recognize it as a new sof module. 45 This -p option is always _required_ if the real (not symbolic) 46 sof/ and zephyr-project/ directories are not nested in one 47 another. 48 49This script supports XtensaTools but only when installed in a specific 50directory structure, example: 51 52myXtensa/ 53└── install/ 54 ├── builds/ 55 │ ├── RD-2012.5-linux/ 56 │ │ └── Intel_HiFiEP/ 57 │ └── RG-2017.8-linux/ 58 │ ├── LX4_langwell_audio_17_8/ 59 │ └── X4H3I16w2D48w3a_2017_8/ 60 └── tools/ 61 ├── RD-2012.5-linux/ 62 │ └── XtensaTools/ 63 └── RG-2017.8-linux/ 64 └── XtensaTools/ 65 66$ XTENSA_TOOLS_ROOT=/path/to/myXtensa $0 ... 67 68Supported platforms ${SUPPORTED_PLATFORMS[*]} 69 70EOF 71} 72 73# Downloads zephyrproject inside sof/ and create a ../../.. symbolic 74# link back to sof/ 75clone() 76{ 77 type -p west || die "Install west and a west toolchain following https://docs.zephyrproject.org/latest/getting_started/index.html" 78 type -p git || die "Install git" 79 80 [ -e "$WEST_TOP" ] && die "$WEST_TOP already exists" 81 mkdir -p "$WEST_TOP" 82 git clone --depth=5 https://github.com/zephyrproject-rtos/zephyr \ 83 "$WEST_TOP"/zephyr 84 git -C "$WEST_TOP"/zephyr --no-pager log --oneline --graph \ 85 --decorate --max-count=20 86 west init -l "${WEST_TOP}"/zephyr 87 ( cd "${WEST_TOP}" 88 mkdir -p modules/audio 89 ln -s ../../.. modules/audio/sof 90 # Do NOT "west update sof"!! 91 west update zephyr hal_xtensa 92 ) 93} 94 95install_opts() 96{ 97 install -D -p "$@" 98} 99 100build() 101{ 102 cd "$WEST_TOP" 103 west topdir || { 104 printf 'SOF_TOP=%s\nWEST_TOP=%s\n' "$SOF_TOP" "$WEST_TOP" 105 die 'try the -p option?' 106 # Also note west can get confused by symbolic links, see 107 # https://github.com/zephyrproject-rtos/west/issues/419 108 } 109 110 local STAGING=build-sof-staging 111 mkdir -p ${STAGING}/sof/ # smex does not use 'install -D' 112 113 for platform in "${PLATFORMS[@]}"; do 114 case "$platform" in 115 apl) 116 PLAT_CONFIG='intel_adsp_cavs15' 117 # XCC build runs out of memory, tracked as 118 # https://github.com/thesofproject/sof/issues/4645 119 unset XTENSA_TOOLS_ROOT 120 #XTENSA_CORE="X4H3I16w2D48w3a_2017_8" 121 #XTENSA_TOOLS_VERSION="RG-2017.8-linux" 122 ;; 123 cnl) 124 PLAT_CONFIG='intel_adsp_cavs18' 125 XTENSA_CORE="X6H3CNL_2017_8" 126 XTENSA_TOOLS_VERSION="RG-2017.8-linux" 127 ;; 128 icl) 129 PLAT_CONFIG='intel_adsp_cavs20' 130 XTENSA_CORE="X6H3CNL_2017_8" 131 XTENSA_TOOLS_VERSION="RG-2017.8-linux" 132 ;; 133 tgl-h) 134 PLAT_CONFIG='intel_adsp_cavs25' 135 XTENSA_CORE="cavs2x_LX6HiFi3_2017_8" 136 XTENSA_TOOLS_VERSION="RG-2017.8-linux" 137 RIMAGE_KEY=modules/audio/sof/keys/otc_private_key_3k.pem 138 ;; 139 imx8) 140 PLAT_CONFIG='nxp_adsp_imx8' 141 RIMAGE_KEY='' # no key needed for imx8 142 ;; 143 *) 144 echo "Unsupported platform: $platform" 145 exit 1 146 ;; 147 esac 148 149 if [ -n "$XTENSA_TOOLS_ROOT" ] 150 then 151 # set variables expected by zephyr/cmake/toolchain/xcc/generic.cmake 152 export ZEPHYR_TOOLCHAIN_VARIANT=xcc 153 export XTENSA_TOOLCHAIN_PATH="$XTENSA_TOOLS_ROOT/install/tools" 154 export TOOLCHAIN_VER="$XTENSA_TOOLS_VERSION" 155 printf 'XTENSA_TOOLCHAIN_PATH=%s\n' "${XTENSA_TOOLCHAIN_PATH}" 156 printf 'TOOLCHAIN_VER=%s\n' "${TOOLCHAIN_VER}" 157 158 # set variables expected by xcc toolchain 159 XTENSA_BUILDS_DIR="$XTENSA_TOOLS_ROOT/install/builds/$XTENSA_TOOLS_VERSION" 160 export XTENSA_SYSTEM=$XTENSA_BUILDS_DIR/$XTENSA_CORE/config 161 printf 'XTENSA_SYSTEM=%s\n' "${XTENSA_SYSTEM}" 162 fi 163 164 local bdir=build-"$platform" 165 166 ( 167 # west can get lost in symbolic links and then 168 # show a confusing error. 169 /bin/pwd 170 set -x 171 west build --build-dir "$bdir" --board "$PLAT_CONFIG" \ 172 zephyr/samples/subsys/audio/sof 173 174 # This should ideally be part of 175 # sof/zephyr/CMakeLists.txt but due to the way 176 # Zephyr works, the SOF library build there does 177 # not seem like it can go further than a 178 # "libmodules_sof.a" file that smex does not 179 # know how to use. 180 "$bdir"/zephyr/smex_ep/build/smex \ 181 -l "$STAGING"/sof/sof-"$platform".ldc \ 182 "$bdir"/zephyr/zephyr.elf 183 184 # Build rimage 185 RIMAGE_DIR=build-rimage 186 cmake -B "$RIMAGE_DIR" -S modules/audio/sof/rimage 187 make -C "$RIMAGE_DIR" -j"$BUILD_JOBS" 188 189 west sign --build-dir "$bdir" \ 190 --tool rimage --tool-path "$RIMAGE_DIR"/rimage \ 191 --tool-data modules/audio/sof/rimage/config -- -k "$RIMAGE_KEY" 192 ) 193 install_opts -m 0644 "$bdir"/zephyr/zephyr.ri \ 194 "$STAGING"/sof/community/sof-"$platform".ri 195 done 196 197 install_opts -m 0755 "$bdir"/zephyr/sof-logger_ep/build/logger/sof-logger \ 198 "$STAGING"/tools/sof-logger 199 200 tree "$STAGING" 201} 202 203main() 204{ 205 local zeproj 206 207 # parse the args 208 while getopts "acj:k:p:" OPTION; do 209 case "$OPTION" in 210 a) PLATFORMS=("${SUPPORTED_PLATFORMS[@]}") ;; 211 c) DO_CLONE=yes ;; 212 j) BUILD_JOBS="$OPTARG" ;; 213 k) RIMAGE_KEY="$OPTARG" ;; 214 p) zeproj="$OPTARG" ;; 215 *) print_usage; exit 1 ;; 216 esac 217 done 218 shift $((OPTIND-1)) 219 220 if [ -n "$zeproj" ] && [ x"$DO_CLONE" = xyes ]; then 221 die 'Cannot use -p with -c, -c supports %s only' "${WEST_TOP}" 222 fi 223 224 if [ -n "$zeproj" ]; then 225 226 [ -d "$zeproj" ] || 227 die "$zeproj is not a directory, try -c instead of -p?" 228 229 ( cd "$zeproj" 230 test "$(realpath "$(west topdir)")" = "$(/bin/pwd)" 231 ) || die '%s is not a zephyrproject' "$WEST_TOP" 232 233 WEST_TOP="$zeproj" 234 fi 235 236 # parse platform args 237 for arg in "$@"; do 238 platform=none 239 for i in "${SUPPORTED_PLATFORMS[@]}"; do 240 if [ x"$i" = x"$arg" ]; then 241 PLATFORMS=("${PLATFORMS[@]}" "$i") 242 platform="$i" 243 shift || true 244 break 245 fi 246 done 247 if [ "$platform" == "none" ]; then 248 echo "Error: Unknown platform specified: $arg" 249 echo "Supported platforms are: ${SUPPORTED_PLATFORMS[*]}" 250 exit 1 251 fi 252 done 253 254 # check target platform(s) have been passed in 255 if [ "${#PLATFORMS[@]}" -eq 0 ]; then 256 echo "Error: No platforms specified. Supported are: " \ 257 "${SUPPORTED_PLATFORMS[*]}" 258 print_usage 259 exit 1 260 fi 261 262 if [ "x$DO_CLONE" == "xyes" ]; then 263 clone 264 else 265 # Symlink zephyr-project to our SOF selves if no sof west module yet 266 test -e "${WEST_TOP}"/modules/audio/sof || { 267 mkdir -p "${WEST_TOP}"/modules/audio 268 ln -s "$SOF_TOP" "${WEST_TOP}"/modules/audio/sof 269 } 270 271 # FIXME: remove this hack. Downloading and building 272 # should be kept separate but support for submodules in 273 # west is too recent, cannot rely on it yet. 274 test -e "${WEST_TOP}"/modules/audio/sof/rimage/CMakeLists.txt || ( 275 cd "${WEST_TOP}"/modules/audio/sof 276 git submodule update --init --recursive 277 ) 278 fi 279 280 build 281} 282 283main "$@" 284