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

282 lines
7.1 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
######
_read_conf_files() {
for conf_file in \
"$(pwd)/.kaleidoscope-builder.conf"; do \
if [ -e "${conf_file}" ]; then
# shellcheck disable=SC1090
. "${conf_file}"
fi
done
}
cmd_configure_arduino_cli() {
if [ -z "${ARDUINO_CLI}" ]; then
cmd_install_arduino_cli
fi
if [ -z "${ARDUINO_CLI_CONFIG}" ]; then
_run_arduino_cli config init
fi
}
_run_arduino_cli() {
"${ARDUINO_CLI}" "$@"
}
_arduino_prop() {
pref=$1
# Strip the preference name. And then strip leading and trailing quotations
_arduino_props | grep --max-count=1 "${pref}=" | sed -e s/^.*"${pref}"=// -e 's/^"//' -e 's/"$//'
}
_arduino_props() {
if [ "x${_ARDUINO_PREFS}x" == "xx" ]; then
_ARDUINO_PREFS=$(_run_arduino_cli --fqbn "${FQBN}" compile --show-properties "${SKETCH_FILE_PATH}")
fi
echo "$_ARDUINO_PREFS"
}
_set_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=$(_arduino_prop 'runtime.tools.avr-gcc.path')/bin}"
# Allow the compiler prefix to be empty for virtual builds
COMPILER_PREFIX="${COMPILER_PREFIX-avr-}"
: "${AVR_OBJDUMP:=${COMPILER_PATH}/${COMPILER_PREFIX}objdump}"
: "${AVR_OBJCOPY:=${COMPILER_PATH}/${COMPILER_PREFIX}objcopy}"
: "${AVR_NM:=${COMPILER_PATH}/${COMPILER_PREFIX}nm}"
: "${AVR_SIZE:=${COMPILER_PATH}/${COMPILER_PREFIX}size}"
}
_set_build_paths() {
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}"
: "${BOOTLOADER_PATH:=$(_arduino_prop 'runtime.platform.path')/bootloaders/$(_arduino_prop 'bootloader.file')}"
: "${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}"
mkdir -p "$BUILD_PATH"
}
_absolute_filename() {
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}
_find_sketch() {
if [ -z "${SKETCH_FILE_PATH}" ] || [ ! -f "${SKETCH_FILE_PATH}" ]; then
# Didn't find a sketch
echo "I couldn't find your sketch (.ino file)" >&2
exit 1
fi
}
cmd_flash() {
_set_up_environment
#TODO (arduino team) I'd love to do this with their json output
#but it's short some of the data we kind of need
port=$(_run_arduino_cli board list --format=text | grep "$FQBN" |cut -d' ' -f 1)
flashing_instructions=$(_arduino_prop 'build.flashing_instructions')
: "${flashing_instructions:="If your keyboard needs you to do something to put it in flashing mode, do that now."}"
printf '%b\n\n' "${flashing_instructions}"
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
_run_arduino_cli upload --fqbn "${FQBN}" --port "${port}" "${ARDUINO_VERBOSE}"
}
cmd_hex_with_bootloader() {
_set_up_environment
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
}
cmd_compile() {
_set_up_environment
install -d "${OUTPUT_PATH}"
echo "Building ${SKETCH_FILE_PATH}"
# This is defined in the (optional) user config.
# shellcheck disable=SC2154
${compile_HOOKS}
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
# shellcheck disable=SC2086
_run_arduino_cli compile \
--fqbn "${FQBN}" \
--libraries "${KALEIDOSCOPE_DIR}/.." \
--build-path "${BUILD_PATH}" \
--output-dir "${OUTPUT_PATH}" \
--build-cache-path "${CORE_CACHE_PATH}" \
--build-properties "compiler.cpp.extra_flags=${LOCAL_CFLAGS}" \
--warnings all ${ARDUINO_VERBOSE} \
"${SKETCH_FILE_PATH}"
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
}
cmd_size_map() {
_set_up_environment
"${AVR_NM}" --size-sort -C -r -l -t decimal "${ELF_FILE_PATH}"
}
cmd_disassemble() {
_set_up_environment
"${AVR_OBJDUMP}" -C -d "${ELF_FILE_PATH}"
}
cmd_clean() {
_set_up_environment
if [ -d "$OUTPUT_PATH" ]; then
rm -rf -- "${OUTPUT_PATH}"
fi
}
_set_up_environment() {
_find_sketch
_set_build_paths
_set_executable_paths
}
cmd_help() {
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.
clean
Cleans up the output directory.
size-map
Displays the size map for the sketch.
disassemble
Decompile the sketch.
flash
Flashes the firmware using avrdude.
EOF
}
if [ $# -lt 1 ]; then
cmd_help
exit 1
fi
_read_conf_files
# shellcheck disable=SC1090
if [[ -z "${ARCH}" && -n "${FQBN}" ]]; then
ARCH=$(echo "${FQBN}" | sed -n -e 's/^[^:]\+:\([^:]\+\).*/\1/p')
fi
: "${BOARD:=model01}"
: "${ARCH:=avr}"
: "${FQBN:=keyboardio:${ARCH}:${BOARD}}"
if [ $# -eq 1 ]; then
cmd="$(echo "$1" | tr '-' '_')"
"cmd_${cmd}"
exit $?
else
"You passed more than two arguments to $0"
help
exit 1
/
fi