Skip to content

Commit 1f86311

Browse files
Add Win32 build to CI system (esp8266#6493)
Build a single INO under a Windows VM on Travis to ensure that the Win32 toolchain works properly. In build.py, instead of making a string with spaces and then splitting on " ", just make the list itself with individual parameters. This will allow spaces in paths to be supported properly.
1 parent 4f74ed8 commit 1f86311

File tree

4 files changed

+99
-35
lines changed

4 files changed

+99
-35
lines changed

.travis.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,18 @@ jobs:
107107
script: $TRAVIS_BUILD_DIR/tests/buildm.sh
108108
env: CC=gcc-7 CXX=g++-7
109109

110-
- name: "MacOS can build sketches"
110+
- name: "Mac OSX can build sketches"
111111
os: osx
112112
stage: build
113113
script: $TRAVIS_BUILD_DIR/tests/build.sh
114114
env: MACOSX=1 BUILD_PARITY=custom mod=500 rem=1
115115

116+
- name: "Windows can build sketches"
117+
os: windows
118+
stage: build
119+
script: $TRAVIS_BUILD_DIR/tests/build.sh
120+
env: WINDOWS=1 BUILD_PARITY=custom mod=500 rem=1
121+
116122
- name: "Boards"
117123
stage: build
118124
script: $TRAVIS_BUILD_DIR/tests/ci/build_boards.sh

tests/common.sh

+41-10
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ function print_size_info()
4444
segments[$seg]=$size
4545
fi
4646

47-
48-
done < <(xtensa-lx106-elf-size --format=sysv $elf_file)
47+
done < <(xtensa-lx106-elf-size --format=sysv $elf_file | sed 's/\r//g' )
4948

5049
total_ram=$((${segments[data]} + ${segments[rodata]} + ${segments[bss]}))
5150
total_flash=$((${segments[data]} + ${segments[rodata]} + ${segments[text]} + ${segments[irom0text]}))
@@ -66,6 +65,10 @@ function build_sketches()
6665
local lwip=$6
6766
mkdir -p $build_dir
6867
local build_cmd="python3 tools/build.py -b generic -v -w all -s 4M1M -v -k --build_cache $cache_dir -p $PWD/$build_dir -n $lwip $build_arg "
68+
if [ "$WINDOWS" = "1" ]; then
69+
# Paths to the arduino builder need to be / referenced, not our native ones
70+
build_cmd=$(echo $build_cmd --ide_path $arduino | sed 's/ \/c\// \//g' ) # replace '/c/' with '/'
71+
fi
6972
local sketches=$(find $srcpath -name *.ino | sort)
7073
print_size_info >size.log
7174
export ARDUINO_IDE_PATH=$arduino
@@ -107,6 +110,14 @@ function build_sketches()
107110
fi
108111
echo -e "\n ------------ Building $sketch ------------ \n";
109112
# $arduino --verify $sketch;
113+
if [ "$WINDOWS" == "1" ]; then
114+
sketch=$(echo $sketch | sed 's/^\/c//')
115+
# MINGW will try to be helpful and silently convert args that look like paths to point to a spot inside the MinGW dir. This breaks everything.
116+
# http://www.mingw.org/wiki/Posix_path_conversion
117+
# https://stackoverflow.com/questions/7250130/how-to-stop-mingw-and-msys-from-mangling-path-names-given-at-the-command-line#34386471
118+
export MSYS2_ARG_CONV_EXC="*"
119+
export MSYS_NO_PATHCONV=1
120+
fi
110121
echo "$build_cmd $sketch"
111122
time ($build_cmd $sketch >build.log)
112123
local result=$?
@@ -135,7 +146,7 @@ function install_libraries()
135146
pushd $HOME/Arduino/libraries
136147

137148
# install ArduinoJson library
138-
{ test -r ArduinoJson-v6.11.0.zip || wget https://github.com/bblanchon/ArduinoJson/releases/download/v6.11.0/ArduinoJson-v6.11.0.zip; } && unzip -q ArduinoJson-v6.11.0.zip
149+
{ test -r ArduinoJson-v6.11.0.zip || wget -nv https://github.com/bblanchon/ArduinoJson/releases/download/v6.11.0/ArduinoJson-v6.11.0.zip; } && unzip -q ArduinoJson-v6.11.0.zip
139150

140151
popd
141152
}
@@ -145,17 +156,27 @@ function install_ide()
145156
local ide_path=$1
146157
local core_path=$2
147158
local debug=$3
148-
if [ "$MACOSX" = "1" ]; then
159+
if [ "$WINDOWS" = "1" ]; then
160+
# Acquire needed packages from Windows package manager
161+
choco install --no-progress python3
162+
export PATH="/c/Python37:$PATH" # Ensure it's live from now on...
163+
cp /c/Python37/python.exe /c/Python37/python3.exe
164+
choco install --no-progress unzip
165+
choco install --no-progress sed
166+
#choco install --no-progress golang
167+
test -r arduino-nightly-windows.zip || wget -nv -O arduino-nightly-windows.zip https://www.arduino.cc/download.php?f=/arduino-nightly-windows.zip
168+
unzip -q arduino-nightly-windows.zip
169+
elif [ "$MACOSX" = "1" ]; then
149170
# MACOS only has next-to-obsolete Python2 installed. Install Python 3 from python.org
150171
wget https://www.python.org/ftp/python/3.7.4/python-3.7.4-macosx10.9.pkg
151172
sudo installer -pkg python-3.7.4-macosx10.9.pkg -target /
152173
# Install the Python3 certificates, because SSL connections fail w/o them and of course they aren't installed by default.
153-
( cd "/Applications/Python 3.7/" && sudo "./Install Certificates.command" )
174+
( cd "/Applications/Python 3.7/" && sudo "./Install Certificates.command" )
154175
# Hack to place arduino-builder in the same spot as sane OSes
155176
test -r arduino.zip || wget -O arduino.zip https://downloads.arduino.cc/arduino-nightly-macosx.zip
156177
unzip -q arduino.zip
157-
mv Arduino.app arduino-nightly
158-
mv arduino-nightly/Contents/Java/* arduino-nightly/.
178+
mv Arduino.app arduino-nightly
179+
mv arduino-nightly/Contents/Java/* arduino-nightly/.
159180
else
160181
test -r arduino.tar.xz || wget -O arduino.tar.xz https://www.arduino.cc/download.php?f=/arduino-nightly-linux64.tar.xz
161182
tar xf arduino.tar.xz
@@ -164,7 +185,11 @@ function install_ide()
164185
cd $ide_path/hardware
165186
mkdir esp8266com
166187
cd esp8266com
167-
ln -s $core_path esp8266
188+
if [ "$WINDOWS" = "1" ]; then
189+
cp -a $core_path esp8266
190+
else
191+
ln -s $core_path esp8266
192+
fi
168193
local debug_flags=""
169194
if [ "$debug" = "debug" ]; then
170195
debug_flags="-DDEBUG_ESP_PORT=Serial -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_OOM"
@@ -176,8 +201,14 @@ function install_ide()
176201
cat esp8266/platform.local.txt
177202
echo -e "\n----\n"
178203
cd esp8266/tools
179-
python3 get.py
180-
export PATH="$ide_path:$core_path/tools/xtensa-lx106-elf/bin:$PATH"
204+
python3 get.py -q
205+
if [ "$WINDOWS" = "1" ]; then
206+
# Because the symlinks don't work well under Win32, we need to add the path to this copy, not the original...
207+
relbin=$(realpath $PWD/xtensa-lx106-elf/bin)
208+
export PATH="$ide_path:$relbin:$PATH"
209+
else
210+
export PATH="$ide_path:$core_path/tools/xtensa-lx106-elf/bin:$PATH"
211+
fi
181212
}
182213

183214
function install_arduino()

tools/build.py

+37-20
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,42 @@
2424
import sys
2525
import os
2626
import argparse
27+
import platform
2728
import subprocess
2829
import tempfile
2930
import shutil
3031

32+
33+
# Arduino-builder needs forward-slash paths for passed in params or it cannot
34+
# launch the needed toolset.
35+
def windowsize_paths(l):
36+
"""Convert forward-slash paths to backslash paths referenced from C:"""
37+
out = []
38+
for i in l:
39+
if i.startswith('/'):
40+
i = 'C:' + i
41+
out += [i.replace('/', '\\')]
42+
return out
43+
3144
def compile(tmp_dir, sketch, cache, tools_dir, hardware_dir, ide_path, f, args):
32-
cmd = ide_path + '/arduino-builder '
33-
cmd += '-compile -logger=human '
34-
cmd += '-build-path "' + tmp_dir + '" '
35-
cmd += '-tools "' + ide_path + '/tools-builder" '
45+
cmd = []
46+
cmd += [ide_path + '/arduino-builder']
47+
cmd += ['-compile', '-logger=human']
48+
cmd += ['-build-path', tmp_dir]
49+
cmd += ['-tools', ide_path + '/tools-builder']
3650
if cache != "":
37-
cmd += '-build-cache "' + cache + '" '
51+
cmd += ['-build-cache', cache ]
3852
if args.library_path:
3953
for lib_dir in args.library_path:
40-
cmd += '-libraries "' + lib_dir + '" '
41-
cmd += '-hardware "' + ide_path + '/hardware" '
54+
cmd += ['-libraries', lib_dir]
55+
cmd += ['-hardware', ide_path + '/hardware']
4256
if args.hardware_dir:
4357
for hw_dir in args.hardware_dir:
44-
cmd += '-hardware "' + hw_dir + '" '
58+
cmd += ['-hardware', hw_dir]
4559
else:
46-
cmd += '-hardware "' + hardware_dir + '" '
60+
cmd += ['-hardware', hardware_dir]
4761
# Debug=Serial,DebugLevel=Core____
48-
cmd += '-fqbn=esp8266com:esp8266:{board_name}:' \
62+
fqbn = '-fqbn=esp8266com:esp8266:{board_name}:' \
4963
'xtal={cpu_freq},' \
5064
'FlashFreq={flash_freq},' \
5165
'FlashMode={flash_mode},' \
@@ -54,20 +68,22 @@ def compile(tmp_dir, sketch, cache, tools_dir, hardware_dir, ide_path, f, args):
5468
'ip={lwIP},' \
5569
'ResetMethod=nodemcu'.format(**vars(args))
5670
if args.debug_port and args.debug_level:
57-
cmd += 'dbg={debug_port},lvl={debug_level}'.format(**vars(args))
58-
cmd += ' '
59-
cmd += '-built-in-libraries "' + ide_path + '/libraries" '
60-
cmd += '-ide-version=10607 '
61-
cmd += '-warnings={warnings} '.format(**vars(args))
71+
fqbn += 'dbg={debug_port},lvl={debug_level}'.format(**vars(args))
72+
cmd += [fqbn]
73+
cmd += ['-built-in-libraries', ide_path + '/libraries']
74+
cmd += ['-ide-version=10607']
75+
cmd += ['-warnings={warnings}'.format(**vars(args))]
6276
if args.verbose:
63-
cmd += '-verbose '
64-
cmd += sketch
77+
cmd += ['-verbose']
78+
cmd += [sketch]
79+
80+
if platform.system() == "Windows":
81+
cmd = windowsize_paths(cmd)
6582

6683
if args.verbose:
67-
print('Building: ' + cmd, file=f)
84+
print('Building: ' + " ".join(cmd), file=f)
6885

69-
cmds = cmd.split(' ')
70-
p = subprocess.Popen(cmds, stdout=f, stderr=subprocess.STDOUT)
86+
p = subprocess.Popen(cmd, stdout=f, stderr=subprocess.STDOUT)
7187
p.wait()
7288
return p.returncode
7389

@@ -127,6 +143,7 @@ def main():
127143
hardware_dir = os.path.dirname(os.path.realpath(__file__)) + '/../cores'
128144

129145
output_name = tmp_dir + '/' + os.path.basename(sketch_path) + '.bin'
146+
130147
if args.verbose:
131148
print("Sketch: ", sketch_path)
132149
print("Build dir: ", tmp_dir)

tools/get.py

+14-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
import tarfile
1616
import zipfile
1717
import re
18+
19+
verbose = True
20+
1821
if sys.version_info[0] == 3:
1922
from urllib.request import urlretrieve
2023
else:
@@ -38,10 +41,12 @@ def mkdir_p(path):
3841
raise
3942

4043
def report_progress(count, blockSize, totalSize):
41-
percent = int(count*blockSize*100/totalSize)
42-
percent = min(100, percent)
43-
sys.stdout.write("\r%d%%" % percent)
44-
sys.stdout.flush()
44+
global verbose
45+
if verbose:
46+
percent = int(count*blockSize*100/totalSize)
47+
percent = min(100, percent)
48+
sys.stdout.write("\r%d%%" % percent)
49+
sys.stdout.flush()
4550

4651
def unpack(filename, destination):
4752
dirname = ''
@@ -111,6 +116,11 @@ def identify_platform():
111116
return arduino_platform_names[sys_name][bits]
112117

113118
def main():
119+
global verbose
120+
# Support optional "-q" quiet mode simply
121+
if len(sys.argv) == 2:
122+
if sys.argv[1] == "-q":
123+
verbose = False
114124
print('Platform: {0}'.format(identify_platform()))
115125
tools_to_download = load_tools_list('../package/package_esp8266com_index.template.json', identify_platform())
116126
mkdir_p(dist_dir)

0 commit comments

Comments
 (0)