diff --git a/.travis.yml b/.travis.yml index 3e0427b48..b15bc89e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,8 +15,7 @@ script: - export CXX="g++-4.8" CC="gcc-4.8" GCOV="gcov-4.8" - pushd $TRAVIS_BUILD_DIR/tests/host - make - - bash <(curl -s https://codecov.io/bash) -X gcov - - make clean + - make clean-objects - popd - wget -O arduino.tar.xz https://www.arduino.cc/download.php?f=/arduino-nightly-linux64.tar.xz - tar xf arduino.tar.xz @@ -34,10 +33,12 @@ script: - which arduino - cd $TRAVIS_BUILD_DIR - source tests/common.sh - - arduino --board esp8266com:esp8266:generic --save-prefs - - arduino --get-pref sketchbook.path - install_libraries - - build_sketches arduino $TRAVIS_BUILD_DIR + - build_sketches $HOME/arduino_ide $TRAVIS_BUILD_DIR "python tools/build.py -l $HOME/Arduino/libraries -b generic -v" + +after_success: + - pushd $TRAVIS_BUILD_DIR/tests/host + - bash <(curl -s https://codecov.io/bash) -X gcov notifications: email: diff --git a/tests/common.sh b/tests/common.sh index 1d674081c..c770d6e3f 100755 --- a/tests/common.sh +++ b/tests/common.sh @@ -4,7 +4,10 @@ function build_sketches() { local arduino=$1 local srcpath=$2 + local build_cmd=$3 + echo $build_cmd local sketches=$(find $srcpath -name *.ino) + export ARDUINO_IDE_PATH=$arduino for sketch in $sketches; do local sketchdir=$(dirname $sketch) if [[ -f "$sketchdir/.test.skip" ]]; then @@ -12,7 +15,9 @@ function build_sketches() continue fi echo -e "\n\n ------------ Building $sketch ------------ \n\n"; - $arduino --verify $sketch; + # $arduino --verify $sketch; + echo "$build_cmd $sketch" + time $build_cmd $sketch local result=$? if [ $result -ne 0 ]; then echo "Build failed ($1)" @@ -25,7 +30,7 @@ function install_libraries() { mkdir -p $HOME/Arduino/libraries pushd $HOME/Arduino/libraries - + # install ArduinoJson library wget https://github.com/bblanchon/ArduinoJson/releases/download/v4.6.1/ArduinoJson-v4.6.1.zip && unzip ArduinoJson-v4.6.1.zip diff --git a/tests/host/Makefile b/tests/host/Makefile index 122dd94bd..37ee1e841 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -62,9 +62,13 @@ all: build-info $(OUTPUT_BINARY) test gcov test: $(OUTPUT_BINARY) $(OUTPUT_BINARY) -clean: +clean: clean-objects clean-coverage rm -rf $(BINARY_DIRECTORY) + +clean-objects: rm -rf $(OBJECTS) + +clean-coverage: rm -rf $(COVERAGE_FILES) *.gcov gcov: test diff --git a/tools/build.py b/tools/build.py new file mode 100755 index 000000000..636ce047f --- /dev/null +++ b/tools/build.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# build.py — build a sketch using arduino-builder +# +# Wrapper script around arduino-builder which accepts some ESP8266-specific +# options and translates them into FQBN +# +# Copyright © 2016 Ivan Grokhotkov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# + + +from __future__ import print_function +import sys +import os +import argparse +import serial +import subprocess +import tempfile +import shutil + +def compile(tmp_dir, sketch, tools_dir, hardware_dir, ide_path, f, args): + cmd = ide_path + '/arduino-builder ' + cmd += '-compile -logger=human ' + for lib_dir in args.library_path: + cmd += '-libraries "' + lib_dir + '" ' + cmd += '-build-path "' + tmp_dir + '" ' + cmd += '-hardware "' + ide_path + '/hardware" ' + cmd += '-hardware ' + hardware_dir + ' ' + cmd += '-tools "' + ide_path + '/tools-builder" ' + # Debug=Serial,DebugLevel=Core____ + cmd += '-fqbn=esp8266com:esp8266:{board_name}:' \ + 'UploadTool=esptool,' \ + 'CpuFrequency={cpu_freq},' \ + 'FlashFreq={flash_freq},' \ + 'FlashMode={flash_mode},' \ + 'UploadSpeed=921600,' \ + 'FlashSize={flash_size},' \ + 'ResetMethod=nodemcu'.format(**vars(args)) + if args.debug_port and args.debug_level: + cmd += 'Debug={debug_port},DebugLevel={debug_level}'.format(**vars(args)) + cmd += ' ' + cmd += '-ide-version=10607 ' + cmd += '-warnings={warnings} '.format(**vars(args)) + if args.verbose: + cmd += '-verbose ' + cmd += sketch + + if args.verbose: + print('Building: ' + cmd, file=f) + + cmds = cmd.split(' ') + p = subprocess.Popen(cmds, stdout=f, stderr=subprocess.STDOUT) + p.wait() + return p.returncode + +def parse_args(): + parser = argparse.ArgumentParser(description='Sketch build helper') + parser.add_argument('-v', '--verbose', help='Enable verbose output', + action='store_true') + parser.add_argument('-i', '--ide_path', help='Arduino IDE path') + parser.add_argument('-p', '--build_path', help='Build directory') + parser.add_argument('-l', '--library_path', help='Additional library path', + action='append') + parser.add_argument('-b', '--board_name', help='Board name', default='generic') + parser.add_argument('-s', '--flash_size', help='Flash size', default='512K64', + choices=['512K0', '512K64', '1M512', '4M1M', '4M3M']) + parser.add_argument('-f', '--cpu_freq', help='CPU frequency', default=80, + choices=[80, 160], type=int) + parser.add_argument('-m', '--flash_mode', help='Flash mode', default='qio', + choices=['dio', 'qio']) + parser.add_argument('-w', '--warnings', help='Compilation warnings level', + default='none', choices=['none', 'all', 'more']) + parser.add_argument('-o', '--output_binary', help='File name for output binary') + parser.add_argument('-k', '--keep', action='store_true', + help='Don\'t delete temporary build directory') + parser.add_argument('--flash_freq', help='Flash frequency', default=40, + type=int, choices=[40, 80]) + parser.add_argument('--debug_port', help='Debug port', + choices=['Serial', 'Serial1']) + parser.add_argument('--debug_level', help='Debug level') + parser.add_argument('sketch_path', help='Sketch file path') + return parser.parse_args() + +def main(): + args = parse_args() + + ide_path = args.ide_path + if not ide_path: + ide_path = os.environ.get('ARDUINO_IDE_PATH') + if not ide_path: + print("Please specify Arduino IDE path via --ide_path option" + "or ARDUINO_IDE_PATH environment variable.", file=sys.stderr) + return 2 + + sketch_path = args.sketch_path + tmp_dir = args.build_path + created_tmp_dir = False + if not tmp_dir: + tmp_dir = tempfile.mkdtemp() + created_tmp_dir = True + + tools_dir = os.path.dirname(os.path.realpath(__file__)) + '/../tools' + hardware_dir = os.path.dirname(os.path.realpath(__file__)) + '/../cores' + + output_name = tmp_dir + '/' + os.path.basename(sketch_path) + '.bin' + if args.verbose: + print("Sketch: ", sketch_path) + print("Build dir: ", tmp_dir) + print("Output: ", output_name) + + if args.verbose: + f = sys.stdout + else: + f = open(tmp_dir + '/build.log', 'w') + + res = compile(tmp_dir, sketch_path, tools_dir, hardware_dir, ide_path, f, args) + if res != 0: + return res + + if args.output_binary is not None: + shutil.copy(output_name, args.output_binary) + + if created_tmp_dir and not args.keep: + shutil.rmtree(tmp_dir, ignore_errors=True) + +if __name__ == '__main__': + sys.exit(main())