From d33bdf53e39a27d531adb528272ab9ff358152de Mon Sep 17 00:00:00 2001 From: Dan Bjorge Date: Sat, 26 Oct 2019 13:08:29 -0700 Subject: [PATCH] Add Windows+Cygwin support for kaleidoscope-builder Signed-off-by: Dan Bjorge --- bin/find-device-port-windows.ps1 | 41 ++++++++++++++++++++++++ bin/kaleidoscope-builder | 7 ++-- etc/kaleidoscope-builder.conf | 55 +++++++++++++++++++++++++++++++- 3 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 bin/find-device-port-windows.ps1 diff --git a/bin/find-device-port-windows.ps1 b/bin/find-device-port-windows.ps1 new file mode 100644 index 00000000..0764efd3 --- /dev/null +++ b/bin/find-device-port-windows.ps1 @@ -0,0 +1,41 @@ +# Usage: +# +# > find-device-port-cygwin.ps1 '1209' '2300' -Format COM +# COM7 +# > find-device-port-cygwin.ps1 '1209' '2300' -Format WSL +# /dev/ttyS7 +# > find-device-port-cygwin.ps1 '1209' '2300' -Format Cygwin +# /dev/ttyS6 +Param( + [string]$VendorID, + [string]$ProductID, # Careful; $PID is a different builtin + [ValidateSet('COM','Cygwin','WSL')][string]$Format +) + +$DeviceParametersRegKey = @(Get-ChildItem -ErrorAction SilentlyContinue -Recurse 'HKLM:\SYSTEM\CurrentControlSet\Enum' | + Where-Object Name -match "VID_$VendorID&PID_$ProductID" | + Where-Object Property -eq PortName) + +if ($DeviceParametersRegKey.Count -eq 0) { + throw "Could not find any devices matching VID $VendorID and PID $ProductID which were mapped to a COM port" +} + +if ($DeviceParametersRegKey.Count -ge 2) { + throw "More than one devices matching VID $VendorID and PID $ProductID were found mapped to a COM port" +} + +# This will be of form 'COM6' +$COMPortName = ($DeviceParametersRegKey | Get-ItemProperty).PortName +$COMPortNumber = [int]$COMPortName.Substring(3) + +if ($Format -eq 'COM') { + $Output = $COMPortName +} elseif ($Format -eq 'WSL') { + $Output = "/dev/ttyS$COMPortNumber" +} elseif ($Format -eq 'Cygwin') { + $CygwinPortNumber = $COMPortNumber - 1 + $Output = "/dev/ttyS$CygwinPortNumber" +} + +# "-NoNewline" below is important to prevent bash from seeing an extra trailing '\r' +Write-Host -NoNewline $Output diff --git a/bin/kaleidoscope-builder b/bin/kaleidoscope-builder index 9314092e..0ba3a287 100755 --- a/bin/kaleidoscope-builder +++ b/bin/kaleidoscope-builder @@ -20,7 +20,7 @@ set -e ###### build_version () { - GIT_VERSION="$(cd "$(find_sketch)"; if [ -d .git ]; then echo '-g' && git describe --abbrev=4 --dirty --always; fi)" + GIT_VERSION="$(cd "$(find_sketch)"; if [ -d .git ]; then echo -n '-g' && git describe --abbrev=4 --dirty --always; fi)" LIB_PROPERTIES_PATH="${LIB_PROPERTIES_PATH:-"../.."}" LIB_VERSION="$(cd "$(find_sketch)"; (grep version= "${LIB_PROPERTIES_PATH}/library.properties" 2>/dev/null || echo version=0.0.0) | cut -d= -f2)${GIT_VERSION}" } @@ -57,7 +57,7 @@ build_filenames () { enable_ccache () { - if [ "$(command -v ccache)" ]; then + if [ -z "${CCACHE_NOT_SUPPORTED}" ] && [ "$(command -v ccache)" ]; then if ! [ -d "$CCACHE_WRAPPER_PATH" ]; then mkdir -p "$CCACHE_WRAPPER_PATH" fi @@ -304,12 +304,13 @@ compile () { -ide-version "${ARDUINO_IDE_VERSION}" \ -built-in-libraries "${ARDUINO_PATH}/libraries" \ -prefs "compiler.cpp.extra_flags=-std=c++11 -Woverloaded-virtual -Wno-unused-parameter -Wno-unused-variable -Wno-ignored-qualifiers ${ARDUINO_CFLAGS} ${LOCAL_CFLAGS}" \ + -prefs compiler.path=${COMPILER_PATH} \ $CCACHE_ENABLE \ -warnings all \ ${ARDUINO_VERBOSE} \ ${ARDUINO_AVR_GCC_PREFIX_PARAM} \ "${SKETCH_DIR}/${SKETCH}.ino" - + cp "${BUILD_PATH}/${SKETCH}.ino.hex" "${HEX_FILE_PATH}" cp "${BUILD_PATH}/${SKETCH}.ino.elf" "${ELF_FILE_PATH}" ln -sf "${OUTPUT_FILE_PREFIX}.hex" "${OUTPUT_PATH}/${SKETCH}-latest.hex" diff --git a/etc/kaleidoscope-builder.conf b/etc/kaleidoscope-builder.conf index 0e789c5b..9dd94561 100644 --- a/etc/kaleidoscope-builder.conf +++ b/etc/kaleidoscope-builder.conf @@ -41,6 +41,7 @@ fi ## 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) find_max_prog_size() { @@ -67,7 +68,7 @@ find_device_vid_pid() { -tools "${ARDUINO_PATH}/tools-builder" \ -fqbn "${FQBN}" \ -build-path ${ARDUINO_PATH} \ - -dump-prefs "${SKETCH_DIR}/${SKETCH}.ino" || grep "\.[vp]id=") + -dump-prefs "${SKETCH_DIR}/${SKETCH}.ino" | grep "\.[vp]id=") VID=${VID:-$(echo "${VPIDS}" | grep build.vid= | cut -dx -f2)} SKETCH_PID=${SKETCH_PID:-$(echo "${VPIDS}" | grep build.pid= | cut -dx -f2)} BOOTLOADER_PID=${BOOTLOADER_PID:-$(echo "${VPIDS}" | grep bootloader.pid= | cut -dx -f2)} @@ -160,6 +161,58 @@ elif [ "${uname_S}" = "FreeBSD" ]; then DEVICE_PORT_BOOTLOADER="$(perl ${DEVICE_PORT_PROBER})" } +elif [ "${uname_O}" = "Cygwin" ]; then + # The Windows arduino-builder.exe doesn't understand being told to exec against Cygwin symlinks + CCACHE_NOT_SUPPORTED=1 + + # Note: the default ARDUINO_PATH here is the default Arduino installation path on Windows, but it won't actually + # work in practice right now since we haven't fixed all bugs related to interpretation of spaces in these paths. + # + # 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. + ARDUINO_PATH="${ARDUINO_PATH:-/cygdrive/c/Program\ Files\ (x86)/Arduino}" + ARDUINO_PACKAGE_PATH="${ARDUINO_PACKAGE_PATH:-/cygdrive/c/Users/${USER}/AppData/Local/Arduino15/packages}" + ARDUINO_LOCAL_LIB_PATH="${ARDUINO_LOCAL_LIB_PATH:-/cygdrive/c/Users/${USER}/Arduino}" + TMPDIR="${ARDUINO_LOCAL_LIB_PATH:-/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 + + ARDUINO_PATH="$(realpath --relative-to=./ ${ARDUINO_PATH})" + ARDUINO_PACKAGE_PATH="$(realpath --relative-to=./ ${ARDUINO_PACKAGE_PATH})" + ARDUINO_LOCAL_LIB_PATH="$(realpath --relative-to=./ ${ARDUINO_LOCAL_LIB_PATH})" + ROOT="$(realpath --relative-to=./ ${ROOT})" + export ROOT + TMPDIR="$(realpath --relative-to=./ ${ARDUINO_PATH})" + + find_device_port() { + find_device_vid_pid + DIR=$(dirname "$0") + DEVICE_PORT_PROBER="${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)" + } + + reset_device_cmd() { + cmd /c mode ${DEVICE_COM_PORT} baud=1200 + } + + find_bootloader_ports() { + find_device_vid_pid + DIR=$(dirname "$0") + BOOTLOADER_VID="${BOOTLOADER_VID:-${VID}}" + DEVICE_PORT_PROBER="${DIR}/find-device-port-windows.ps1" + DEVICE_PORT_BOOTLOADER="$(powershell -noprofile -executionpolicy bypass ${DEVICE_PORT_PROBER} ${BOOTLOADER_VID} ${BOOTLOADER_PID} -Format COM)" + } + fi ######