#!/usr/bin/env bash
# kaleidoscope-builder - Kaleidoscope helper tool
# Copyright (C) 2017-2018 Keyboard.io, Inc.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see .
set -e
######
###### Build and output configuration
######
absolute_filename() {
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}
read_conf_files() {
for conf_file in \
"${HOME}/.kaleidoscope-builder.conf" \
"$(pwd)/.kaleidoscope-builder.conf" \
"$(pwd)/kaleidoscope-builder.conf" \
"${KALEIDOSCOPE_DIR}/etc/kaleidoscope-builder.conf"; do
if [ -e "${conf_file}" ]; then
# shellcheck disable=SC1090
. "${conf_file}"
fi
done
}
configure_arduino_cli_env() {
SYSTEM_ARDUINO_CLI="$(command -v arduino-cli || true )"
if [ -z "${SYSTEM_ARDUINO_CLI}" ]; then
: "${ARDUINO_CLI:=${KALEIDOSCOPE_BIN_DIR}/arduino-cli}"
else
: "${ARDUINO_CLI:=${SYSTEM_ARDUINO_CLI}}"
fi
: "${ARDUINO_CONTENT:=${KALEIDOSCOPE_DIR}/.arduino}"
: "${ARDUINO_DIRECTORIES_DATA:=${ARDUINO_CONTENT}/data}"
: "${ARDUINO_DIRECTORIES_DOWNLOADS:=${ARDUINO_CONTENT}/downloads}"
: "${ARDUINO_DIRECTORIES_USER:=${ARDUINO_CONTENT}/user}"
: "${ARDUINO_CLI_CONFIG:=${ARDUINO_DIRECTORIES_DATA}/arduino-cli.yaml}"
: "${ARDUINO_BOARDS_MANAGER_KALEIDOSCOPE:=https://raw.githubusercontent.com/keyboardio/boardsmanager/master/package_keyboardio_index.json}"
}
install_arduino_cli() {
# todo cd to kaleidoscope dir
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
}
configure_arduino_cli() {
if [ -z "${ARDUINO_CLI}" ]; then
install_arduino_cli
fi
if [ -z "${ARDUINO_CLI_CONFIG}" ]; then
install_arduino_cli_config
fi
}
install_arduino_cli_config() {
run_arduino_cli config init
}
install_arduino_core_kaleidoscope() {
install_arduino_core_avr
install_arduino_core "keyboardio:avr"
}
install_arduino_core_avr() {
install_arduino_core "arduino:avr"
}
install_arduino_core() {
run_arduino_cli core install "$1"
}
run_arduino_cli() {
ARDUINO_DIRECTORIES_USER=${ARDUINO_DIRECTORIES_USER} \
ARDUINO_DIRECTORIES_DATA=${ARDUINO_DIRECTORIES_DATA} \
ARDUINO_DIRECTORIES_DOWNLOADS=${ARDUINO_DIRECTORIES_DOWNLOADS} \
ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS=${ARDUINO_BOARDS_MANAGER_KALEIDOSCOPE} \
"${ARDUINO_CLI}" "$@"
}
build_version () {
: "${LIB_PROPERTIES_PATH:="../.."}"
GIT_VERSION="$(cd "${SKETCH_DIR}"; if [ -d .git ]; then echo -n '-g' && git describe --abbrev=4 --dirty --always; fi)"
LIB_VERSION="$(cd "${SKETCH_DIR}"; (grep version= "${LIB_PROPERTIES_PATH}/library.properties" 2>/dev/null || echo version=0.0.0) | cut -d= -f2)${GIT_VERSION}"
}
build_paths() {
# We need that echo because we\re piping to cksum
# shellcheck disable=SC2005
SKETCH_IDENTIFIER="$(echo "${SKETCH_FILE_PATH}" | cksum | cut -d ' ' -f 1)-${SKETCH_FILE_NAME}"
: "${KALEIDOSCOPE_TEMP_PATH:=${TMPDIR:-/tmp}/kaleidoscope-${USER}}"
: "${KALEIDOSCOPE_BUILD_PATH:=${KALEIDOSCOPE_TEMP_PATH}/sketch}"
: "${KALEIDOSCOPE_OUTPUT_PATH:=${KALEIDOSCOPE_TEMP_PATH}/sketch}"
: "${SKETCH_OUTPUT_DIR:=${SKETCH_IDENTIFIER}/output}"
: "${SKETCH_BUILD_DIR:=${SKETCH_IDENTIFIER}/build}"
: "${BUILD_PATH:=${KALEIDOSCOPE_BUILD_PATH}/${SKETCH_BUILD_DIR}}"
: "${OUTPUT_PATH:=${KALEIDOSCOPE_OUTPUT_PATH}/${SKETCH_OUTPUT_DIR}}"
: "${CCACHE_WRAPPER_PATH:=${KALEIDOSCOPE_TEMP_PATH}/ccache/bin}"
: "${CORE_CACHE_PATH:=${KALEIDOSCOPE_TEMP_PATH}/arduino-cores}"
mkdir -p "$CORE_CACHE_PATH"
mkdir -p "$BUILD_PATH"
}
build_filenames () {
: "${OUTPUT_FILE_PREFIX:=${SKETCH_BASE_NAME}-${LIB_VERSION}}"
: "${HEX_FILE_PATH:=${OUTPUT_PATH}/${OUTPUT_FILE_PREFIX}.hex}"
: "${HEX_FILE_WITH_BOOTLOADER_PATH:=${OUTPUT_PATH}/${OUTPUT_FILE_PREFIX}-with-bootloader.hex}"
: "${ELF_FILE_PATH:=${OUTPUT_PATH}/${OUTPUT_FILE_PREFIX}.elf}"
: "${LIB_FILE_PATH:=${OUTPUT_PATH}/${OUTPUT_FILE_PREFIX}.a}"
}
enable_ccache () {
if [ -z "${CCACHE_NOT_SUPPORTED}" ] && [ "$(command -v ccache)" ]; then
if ! [ -d "$CCACHE_WRAPPER_PATH" ]; then
mkdir -p "$CCACHE_WRAPPER_PATH"
if ! [ -h "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}${C_COMPILER_BASENAME}" ]; then
ln -s "$(command -v ccache)" "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}${C_COMPILER_BASENAME}"
fi
if ! [ -h "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}${CXX_COMPILER_BASENAME}" ]; then
ln -s "$(command -v ccache)" "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}${CXX_COMPILER_BASENAME}"
fi
if ! [ -h "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}nm" ]; then
ln -s "${AVR_NM}" "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}nm"
fi
if ! [ -h "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}objcopy" ]; then
ln -s "${AVR_OBJCOPY}" "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}objcopy"
fi
if ! [ -h "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}ar" ]; then
ln -s "${AVR_AR}" "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}ar"
fi
if ! [ -h "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}size" ]; then
ln -s "${AVR_SIZE}" "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}size"
fi
fi
export CCACHE_PATH=${COMPILER_PATH}/
CCACHE_ENABLED=1
fi
}
firmware_size () {
if [ "${ARCH}" = "virtual" ]; then
echo "[Size not computed for virtual build]"
return
fi
: "${MAX_PROG_SIZE:=$(get_arduino_pref 'upload.maximum_size')}"
## This is a terrible hack, please don't hurt me. - algernon
set +e
raw_output=$("$@" 2> /dev/null)
rc=$?
set -e
if [ $rc -eq 0 ]; then
output="$(echo "${raw_output}"| grep "\\(Program\\|Data\\):" | sed -e 's,^, - ,' && echo)"
PROGSIZE="$(echo "${output}" | grep "Program:" | cut -d: -f2 | awk '{print $1}')"
PERCENT="$(echo "${PROGSIZE}" "${MAX_PROG_SIZE}" | awk "{ printf \"%02.01f\", \$1 / \$2 * 100 }")"
# we want the sed there, doing with shell builtins would be worse.
# shellcheck disable=SC2001 disable=SC1117
echo "${output}" | sed -e "s/\(Program:.*\)(\([0-9\.]*%\) Full)/\1(${PERCENT}% Full)/"
else
echo "Unable to determine image size."
fi
}
find_sketch () {
SKETCH_DIR="${SKETCH:-$(absolute_filename $(pwd))}"
SKETCH_BASE_NAME=$(basename "${SKETCH_DIR}")
SKETCH_FILE_NAME="${SKETCH_BASE_NAME}.ino"
# Arduino sketches are usually a file inside directory Foo named Foo.ino, so try that as a fallback
for dir in \
"${SKETCH_DIR}" \
"src/" \
"."; do
if [ -f "${dir}/${SKETCH_FILE_NAME}" ]; then
SKETCH_DIR="${dir}"
SKETCH_FILE_PATH=$(absolute_filename "${dir}/${SKETCH_FILE_NAME}")
return
fi
done
echo "I couldn't find your sketch (.ino file)" >&2
exit 1
}
find_device_vid_pid() {
: "${VID:=$(get_arduino_pref 'build.vid')}"
: "${SKETCH_PID:=$(get_arduino_pref 'build.pid')}"
: "${BOOTLOADER_PID:=$(get_arduino_pref 'bootloader.pid')}"
: "${BOOTLOADER_VID:=$(get_arduino_pref 'bootloader.vid')}"
}
prompt_before_flashing () {
flashing_instructions=$(get_arduino_pref 'build.flashing_instructions')
if [ "x${flashing_instructions}x" = "xx" ]; then
flashing_instructions="If your keyboard needs you to do something to put it in flashing mode, do that now."
fi
printf '%b\n\n' "${flashing_instructions}"
echo ""
echo "When you're ready to proceed, press 'Enter'."
# We do not want to permit line continuations here. We just want a newline.
# shellcheck disable=SC2162
read
}
flash () {
compile "$@"
# Check to see if we can see a keyboard bootloader port.
# If we -can-, then we should skip over the "reset to bootloader" thing
find_bootloader_ports
if [ -z "${DEVICE_PORT_BOOTLOADER}" ]; then
prompt_before_flashing
# This is defined in the (optional) user config.
# shellcheck disable=SC2154
${preFlash_HOOKS}
# If we're -not- doing a manual reset, then try to do it automatically
if [ -z "${MANUAL_RESET}" ]; then
reset_device
sleep 2
find_bootloader_ports
# Otherwise, poll for a bootloader port.
else
wait_for_bootloader_port
fi
fi
check_bootloader_port_and_flash
# This is defined in the (optional) user config.
# shellcheck disable=SC2154
${postFlash_HOOKS}
}
wait_for_bootloader_port() {
declare -i tries
tries=15
while [ "$tries" -gt 0 ] && [ -z "${DEVICE_PORT_BOOTLOADER}" ]; do
sleep 1
printf "."
find_bootloader_ports
# the variable annotations do appear to be necessary
# shellcheck disable=SC2004
tries=$(($tries-1))
done
if [ "$tries" -gt 0 ]; then
echo "Found."
else
echo "Timed out."
fi
}
check_bootloader_port () {
if [ -z "${DEVICE_PORT_BOOTLOADER}" ]; then
echo "Unable to detect a keyboard in bootloader mode."
echo "You may need to hold a key or hit a reset button."
echo "Please check your keyboard's documentation"
return 1
fi
}
check_bootloader_port_and_flash () {
if ! check_bootloader_port; then
return 1
fi
echo "Flashing your keyboard:"
# If the flash fails, try a second time
if ! flash_over_usb; then
sleep 2
if ! flash_over_usb; then
if [ "${ARDUINO_VERBOSE}" != "--verbose" ]; then
echo "Something went wrong."
echo "You might want to try flashing again with the VERBOSE environment variable set"
fi
return 1
fi
fi
echo "Keyboard flashed successfully!"
return 0
}
flash_from_bootloader() {
compile "$@"
prompt_before_flashing
find_bootloader_ports
check_bootloader_port_and_flash
}
program() {
compile "$@"
prompt_before_flashing
flash_with_programmer
}
flash_with_programmer() {
${AVRDUDE_CMD}
-cusbtiny \
-B 1 \
"-Uflash:w:${HEX_FILE_PATH}:i"
}
flash_over_usb () {
FLASH_CMD=$( ${AVRDUDE_CMD}
-cavr109 \
-P "${DEVICE_PORT_BOOTLOADER}" \
-b57600 \
"-Uflash:w:${HEX_FILE_PATH}:i")
if [ "${ARDUINO_VERBOSE}" != "--verbose" ]; then
${FLASH_CMD} 2>&1 |grep -v ^avrdude | grep -v '^$' |grep -v '^ ' | grep -vi programmer
return "${PIPESTATUS[0]}"
else
${FLASH_CMD}
return $?
fi
}
hex_with_bootloader () {
compile
: "${BOOTLOADER_PATH:=$( get_arduino_pref 'runtime.platform.path' )/bootloaders/$( get_arduino_pref 'bootloader.file' )}"
awk '/^:00000001FF/ == 0' "${HEX_FILE_PATH}" > "${HEX_FILE_WITH_BOOTLOADER_PATH}"
echo "Using ${BOOTLOADER_PATH}"
cat "${BOOTLOADER_PATH}" >> "${HEX_FILE_WITH_BOOTLOADER_PATH}"
ln -sf -- "${OUTPUT_FILE_PREFIX}-with-bootloader.hex" "${OUTPUT_PATH}/${SKETCH_BASE_NAME}-latest-with-bootloader.hex"
cat <<- EOF
Combined firmware and bootloader are now at ${HEX_FILE_WITH_BOOTLOADER_PATH}
Make sure you have the bootloader version you expect.
And TEST THIS ON REAL HARDWARE BEFORE YOU GIVE IT TO ANYONE
EOF
}
build () {
compile "$@"
size "$@"
}
prepare_ccache () {
find_sketch
build_paths
enable_ccache
}
compile () {
find_sketch
build_version
build_paths
build_filenames
# If the hex file is older than the sketch file, or the hex file does not exist
# then rebuild. This is not as correct as letting make check our dependencies
# But it's less broken for most user use cases
# TODO(anyone): Make this suck less
if [ "${HEX_FILE_PATH}" -ot "${SKETCH_FILE_PATH}" ]; then
do_compile "$@"
else
echo "${HEX_FILE_PATH} did not need to be rebuilt"
fi
}
set_executable_paths () {
######
###### Executable paths
######
# Allow the compiler path to be empty for virtual builds
# should use compiler.path instead of appending bin, but we don't have substitution het
: "${COMPILER_PATH=$(get_arduino_pref 'runtime.tools.avr-gcc.path')/bin}"
COMPILER_SUFFIX=""
C_COMPILER_BASENAME=$(basename ${CC:-gcc})
CXX_COMPILER_BASENAME=$(basename ${CXX:-g++})
AR_BASENAME=$(basename ${AR:-ar})
OBJCOPY_BASENAME=$(basename ${OBJCOPY:-objcopy})
# Allow the compiler prefix to be empty for virtual builds
COMPILER_PREFIX="${COMPILER_PREFIX-avr-}"
: "${AVR_SIZE:=${COMPILER_PATH}/${COMPILER_PREFIX}size}"
: "${AVR_OBJDUMP:=${COMPILER_PATH}/${COMPILER_PREFIX}objdump}"
: "${AVR_OBJCOPY:=${COMPILER_PATH}/${COMPILER_PREFIX}objcopy}"
: "${AVR_NM:=${COMPILER_PATH}/${COMPILER_PREFIX}nm}"
: "${AVR_AR:=${COMPILER_PATH}/${COMPILER_PREFIX}ar}"
# TO DO should use tools.avrdude.cmd.path and tools.avrdude.config.path instead of hardcoding
: "${AVRDUDE:=$(get_arduino_pref 'runtime.tools.avrdude.path')/bin/avrdude}"
: "${AVRDUDE_CONF:=$(get_arduino_pref 'runtime.tools.avrdude.path')/etc/avrdude.conf}"
AVRDUDE_CMD="${AVRDUDE} -v-C "${AVRDUDE_CONF}" -D -p\"$(get_arduino_pref 'build.mcu')\""
}
do_compile () {
prepare_ccache
install -d "${OUTPUT_PATH}"
echo "Building ${SKETCH_FILE_PATH}"
# This is defined in the (optional) user config.
# shellcheck disable=SC2154
${compile_HOOKS}
SAVED_BOARD="${BOARD}"
SAVED_FQBN="${FQBN}"
if [ -e "${SKETCH_DIR}/.kaleidoscope-builder.conf" ]; then
# shellcheck disable=SC1090
BOARD="$(. "${SKETCH_DIR}"/.kaleidoscope-builder.conf && echo "${BOARD}")"
# shellcheck disable=SC1090
FQBN="$(. "${SKETCH_DIR}"/.kaleidoscope-builder.conf && echo "${FQBN}")"
if [ -n "${BOARD}" ]; then
: "${ARCH:=avr}"
FQBN="keyboardio:${ARCH}:${BOARD}"
fi
fi
_CMD_CXX="${CXX:-${COMPILER_PREFIX}${CXX_COMPILER_BASENAME}${COMPILER_SUFFIX}}"
_CMD_CC="${CC:-${COMPILER_PREFIX}${C_COMPILER_BASENAME}${COMPILER_SUFFIX}}"
_CMD_AR="${AR:-${COMPILER_PREFIX}${AR_BASENAME}${COMPILER_SUFFIX}}"
do_compile_with_cli
if [ -z "${LIBONLY}" ]; then
cp "${BUILD_PATH}/${SKETCH_FILE_NAME}.hex" "${HEX_FILE_PATH}"
cp "${BUILD_PATH}/${SKETCH_FILE_NAME}.elf" "${ELF_FILE_PATH}"
ln -sf "${OUTPUT_FILE_PREFIX}.hex" "${OUTPUT_PATH}/${SKETCH_BASE_NAME}-latest.hex"
ln -sf "${OUTPUT_FILE_PREFIX}.elf" "${OUTPUT_PATH}/${SKETCH_BASE_NAME}-latest.elf"
else
cp "${BUILD_PATH}/${SKETCH_FILE_NAME}.a" "${LIB_FILE_PATH}"
ln -sf "${OUTPUT_FILE_PREFIX}.a" "${OUTPUT_PATH}/${SKETCH_BASE_NAME}-latest.a"
fi
if [ "${ARDUINO_VERBOSE}" == "--verbose" ]; then
echo "Build artifacts can be found in ${BUILD_PATH}";
fi
BOARD="${SAVED_BOARD}"
FQBN="${SAVED_FQBN}"
}
get_arduino_pref() {
pref=$1
# Strip the preference name. And then strip leading and trailing quotations
MESSAGE=$(dump_arduino_prefs | grep --max-count=1 "${pref}=" | sed -e s/^.*${pref}=// -e 's/^"//' -e 's/"$//')
echo "$MESSAGE"
}
dump_arduino_prefs() {
if [ "x${_ARDUINO_PREFS}x" == "xx" ]; then
_ARDUINO_PREFS=$(run_arduino_cli --fqbn "${FQBN}" compile --show-properties "${SKETCH_FILE_PATH}")
fi
echo "$_ARDUINO_PREFS"
}
do_compile_with_cli() {
#-build-cache "${CORE_CACHE_PATH}" \
if [ $CCACHE_ENABLED ]; then
COMPILER_PATH_PROP="${CCACHE_WRAPPER_PATH}/"
else
COMPILER_PATH_PROP="${COMPILER_PATH}"
fi
run_arduino_cli compile \
--fqbn "${FQBN}" \
--libraries "${KALEIDOSCOPE_DIR}/.." \
--build-path "${BUILD_PATH}" \
--output-dir "${OUTPUT_PATH}" \
--build-properties "compiler.path=${COMPILER_PATH_PROP}" \
--build-properties "compiler.c.cmd=${_CMD_CC}" \
--build-properties "compiler.cpp.cmd=${_CMD_CXX}" \
--build-properties "compiler.ar.cmd=${_CMD_AR}" \
--build-properties "compiler.c.elf.cmd=${_CMD_CXX}" \
--build-properties "compiler.cpp.extra_flags=${LOCAL_CFLAGS}"\
--warnings all \
"${SKETCH_FILE_PATH}"
}
find_all_sketches () {
for plugin in ./*.ino \
$([ -d examples ] && find examples -name '*.ino') \
src/*.ino; do
if [ -d "$(dirname "${plugin}")" ] || [ -f "${plugin}" ]; then
p="$(basename "${plugin}" .ino)"
if [ "${p}" != '*' ]; then
case "${plugin}" in
examples/*/${p}/${p}.ino)
echo "${plugin}" | sed -e "s,examples/,," | sed -e "s,/${p}\\.ino,,"
;;
*)
echo "${p}"
;;
esac
fi
fi
done | sort
}
build_all () {
plugins="$(find_all_sketches)"
for sketch in ${plugins}; do
export SKETCH="${sketch}"
$0 "${plugin}" build
done
}
size () {
compile
: "${AVR_SIZE_FLAGS:=-C --mcu=$(get_arduino_pref 'build.mcu')}"
echo "- Size: ${ELF_FILE_PATH}"
# shellcheck disable=SC2086
firmware_size "${AVR_SIZE}" ${AVR_SIZE_FLAGS} "${ELF_FILE_PATH}"
echo
}
size_map () {
compile
"${AVR_NM}" --size-sort -C -r -l -t decimal "${ELF_FILE_PATH}"
}
disassemble () {
compile
"${AVR_OBJDUMP}" -C -d "${ELF_FILE_PATH}"
}
decompile () {
disassemble
}
clean () {
find_sketch
build_paths
if [ -d "$OUTPUT_PATH" ]; then
rm -rf -- "${OUTPUT_PATH}"
fi
}
reset_device() {
find_device_port
check_device_port
reset_device_cmd
}
check_device_port () {
if [ -z "$DEVICE_PORT" ]; then
cat <&2
I couldn't autodetect the keyboard's serial port.
If you see this message and your keyboard is connected to your computer,
it may mean that our serial port detection logic is buggy or incomplete.
In that case, please report this issue at:
https://github.com/keyboardio/Kaleidoscope
EOF
exit 1
elif echo "$DEVICE_PORT" | grep -q '[[:space:]]'; then
cat <&2
Unexpected whitespace found in detected serial port:
$DEVICE_PORT
If you see this message, it means that our serial port
detection logic is buggy or incomplete.
Please report this issue at:
https://github.com/keyboardio/Kaleidoscope
EOF
exit 1
fi
if ! [ -w "$DEVICE_PORT" ]; then
cat <&2
In order to update your keyboard's firmware you need to have permission
to write to its serial port $DEVICE_PORT.
It appears that you do not have this permission:
$(ls -l "$DEVICE_PORT")
This may be because you're not in the correct unix group:
$(stat -c %G "$DEVICE_PORT").
You are currently in the following groups:
$(id -Gn)
Please ensure you have followed the instructions on setting up your
account to be in the right group:
https://github.com/keyboardio/Kaleidoscope/wiki/Install-Arduino-support-on-Linux
EOF
exit 1
fi
}
usage () {
cat <<- EOF
Usage: $0 SKETCH commands...
Runs all of the commands in the context of the Sketch.
Available commands:
help
This help screen.
compile
Compiles the sketch.
size
Reports the size of the compiled sketch.
build
Runs compile and report-size.
clean
Cleans up the output directory.
size-map
Displays the size map for the sketch.
disassemble
Decompile the sketch.
reset-device
Reset the device.
flash
Flashes the firmware using avrdude.
EOF
}
help () {
usage
}
if [ $# -lt 1 ]; then
usage
exit 1
fi
# Temporary migration for old makefiles
# I'm not thrilled about how we default to system Arduino dirs.
if [ -n "${BOARD_HARDWARE_PATH}" ]; then
ARDUINO_DIRECTORIES_USER="${BOARD_HARDWARE_PATH}/../"
fi
: "${KALEIDOSCOPE_DIR:=$(cd "$(dirname "$0")"/..; pwd)}"
# shellcheck disable=SC2034
: "${KALEIDOSCOPE_BIN_DIR:=${KALEIDOSCOPE_DIR}/bin/}"
read_conf_files
configure_arduino_cli_env
set_executable_paths
# shellcheck disable=SC1090
if [ -n "${VERBOSE}" ] && [[ "${VERBOSE}" -gt 0 ]]; then
ARDUINO_VERBOSE="--verbose"
else
ARDUINO_VERBOSE="--quiet"
fi
## Parse the command-line
## - anything that has a =, is an env var
## - from the remaining stuff, the first one is the Library/Sketch
## - everything else are commands
##
## - if there is only one argument, that's a command
cmds=""
## Export vars
for i in $(seq 1 $#); do
v="$1"
shift
case "${v}" in
*=*)
# Exporting an expansion is *precisely* what we want here.
# shellcheck disable=SC2086,SC2163
export ${v}
;;
*)
cmds="${cmds} ${v}"
;;
esac
done
# Word splitting is desired here.
# shellcheck disable=SC2086
set -- ${cmds}
if [ $# -eq 1 ]; then
cmd="$(echo "$1" | tr '-' '_')"
${cmd}
exit $?
fi
SKETCH="$1"
shift
if [ "${SKETCH}" = "default" ]; then
SKETCH="${DEFAULT_SKETCH}"
fi
cmds=""
# shellcheck disable=2034
for i in $(seq 1 $#); do
cmds="${cmds} $(echo "$1" | tr '-' '_')"
shift
done
for cmd in ${cmds}; do
${cmd}
done