diff --git a/config/functions b/config/functions index 78d4b41f8d..afd0a72f3b 100644 --- a/config/functions +++ b/config/functions @@ -1216,6 +1216,7 @@ pkg_lock() { local pkg="$1" task="$2" parent_pkg="$3" local this_job="${MTJOBID}" local lock_job lock_task lock_pkg + local fail_seq exec 98>"${THREAD_CONTROL}/locks/${pkg}.${task}" if ! flock --nonblock --exclusive 98; then @@ -1229,6 +1230,23 @@ pkg_lock() { flock --exclusive 98 fi fi + + # As we now have the lock, if .failed still exists then a previous process must have failed + if [ -f "${THREAD_CONTROL}/locks/${pkg}.${task}.failed" ]; then + fail_seq="$(cat "${THREAD_CONTROL}/locks/${pkg}.${task}.failed")" + print_color CLR_ERROR "FAILURE: ${pkg}.${task}.failed exists, a previous dependency process has failed (seq: ${fail_seq})\n" + if [ -d "${THREAD_CONTROL}/logs" ]; then +cat <"${THREAD_CONTROL}/locks/${pkg}.${task}.owner" pkg_lock_status "LOCKED" "${pkg}" "${task}" @@ -1248,6 +1266,14 @@ pkg_lock_status() { echo "${line}" >>"${THREAD_CONTROL}/history" [ "${DASHBOARD}" != "no" ] && update_dashboard "${status}" "${pkg}" "${task}" "${msg}" + + if [ "${status}" = "LOCKED" ]; then + echo "${PARALLEL_SEQ}" > "${THREAD_CONTROL}/locks/${pkg}.${task}.failed" + elif [ "${status}" = "UNLOCK" ]; then + rm "${THREAD_CONTROL}/locks/${pkg}.${task}.failed" + fi + + return 0 } update_dashboard() { @@ -1304,14 +1330,14 @@ update_dashboard() { acquire_exclusive_lock() { [ "${MTWITHLOCKS}" != "yes" ] && return 0 - local pkg="$1" task="$2" lockfile="${3:-.global}" + local pkg="$1" task="$2" lockfile="${3:-global}" local this_job="${MTJOBID}" local lock_job lock_task lock_pkg - exec 96>"${THREAD_CONTROL}/locks/${lockfile}" + exec 96>"${THREAD_CONTROL}/locks/.mutex.${lockfile}" if ! flock --nonblock --exclusive 96; then while [ : ]; do - read -r lock_job lock_task lock_pkg <<<$(cat "${THREAD_CONTROL}/locks/${lockfile}.owner" 2>/dev/null) + read -r lock_job lock_task lock_pkg <<<$(cat "${THREAD_CONTROL}/locks/.mutex.${lockfile}.owner" 2>/dev/null) [ -n "${lock_job}" ] && break || sleep 1 done @@ -1320,7 +1346,7 @@ acquire_exclusive_lock() { flock --exclusive 96 fi fi - echo "${this_job} ${task} ${pkg}" >"${THREAD_CONTROL}/locks/${lockfile}.owner" + echo "${this_job} ${task} ${pkg}" >"${THREAD_CONTROL}/locks/.mutex.${lockfile}.owner" pkg_lock_status "MUTEX" "${pkg}" "${task}" "mutex: ${lockfile}" } diff --git a/config/multithread b/config/multithread index 35cf4d6c77..2ffa4c6dda 100644 --- a/config/multithread +++ b/config/multithread @@ -53,26 +53,68 @@ export -f json_worker package_worker() { local slot=$1 job=$2 jobs=$3 args="$4" local task pkgname result status - - . config/options "" - - [ -f "${THREAD_CONTROL}/pid" ] || echo "${PARALLEL_PID}" >"${THREAD_CONTROL}/pid" + local addon istarget export MTJOBID=${slot} MTMAXJOBS=${jobs} - read -r task pkgname <<<$(echo "${args}") + read -r task pkgname <<< "${args}" + + . config/options "${pkgname}" + + [ ! -f "${THREAD_CONTROL}/pid" ] && echo "${PARALLEL_PID}" >"${THREAD_CONTROL}/pid" ${SCRIPTS}/${task} ${pkgname} 2>&1 && result=0 || result=1 - [ ${result} -eq 0 ] && status="DONE" || status="FAIL" + [[ ${pkgname} =~ :target$ || "${pkgname//:/}" = "${pkgname}" ]] && istarget="yes" || istarget="no" + + if [ "${MTADDONBUILD}" = "yes" -a "${PKG_IS_ADDON}" = "yes" -a "${istarget}" = "yes" ]; then + if [ ${result} -eq 0 ]; then + ( + pkg_lock "${pkgname}" "packadd" + pkg_lock_status "ACTIVE" "${pkgname}" "packadd" + + # cleanup old install path + rm -rf "${ADDON_BUILD}" + + # install addon parts + if pkg_call_exists addon; then + pkg_call addon + else + install_binary_addon "${PKG_ADDON_ID}" + fi + + # HACK for packages that provide multiple addons like screensavers.rsxs + # addon's addon() in package.mk should take care for exporting + # MULTI_ADDONS="addon.boo1 addon.boo2 addon.boo3" + if [ -n "${MULTI_ADDONS}" ] ; then + for addon in ${MULTI_ADDONS}; do + ${SCRIPTS}/install_addon "${PKG_NAME}" "${addon}" + done + else + ${SCRIPTS}/install_addon "${PKG_NAME}" "${PKG_ADDON_ID}" + fi + + pkg_lock_status "UNLOCK" "${pkgname}" "packadd" "packed" + ) 2>&1 || result=1 + fi + + if [ ${result} -ne 0 ]; then + if [ -d "${THREAD_CONTROL}/logs" ]; then + echo "${PKG_NAME} ${THREAD_CONTROL}/logs/${job}/stdout" >>"${THREAD_CONTROL}/addons.failed" + else + echo "${PKG_NAME}" >>"${THREAD_CONTROL}/addons.failed" + fi + fi + fi ( flock --exclusive 95 + [ ${result} -eq 0 ] && status="DONE" || status="FAIL" num=$(($(cat "${THREAD_CONTROL}/progress") + 1)) mv "${THREAD_CONTROL}/progress" "${THREAD_CONTROL}/progress.prev" echo ${num} >"${THREAD_CONTROL}/progress" printf "[%0*d/%0*d] [%-4s] %-7s %s\n" ${#jobs} ${num} ${#jobs} ${jobs} "${status}" "${task}" "${pkgname}" >&2 - ) 95>"${THREAD_CONTROL}/progress.lock" + ) 95>"${THREAD_CONTROL}/locks/.progress" if [ ${result} -eq 0 ]; then pkg_lock_status "IDLE" @@ -97,7 +139,7 @@ EOF export -f package_worker start_multithread_build() { - local logbuffer withlocks + local singlethread buildopts # init thread control folder rm -fr "${THREAD_CONTROL}" @@ -112,16 +154,19 @@ start_multithread_build() { $SCRIPTS/build parallel:host 2>&1 || die "Unable to bootstrap parallel package" # if number of detected slots is 1 then don't bother using inter-process locks as this is a sequential build - [ $(seq 1 32 | ${TOOLCHAIN}/bin/parallel --plain --no-notice --max-procs ${THREADCOUNT} echo {%} | sort -n | tail -1) -eq 1 ] && withlocks=no || withlocks=yes + [ $(seq 1 32 | ${TOOLCHAIN}/bin/parallel --plain --no-notice --max-procs ${THREADCOUNT} echo {%} | sort -n | tail -1) -eq 1 ] && singlethread=yes || singlethread=no # create a single log file by default if not using locks (single build process), or the builder is a masochist - if [ "${withlocks}" = "no" -a "${ONELOG,,}" != "no" ] || [ "${ONELOG,,}" = "yes" ]; then - logbuffer="--ungroup" + if [ "${singlethread}" = "yes" -a "${ONELOG,,}" != "no" ] || [ "${ONELOG,,}" = "yes" ]; then + buildopts+=" --ungroup" else mkdir -p "${THREAD_CONTROL}/logs" - logbuffer="--group --results ${THREAD_CONTROL}/logs/{#}/" + buildopts+=" --group --results ${THREAD_CONTROL}/logs/{#}/" fi + # When building addons, don't halt on error - keep building all packages/addons + [ "${MTADDONBUILD}" = "yes" ] && buildopts+=" --halt never" || buildopts+=" --halt now,fail=1" + # pipefail: return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status set -o pipefail @@ -130,8 +175,8 @@ start_multithread_build() { ${SCRIPTS}/genbuildplan.py --no-reorder --show-wants --build ${@} > "${THREAD_CONTROL}"/plan || return cat "${THREAD_CONTROL}"/plan | awk '{print $1 " " $2}' | \ - MTBUILDSTART=$(date +%s) MTWITHLOCKS=${withlocks} ${TOOLCHAIN}/bin/parallel \ - --plain --no-notice --max-procs ${THREADCOUNT} --joblog="${THREAD_CONTROL}/joblog" ${logbuffer} --halt now,fail=1 --plus \ + MTBUILDSTART=$(date +%s) MTWITHLOCKS=yes ${TOOLCHAIN}/bin/parallel \ + --plain --no-notice --max-procs ${THREADCOUNT} --joblog="${THREAD_CONTROL}/joblog" --plus ${buildopts} \ package_worker {%} {#} {##} {} || return set +o pipefail diff --git a/scripts/create_addon b/scripts/create_addon index 64588696d7..f2e75d6505 100755 --- a/scripts/create_addon +++ b/scripts/create_addon @@ -102,69 +102,6 @@ function find_addons() { echo $_addons } -pack_addon() { - scripts/install_addon $PKG_NAME $PKG_ADDON_ID || exit - - if [ "$2" != "-test" ] ; then - ADDON_INSTALL_DIR="$TARGET_IMG/$ADDONS/$ADDON_VERSION/${DEVICE:-$PROJECT}/$TARGET_ARCH/$PKG_ADDON_ID" - ADDONVER="$(xmlstarlet sel -t -v "/addon/@version" $ADDON_BUILD/$PKG_ADDON_ID/addon.xml)" - - if [ -f $ADDON_INSTALL_DIR/$PKG_ADDON_ID-$ADDONVER.zip ]; then - if [ "$ADDON_OVERWRITE" = "yes" ]; then - rm $ADDON_INSTALL_DIR/$PKG_ADDON_ID-$ADDONVER.zip - else - build_msg "CLR_WARNING" "*** WARNING: ${PKG_ADDON_ID}-${ADDONVER}.zip already exists. Not overwrittng it. ***" - return 0 - fi - fi - cd $ADDON_BUILD - build_msg "CLR_INFO" "*** compressing addon ${PKG_ADDON_ID} ... ***" - $TOOLCHAIN/bin/7za a -l -mx9 -bsp0 -bso0 -tzip $PKG_ADDON_ID-$ADDONVER.zip $PKG_ADDON_ID - cd - &>/dev/null - - mkdir -p $ADDON_INSTALL_DIR - cp $ADDON_BUILD/$PKG_ADDON_ID-$ADDONVER.zip $ADDON_INSTALL_DIR - if [ -f $ADDON_BUILD/$PKG_ADDON_ID/changelog.txt ]; then - cp $ADDON_BUILD/$PKG_ADDON_ID/changelog.txt $ADDON_INSTALL_DIR/changelog-$ADDONVER.txt - fi - if [ -f $ADDON_BUILD/$PKG_ADDON_ID/resources/icon.png ]; then - mkdir -p $ADDON_INSTALL_DIR/resources - cp $ADDON_BUILD/$PKG_ADDON_ID/resources/icon.png $ADDON_INSTALL_DIR/resources/icon.png - fi - - # workaround for kodi pvr addons - if [ -f $ADDON_BUILD/$PKG_ADDON_ID/icon.png ]; then - cp $ADDON_BUILD/$PKG_ADDON_ID/icon.png $ADDON_INSTALL_DIR/icon.png - fi - - if [ -f $ADDON_BUILD/$PKG_ADDON_ID/resources/fanart.png ]; then - mkdir -p $ADDON_INSTALL_DIR/resources - cp $ADDON_BUILD/$PKG_ADDON_ID/resources/fanart.png $ADDON_INSTALL_DIR/resources/fanart.png - fi - for f in $ADDON_BUILD/$PKG_ADDON_ID/resources/screenshot-*.{jpg,png}; do - if [ -f "$f" ]; then - mkdir -p $ADDON_INSTALL_DIR/resources - cp $f $ADDON_INSTALL_DIR/resources - fi - done - - # Jenkins add-on build - if [ "$ADDON_JENKINS" = "yes" ]; then - ADDON_JENKINS_DIR="$TARGET_IMG/jenkins" - ADDON_JENKINS_ADDON_NAME="$ADDON_VERSION-${DEVICE:-$PROJECT}-$TARGET_ARCH-$PKG_ADDON_ID-$ADDONVER" - mkdir -p "$ADDON_JENKINS_DIR" - cd $ADDON_INSTALL_DIR - $TOOLCHAIN/bin/7za a -l -mx0 -bsp0 -bso0 -tzip $ADDON_JENKINS_DIR/$ADDON_JENKINS_ADDON_NAME.zip $PKG_ADDON_ID-$ADDONVER.zip resources/ - ( cd $ADDON_JENKINS_DIR - sha256sum $ADDON_JENKINS_ADDON_NAME.zip > $ADDON_JENKINS_ADDON_NAME.zip.sha256 - ) - build_msg "CLR_INFO" "*** creating ${ADDON_JENKINS_ADDON_NAME}.zip for Jenkins complete ***" - else - build_msg "CLR_INFO" "*** creating ${PKG_ADDON_ID} complete ***" - fi - fi -} - not_supported_arch() { build_msg "CLR_WARNING" "*** SKIP: ${PKG_ADDON_ID} '${TARGET_ARCH}' not supported ***" exit 0 @@ -220,10 +157,10 @@ build_addon() { if [ -n "$MULTI_ADDONS" ] ; then for _ADDON in $MULTI_ADDONS ; do PKG_ADDON_ID=$_ADDON - pack_addon + ${SCRIPTS}/install_addon $PKG_NAME $PKG_ADDON_ID done else - pack_addon + ${SCRIPTS}/install_addon $PKG_NAME $PKG_ADDON_ID fi } diff --git a/scripts/create_addon_mt b/scripts/create_addon_mt new file mode 100755 index 0000000000..2388dab05f --- /dev/null +++ b/scripts/create_addon_mt @@ -0,0 +1,184 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) + +. config/options "" +. config/multithread + +usage() { + cat - >&2 < ./script/create_addon_mt all + + build audio encoders and decoders, only + > ./script/create_addon_mt audioencoder.* audiodecoder.* + + build all, but not binary + > ./script/create_addon_mt all -binary +EOF + exit ${1:-0} +} + +# Get list of addon packages +get_addons() { + local paths filter + local pkgpath exited + local count=0 validpkg + + case $1 in + binary) paths="^$ROOT/packages/mediacenter/kodi-binary-addons/";; + official) paths="^$ROOT/packages/addons/";; + all) paths="^$ROOT/packages/|^$ROOT/projects/.*/packages/";; + *) paths="^$ROOT/packages/|^$ROOT/projects/.*/packages/"; filter="$1";; + esac + + exit() { exited=1; } + + for pkgpath in $(cat "${_CACHE_PACKAGE_LOCAL}" "${_CACHE_PACKAGE_GLOBAL}" | grep -E "${paths}"); do + if [ -n "${filter}" ]; then + [[ ${pkgpath} =~ ^.*/${filter}@?+?@ ]] || continue + fi + + exited=0 + source_package "${pkgpath%%@*}/package.mk" &>/dev/null + [ ${exited} -eq 1 ] && continue + + validpkg="no" + # Should only build embedded addons when they are explictly specified in the addon list + if [ "${PKG_IS_ADDON}" = "embedded" ]; then + if [ -n "${filter}" ]; then + verify_addon && validpkg="yes" + fi + elif [ "${PKG_IS_ADDON}" = "yes" ]; then + verify_addon && validpkg="yes" + fi + + if [ "${validpkg}" = "yes" ]; then + echo "${PKG_NAME}" + count=$((count + 1)) + fi + done + + unset -f exit + + if [ ${count} -eq 0 -a -n "${filter}" ]; then + echo "$(print_color CLR_ERROR "ERROR: no addons matched for filter ${filter}")" >&2 + echo "For more information type: ./scripts/create_addon_mt --help" >&2 + die + fi +} + +# Return 0 if package is a suitable addon, 1 otherwise +verify_addon() { + [ "${PKG_ADDON_TYPE}" = "xbmc.broken" ] && return 1 + + if [ -n "${PKG_ARCH}" ]; then + listcontains "${PKG_ARCH}" "!${TARGET_ARCH}" && return 1 + listcontains "${PKG_ARCH}" "${TARGET_ARCH}" || listcontains "${PKG_ARCH}" "any" || return 1 + fi + + if [ -n "${PKG_ADDON_PROJECTS}" ]; then + [ "${DEVICE}" = "RPi" ] && _DEVICE="RPi1" || _DEVICE="${DEVICE}" + + if listcontains "${PKG_ADDON_PROJECTS}" "!${_DEVICE:-$PROJECT}" || + listcontains "${PKG_ADDON_PROJECTS}" "!${PROJECT}"; then + return 1 + fi + + if ! listcontains "${PKG_ADDON_PROJECTS}" "${_DEVICE:-$PROJECT}" && + ! listcontains "${PKG_ADDON_PROJECTS}" "${PROJECT}" && + ! listcontains "${PKG_ADDON_PROJECTS}" "any"; then + return 1 + fi + fi + + return 0 +} + +# need parameter +if [ $# -eq 0 ]; then + usage 1 +fi + +# check environment and configure toolchains +${SCRIPTS}/checkdeps + +(setup_toolchain host) +setup_toolchain target + +# collect list of addons for building +addons= +addons_drop= +show_only="no" + +# read addons from parameter list +while [ $# -gt 0 ]; do + case $1 in + --help) usage 0;; + --show-only) show_only="yes";; + --*) usage 1;; + -*) addons_drop+=" $(get_addons ${1:1})";; + *) addons+=" $(get_addons $1)";; + esac + shift +done + +# Build a new list containing only those addons we want to build +wanted_addons= +for addon in $(echo ${addons} | tr ' ' '\n' | sort -u); do + listcontains "${addons_drop}" "${addon}" || wanted_addons+=" ${addon}" +done + +if [ "${show_only}" = "yes" ]; then + for addon in ${wanted_addons}; do + echo ${addon} + done + exit 0 +fi + +# Build all addons at once using a single plan +if MTADDONBUILD=yes start_multithread_build "${wanted_addons:1}"; then + echo + echo "$(print_color CLR_INFO "ALL ADDONS BUILT SUCCESSFULLY")" + exit 0 +elif [ -f "${THREAD_CONTROL}/addons.failed" ]; then + echo >&2 + print_color CLR_ERROR "FAILED ADDONS:\n" >&2 + while read -r addon logfile; do + if [ -n "${addon}" ]; then + if [ -n "${logfile}" ]; then + echo " $(print_color CLR_ERROR "${addon}"): ${logfile}" >&2 + else + echo " $(print_color CLR_ERROR "${addon}")" >&2 + fi + fi + done < "${THREAD_CONTROL}/addons.failed" + die +else + die "$(print_color CLR_ERROR "UNKNOWN BUILD FAILURE OR INABILITY TO GENERATE PLAN")" +fi diff --git a/scripts/genbuildplan.py b/scripts/genbuildplan.py index 0a3a078c56..73a5d175d5 100755 --- a/scripts/genbuildplan.py +++ b/scripts/genbuildplan.py @@ -203,6 +203,14 @@ def get_build_steps(args, nodes, trigger_pkgs, built_pkgs): resolved = [] unresolved = [] + # When building the image the :target packages must be installed. + # + # However, if we are not building the image then only build the packages + # and don't install them as it's likely we will be building discrete add-ons + # which are installed outside of the image. + # + install = True if "image" in args.build else False + for pkgname in [x for x in trigger_pkgs if x]: if pkgname.find(":") == -1: pkgname = "%s:target" % pkgname @@ -221,7 +229,7 @@ def get_build_steps(args, nodes, trigger_pkgs, built_pkgs): for pkg in resolved: if pkg.fqname not in built_pkgs: built_pkgs.append(pkg.fqname) - task = "build" if pkg.fqname.endswith(":host") else "install" + task = "build" if pkg.fqname.endswith(":host") or not install else "install" yield(task, pkg.fqname) # Reduce the complete list of packages to a map of those packages that will diff --git a/scripts/image_mt b/scripts/image_mt index 0bf4334d1f..de595fe5a4 100755 --- a/scripts/image_mt +++ b/scripts/image_mt @@ -93,7 +93,7 @@ for directory in etc dev proc run sys tmp usr var flash storage; do done # Build image contents -start_multithread_build image || die "Parallel build failure - see log for details. Time of failure: $(date)" +MTADDONBUILD=no start_multithread_build image || die "Parallel build failure - see log for details. Time of failure: $(date)" echo "Successful build, creating image..." >&2 diff --git a/scripts/install_addon b/scripts/install_addon index 0564c472f3..e74d0bb85e 100755 --- a/scripts/install_addon +++ b/scripts/install_addon @@ -5,6 +5,9 @@ . config/options $1 +# Make sure we have a value for STRIP +setup_toolchain target + [ -n "$2" ] && PKG_ADDON_ID=$2 ADDON_DIRECTORY="$ADDON_BUILD/$PKG_ADDON_ID" @@ -14,3 +17,62 @@ mkdir -p "$ADDON_DIRECTORY" install_addon_files "$ADDON_DIRECTORY" debug_strip "$ADDON_DIRECTORY" + +# pack_addon() +ADDON_INSTALL_DIR="$TARGET_IMG/$ADDONS/$ADDON_VERSION/${DEVICE:-$PROJECT}/$TARGET_ARCH/$PKG_ADDON_ID" +ADDONVER="$(xmlstarlet sel -t -v "/addon/@version" $ADDON_BUILD/$PKG_ADDON_ID/addon.xml)" + +if [ -f $ADDON_INSTALL_DIR/$PKG_ADDON_ID-$ADDONVER.zip ]; then + if [ "$ADDON_OVERWRITE" = "yes" ]; then + rm $ADDON_INSTALL_DIR/$PKG_ADDON_ID-$ADDONVER.zip + else + build_msg "CLR_WARNING" "*** WARNING: ${PKG_ADDON_ID}-${ADDONVER}.zip already exists. Not overwrittng it. ***" + exit 0 + fi +fi + +cd $ADDON_BUILD +build_msg "CLR_INFO" "*** compressing addon ${PKG_ADDON_ID} ... ***" +$TOOLCHAIN/bin/7za a -l -mx9 -bsp0 -bso0 -tzip $PKG_ADDON_ID-$ADDONVER.zip $PKG_ADDON_ID +cd - &>/dev/null + +mkdir -p $ADDON_INSTALL_DIR +cp $ADDON_BUILD/$PKG_ADDON_ID-$ADDONVER.zip $ADDON_INSTALL_DIR +if [ -f $ADDON_BUILD/$PKG_ADDON_ID/changelog.txt ]; then + cp $ADDON_BUILD/$PKG_ADDON_ID/changelog.txt $ADDON_INSTALL_DIR/changelog-$ADDONVER.txt +fi +if [ -f $ADDON_BUILD/$PKG_ADDON_ID/resources/icon.png ]; then + mkdir -p $ADDON_INSTALL_DIR/resources + cp $ADDON_BUILD/$PKG_ADDON_ID/resources/icon.png $ADDON_INSTALL_DIR/resources/icon.png +fi + +# workaround for kodi pvr addons +if [ -f $ADDON_BUILD/$PKG_ADDON_ID/icon.png ]; then + cp $ADDON_BUILD/$PKG_ADDON_ID/icon.png $ADDON_INSTALL_DIR/icon.png +fi + +if [ -f $ADDON_BUILD/$PKG_ADDON_ID/resources/fanart.png ]; then + mkdir -p $ADDON_INSTALL_DIR/resources + cp $ADDON_BUILD/$PKG_ADDON_ID/resources/fanart.png $ADDON_INSTALL_DIR/resources/fanart.png +fi +for f in $ADDON_BUILD/$PKG_ADDON_ID/resources/screenshot-*.{jpg,png}; do + if [ -f "$f" ]; then + mkdir -p $ADDON_INSTALL_DIR/resources + cp $f $ADDON_INSTALL_DIR/resources + fi +done + +# Jenkins add-on build +if [ "$ADDON_JENKINS" = "yes" ]; then + ADDON_JENKINS_DIR="$TARGET_IMG/jenkins" + ADDON_JENKINS_ADDON_NAME="$ADDON_VERSION-${DEVICE:-$PROJECT}-$TARGET_ARCH-$PKG_ADDON_ID-$ADDONVER" + mkdir -p "$ADDON_JENKINS_DIR" + cd $ADDON_INSTALL_DIR + $TOOLCHAIN/bin/7za a -l -mx0 -bsp0 -bso0 -tzip $ADDON_JENKINS_DIR/$ADDON_JENKINS_ADDON_NAME.zip $PKG_ADDON_ID-$ADDONVER.zip resources/ + ( cd $ADDON_JENKINS_DIR + sha256sum $ADDON_JENKINS_ADDON_NAME.zip > $ADDON_JENKINS_ADDON_NAME.zip.sha256 + ) + build_msg "CLR_INFO" "*** creating ${ADDON_JENKINS_ADDON_NAME}.zip for Jenkins complete ***" +else + build_msg "CLR_INFO" "*** creating ${PKG_ADDON_ID} complete ***" +fi