You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Kaleidoscope/bin/kaleidoscope-builder

897 lines
23 KiB

#!/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 <http://www.gnu.org/licenses/>.
set -e
######
###### Build and output configuration
######
identify_os() {
4 years ago
## Platform-specific overrides
# Shamelessly stolen from git's Makefile
uname_S=$(uname -s 2>/dev/null || echo not)
uname_O=$(uname -o 2>/dev/null || echo not)
}
adjust_for_virtual_build() {
4 years ago
if [ "${uname_S}" = "FreeBSD" ]; then
: "${COMPILER_PATH:=/usr/local/bin/}"
else
: "${COMPILER_PATH:=/usr/bin/}"
fi
4 years ago
COMPILER_PREFIX=""
}
adjust_for_cygwin() {
4 years ago
# The Windows arduino-builder.exe doesn't understand being told to exec against Cygwin symlinks
CCACHE_NOT_SUPPORTED=1
# It's important that all of these be underneath /cygdrive/c so they can be converted to Windows paths that the
# Windows Arduino binaries can understand.
: "${TMPDIR:=/cygdrive/c/Users/${USER}/AppData/Local/Temp}"
# We need to prevent Windows executables from being passed parameters that are absolute paths, since they won't
# be interpretable when of the form /cygdrive/c/foo. To work around this, we set the common path root variables
# to use relative paths instead of absolute paths, since those have mostly platform-agnostic behavior.
#
# Note that this trick requires that all of these paths exist on the same drive letter as the current directory,
# since otherwise even the relative paths would include Cygwin-specific components. So...
if [[ $(realpath --relative-base=/cygdrive/c .) == /* ]]; then
echo "kaleidoscope-builder's Cygwin support is currently limited to running from within /cygdrive/c"
exit 1
fi
4 years ago
TMPDIR="$(realpath --relative-to=./ ${TMPDIR})"
}
absolute_filename() {
4 years ago
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}
read_conf_files() {
4 years ago
for conf_file in \
"${HOME}/.kaleidoscope-builder.conf" \
"$(pwd)/.kaleidoscope-builder.conf" \
4 years ago
"$(pwd)/kaleidoscope-builder.conf"; do
4 years ago
if [ -e "${conf_file}" ]; then
# shellcheck disable=SC1090
. "${conf_file}"
fi
4 years ago
done
}
configure_arduino_cli_env() {
4 years ago
SYSTEM_ARDUINO_CLI="$(command -v arduino-cli || true)"
4 years ago
if [ -z "${SYSTEM_ARDUINO_CLI}" ]; then
: "${ARDUINO_CLI:=${KALEIDOSCOPE_BIN_DIR}/arduino-cli}"
else
: "${ARDUINO_CLI:=${SYSTEM_ARDUINO_CLI}}"
fi
4 years ago
: "${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}"
}
4 years ago
install_arduino_cli() {
# todo cd to kaleidoscope dir
4 years ago
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
4 years ago
install_arduino_cli_config
fi
}
install_arduino_cli_config() {
4 years ago
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} \
4 years ago
ARDUINO_DIRECTORIES_DATA=${ARDUINO_DIRECTORIES_DATA} \
ARDUINO_DIRECTORIES_DOWNLOADS=${ARDUINO_DIRECTORIES_DOWNLOADS} \
ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS=${ARDUINO_BOARDS_MANAGER_KALEIDOSCOPE} \
"${ARDUINO_CLI}" "$@"
}
4 years ago
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() {
4 years ago
# 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}"
4 years ago
: "${SKETCH_OUTPUT_DIR:=${SKETCH_IDENTIFIER}/output}"
: "${SKETCH_BUILD_DIR:=${SKETCH_IDENTIFIER}/build}"
4 years ago
: "${BUILD_PATH:=${KALEIDOSCOPE_BUILD_PATH}/${SKETCH_BUILD_DIR}}"
: "${OUTPUT_PATH:=${KALEIDOSCOPE_OUTPUT_PATH}/${SKETCH_OUTPUT_DIR}}"
4 years ago
: "${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"
}
4 years ago
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}"
}
4 years ago
enable_ccache() {
if [ -z "${CCACHE_NOT_SUPPORTED}" ] && [ "$(command -v ccache)" ]; then
if ! [ -d "$CCACHE_WRAPPER_PATH" ]; then
mkdir -p "$CCACHE_WRAPPER_PATH"
4 years ago
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
4 years ago
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
4 years ago
if ! [ -h "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}nm" ]; then
ln -s "${AVR_NM}" "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}nm"
fi
4 years ago
if ! [ -h "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}objcopy" ]; then
ln -s "${AVR_OBJCOPY}" "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}objcopy"
fi
4 years ago
if ! [ -h "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}ar" ]; then
ln -s "${AVR_AR}" "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}ar"
fi
4 years ago
if ! [ -h "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}size" ]; then
ln -s "${AVR_SIZE}" "${CCACHE_WRAPPER_PATH}/${COMPILER_PREFIX}size"
fi
fi
4 years ago
export CCACHE_PATH=${COMPILER_PATH}/
CCACHE_ENABLED=1
4 years ago
fi
}
4 years ago
firmware_size() {
if [ "${ARCH}" = "virtual" ]; then
echo "[Size not computed for virtual build]"
return
fi
4 years ago
: "${MAX_PROG_SIZE:=$(get_arduino_pref 'upload.maximum_size')}"
4 years ago
## This is a terrible hack, please don't hurt me. - algernon
4 years ago
set +e
raw_output=$("$@" 2>/dev/null)
rc=$?
set -e
4 years ago
if [ $rc -eq 0 ]; then
output="$(echo "${raw_output}" | grep "\\(Program\\|Data\\):" | sed -e 's,^, - ,' && echo)"
4 years ago
PROGSIZE="$(echo "${output}" | grep "Program:" | cut -d: -f2 | awk '{print $1}')"
4 years ago
PERCENT="$(echo "${PROGSIZE}" "${MAX_PROG_SIZE}" | awk "{ printf \"%02.01f\", \$1 / \$2 * 100 }")"
4 years ago
# 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
}
4 years ago
find_sketch() {
SKETCH_DIR="${SKETCH:-$(absolute_filename "$(pwd)")}"
SKETCH_BASE_NAME=$(basename "${SKETCH_DIR}")
SKETCH_FILE_NAME="${SKETCH_BASE_NAME}.ino"
4 years ago
# 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
}
4 years ago
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')}"
}
4 years ago
prompt_before_flashing() {
flashing_instructions=$(get_arduino_pref 'build.flashing_instructions')
4 years ago
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
4 years ago
printf '%b\n\n' "${flashing_instructions}"
echo ""
echo "When you're ready to proceed, press 'Enter'."
4 years ago
# We do not want to permit line continuations here. We just want a newline.
# shellcheck disable=SC2162
read
}
reset_device_cmd() {
4 years ago
if [ -z ${NO_RESET} ]; then
if [ "${uname_S}" = "Darwin" ]; then
/bin/stty -f ${DEVICE_PORT} 1200
elif [ "${uname_S}" = "FreeBSD" ]; then
/bin/stty -f ${DEVICE_PORT} 1200
elif [ "${uname_O}" = "Cygwin" ]; then
cmd /c mode ${DEVICE_COM_PORT} baud=1200
else
stty -F ${DEVICE_PORT} 1200 hupcl
fi
fi
}
4 years ago
flash() {
compile "$@"
4 years ago
# 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
4 years ago
# This is defined in the (optional) user config.
# shellcheck disable=SC2154
${preFlash_HOOKS}
4 years ago
# 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
4 years ago
fi
4 years ago
check_bootloader_port_and_flash
4 years ago
# This is defined in the (optional) user config.
# shellcheck disable=SC2154
${postFlash_HOOKS}
}
wait_for_bootloader_port() {
4 years ago
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
}
4 years ago
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
}
4 years ago
check_bootloader_port_and_flash() {
4 years ago
if ! check_bootloader_port; then
return 1
fi
4 years ago
echo "Flashing your keyboard:"
4 years ago
# 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
4 years ago
return 1
fi
fi
echo "Keyboard flashed successfully!"
return 0
}
flash_from_bootloader() {
4 years ago
compile "$@"
prompt_before_flashing
find_bootloader_ports
check_bootloader_port_and_flash
}
program() {
4 years ago
compile "$@"
prompt_before_flashing
flash_with_programmer
}
flash_with_programmer() {
${AVRDUDE_CMD} \
4 years ago
-cusbtiny \
-B 1 \
"-Uflash:w:${HEX_FILE_PATH}:i"
}
4 years ago
flash_over_usb() {
FLASH_CMD=$(${AVRDUDE_CMD} \
-cavr109 \
-P "${DEVICE_PORT_BOOTLOADER}" \
-b57600 \
"-Uflash:w:${HEX_FILE_PATH}:i")
4 years ago
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
}
4 years ago
hex_with_bootloader() {
compile
4 years ago
: "${BOOTLOADER_PATH:=$(get_arduino_pref 'runtime.platform.path')/bootloaders/$(get_arduino_pref 'bootloader.file')}"
4 years ago
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
4 years ago
EOF
}
4 years ago
build() {
compile "$@"
size "$@"
}
4 years ago
prepare_ccache() {
find_sketch
build_paths
enable_ccache
}
4 years ago
compile() {
find_sketch
set_executable_paths
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
}
4 years ago
set_executable_paths() {
######
###### Executable paths
######
4 years ago
# 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}"
4 years ago
COMPILER_SUFFIX=""
4 years ago
C_COMPILER_BASENAME=$(basename "${CC:-gcc}")
CXX_COMPILER_BASENAME=$(basename "${CXX:-g++}")
AR_BASENAME=$(basename "${AR:-ar}")
4 years ago
# 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}"
4 years ago
# 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')\""
}
4 years ago
do_compile() {
prepare_ccache
4 years ago
install -d "${OUTPUT_PATH}"
4 years ago
echo "Building ${SKETCH_FILE_PATH}"
4 years ago
# This is defined in the (optional) user config.
# shellcheck disable=SC2154
${compile_HOOKS}
4 years ago
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
4 years ago
do_compile_with_cli
4 years ago
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
4 years ago
if [ "${ARDUINO_VERBOSE}" == "--verbose" ]; then
echo "Build artifacts can be found in ${BUILD_PATH}"
fi
4 years ago
BOARD="${SAVED_BOARD}"
FQBN="${SAVED_FQBN}"
}
get_arduino_pref() {
4 years ago
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() {
4 years ago
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() {
4 years ago
#-build-cache "${CORE_CACHE_PATH}" \
4 years ago
if [ $CCACHE_ENABLED ]; then
COMPILER_PATH_PROP="${CCACHE_WRAPPER_PATH}/"
else
4 years ago
COMPILER_PATH_PROP="${COMPILER_PATH}"
fi
4 years ago
_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}}"
run_arduino_cli compile \
--fqbn "${FQBN}" \
4 years ago
--libraries "${KALEIDOSCOPE_DIR}/.." \
--build-path "${BUILD_PATH}" \
--output-dir "${OUTPUT_PATH}" \
4 years ago
--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}"
}
4 years ago
find_all_sketches() {
for sketch_name in ./*.ino \
$([ -d examples ] && find examples -name '*.ino') \
src/*.ino; do
if [ -d "$(dirname "${sketch_name}")" ] || [ -f "${sketch_name}" ]; then
p="$(basename "${sketch_name}" .ino)"
if [ "${p}" != '*' ]; then
case "${sketch_name}" in
examples/*/${p}/${p}.ino)
echo "${sketch_name}" | sed -e "s,examples/,," | sed -e "s,/${p}\\.ino,,"
;;
*)
echo "${p}"
;;
esac
fi
fi
done | sort
}
4 years ago
build_all() {
plugins="$(find_all_sketches)"
4 years ago
for sketch in ${plugins}; do
export SKETCH="${sketch}"
$0 "${sketch}" build
done
}
4 years ago
size() {
compile
4 years ago
: "${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
}
4 years ago
size_map() {
compile
4 years ago
"${AVR_NM}" --size-sort -C -r -l -t decimal "${ELF_FILE_PATH}"
}
4 years ago
disassemble() {
compile
4 years ago
"${AVR_OBJDUMP}" -C -d "${ELF_FILE_PATH}"
}
4 years ago
decompile() {
disassemble
}
4 years ago
clean() {
find_sketch
build_paths
if [ -d "$OUTPUT_PATH" ]; then
rm -rf -- "${OUTPUT_PATH}"
fi
}
reset_device() {
4 years ago
find_device_port
check_device_port
reset_device_cmd
}
find_bootloader_ports() {
4 years ago
if [ -n "${DEVICE_PORT_BOOTLOADER}" ]; then
echo "DEVICE_PORT_BOOTLOADER=\"${DEVICE_PORT_BOOTLOADER}\" predefined."
return
fi
4 years ago
find_device_vid_pid
: "${BOOTLOADER_VID:=${VID}}"
if [ "${uname_S}" = "Darwin" ]; then
DEVICE_PORT_PROBER="${KALEIDOSCOPE_BIN_DIR}/find-device-port-macos"
DEVICE_PORT_BOOTLOADER="$(perl ${DEVICE_PORT_PROBER} ${BOOTLOADER_VID} ${BOOTLOADER_PID})"
elif [ "${uname_O}" = "Cygwin" ]; then
DEVICE_PORT_PROBER="${KALEIDOSCOPE_BIN_DIR}/find-device-port-windows.ps1"
DEVICE_PORT_BOOTLOADER="$(powershell -noprofile -executionpolicy bypass ${DEVICE_PORT_PROBER} ${BOOTLOADER_VID} ${BOOTLOADER_PID} -Format COM)"
elif [ "${uname_S}" = "FreeBSD" ]; then
DEVICE_PORT_PROBER="${KALEIDOSCPE_BIN_DIR}/find-device-port-freebsd"
DEVICE_PORT_BOOTLOADER="$(perl ${DEVICE_PORT_PROBER})"
4 years ago
else
4 years ago
DEVICE_PORT_PROBER="${KALEIDOSCOPE_BIN_DIR}/find-device-port-linux-udev"
DEVICE_PORT_BOOTLOADER="$(perl ${DEVICE_PORT_PROBER} ${BOOTLOADER_VID} ${BOOTLOADER_PID})"
fi
}
find_device_port() {
4 years ago
if [ -n "${DEVICE_PORT}" ]; then
echo "DEVICE_PORT=\"${DEVICE_PORT}\" predefined."
return
fi
4 years ago
find_device_vid_pid
if [ "${uname_S}" = "Darwin" ]; then
DEVICE_PORT_PROBER="${KALEIDOSCOPE_BIN_DIR}/find-device-port-macos"
DEVICE_PORT="$(perl ${DEVICE_PORT_PROBER} ${VID} ${SKETCH_PID})"
elif [ "${uname_O}" = "Cygwin" ]; then
DEVICE_PORT_PROBER="${KALEIDOSCOPE_BIN_DIR}/find-device-port-windows.ps1"
DEVICE_PORT="$(powershell -noprofile -executionpolicy bypass ${DEVICE_PORT_PROBER} ${VID} ${SKETCH_PID} -Format Cygwin)"
DEVICE_COM_PORT="$(powershell -noprofile -executionpolicy bypass ${DEVICE_PORT_PROBER} ${VID} ${SKETCH_PID} -Format COM)"
elif [ "${uname_S}" = "FreeBSD" ]; then
DEVICE_PORT_PROBER="${KALEIDOSCOPE_BIN_DIR}/find-device-port-freebsd"
DEVICE_PORT="$(perl ${DEVICE_PORT_PROBER})"
else
DEVICE_PORT_PROBER="${KALEIDOSCOPE_BIN_DIR}/find-device-port-linux-udev"
DEVICE_PORT="$(perl ${DEVICE_PORT_PROBER} ${VID} ${SKETCH_PID})"
fi
}
4 years ago
check_device_port() {
if [ -z "$DEVICE_PORT" ]; then
cat <<EOF >&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
4 years ago
exit 1
elif echo "$DEVICE_PORT" | grep -q '[[:space:]]'; then
cat <<EOF >&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
4 years ago
exit 1
fi
4 years ago
if ! [ -w "$DEVICE_PORT" ]; then
cat <<EOF >&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
4 years ago
exit 1
fi
}
4 years ago
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.
4 years ago
EOF
}
4 years ago
help() {
usage
}
if [ $# -lt 1 ]; then
4 years ago
usage
exit 1
fi
# Temporary migration for old makefiles
4 years ago
# 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
4 years ago
: "${KALEIDOSCOPE_DIR:=$(
cd "$(dirname "$0")"/..
pwd
)}"
# shellcheck disable=SC2034
: "${KALEIDOSCOPE_BIN_DIR:=${KALEIDOSCOPE_DIR}/bin/}"
identify_os
read_conf_files
configure_arduino_cli_env
# shellcheck disable=SC1090
if [ -n "${VERBOSE}" ] && [[ "${VERBOSE}" -gt 0 ]]; then
4 years ago
ARDUINO_VERBOSE="--verbose"
else
4 years ago
ARDUINO_VERBOSE="--quiet"
fi
: "${BOARD:=model01}"
if [[ -z "${ARCH}" && -n "${FQBN}" ]]; then
4 years ago
ARCH=$(echo "${FQBN}" | sed -n -e 's/^[^:]\+:\([^:]\+\).*/\1/p')
fi
: "${ARCH:=avr}"
: "${FQBN:=keyboardio:${ARCH}:${BOARD}}"
if [ "${ARCH}" = "virtual" ]; then
4 years ago
adjust_for_virtual_build
fi
if [ "${uname_O}" = "Cygwin" ]; then
4 years ago
adjust_for_cygwin
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
4 years ago
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
4 years ago
cmd="$(echo "$1" | tr '-' '_')"
${cmd}
exit $?
fi
SKETCH="$1"
shift
cmds=""
# shellcheck disable=2034
for i in $(seq 1 $#); do
4 years ago
cmds="${cmds} $(echo "$1" | tr '-' '_')"
shift
done
for cmd in ${cmds}; do
4 years ago
${cmd}
done