mirror of
https://github.com/arduino/Arduino.git
synced 2024-11-29 10:24:12 +01:00
commit
97eb263a36
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,6 +14,7 @@ hardware/arduino/bootloaders/caterina_LUFA/Caterina.elf
|
||||
hardware/arduino/bootloaders/caterina_LUFA/Caterina.eep
|
||||
hardware/arduino/bootloaders/caterina_LUFA/.dep/
|
||||
build/*.zip
|
||||
build/*.tar.bz2
|
||||
build/windows/work/
|
||||
build/windows/*.zip
|
||||
build/windows/*.tgz
|
||||
|
@ -116,9 +116,9 @@ public class ConsoleOutputStream extends ByteArrayOutputStream {
|
||||
if (document != null) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
try {
|
||||
String lineWithoutSlashR = line.replace("\r\n", "\n").replace("\r", "\n");
|
||||
String lineWithoutCR = line.replace("\r\n", "\n").replace("\r", "\n");
|
||||
int offset = document.getLength();
|
||||
document.insertString(offset, lineWithoutSlashR, attributes);
|
||||
document.insertString(offset, lineWithoutCR, attributes);
|
||||
} catch (BadLocationException ble) {
|
||||
//ignore
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
|
@ -750,6 +750,10 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
item = newJMenuItemAlt(tr("Export compiled Binary"), 'S');
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (new ShouldSaveReadOnly().test(sketch) && !handleSave(true)) {
|
||||
System.out.println(tr("Export canceled, changes must first be saved."));
|
||||
return;
|
||||
}
|
||||
handleRun(false, new ShouldSaveReadOnly(), Editor.this.presentAndSaveHandler, Editor.this.runAndSaveHandler);
|
||||
}
|
||||
});
|
||||
|
@ -23,11 +23,14 @@
|
||||
|
||||
package processing.app;
|
||||
|
||||
import cc.arduino.Compiler;
|
||||
import cc.arduino.CompilerProgressListener;
|
||||
import cc.arduino.UploaderUtils;
|
||||
import cc.arduino.files.DeleteFilesOnShutdown;
|
||||
import cc.arduino.packages.Uploader;
|
||||
import processing.app.debug.Compiler;
|
||||
import processing.app.debug.Compiler.ProgressListener;
|
||||
import processing.app.debug.RunnerException;
|
||||
import processing.app.forms.PasswordAuthorizationDialog;
|
||||
import processing.app.helpers.FileUtils;
|
||||
import processing.app.helpers.OSUtils;
|
||||
import processing.app.helpers.PreferencesMapException;
|
||||
import processing.app.packages.LibraryList;
|
||||
@ -37,10 +40,14 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static processing.app.I18n.tr;
|
||||
|
||||
@ -60,7 +67,7 @@ public class Sketch {
|
||||
private int currentIndex;
|
||||
|
||||
private final SketchData data;
|
||||
|
||||
|
||||
/**
|
||||
* path is location of the main .pde file, because this is also
|
||||
* simplest to use when opening the file from the finder/explorer.
|
||||
@ -1093,7 +1100,7 @@ public class Sketch {
|
||||
* @return null if compilation failed, main class name if not
|
||||
* @throws RunnerException
|
||||
*/
|
||||
public String build(boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
|
||||
public String build(boolean verbose, boolean save) throws RunnerException, PreferencesMapException, IOException {
|
||||
return build(tempBuildFolder.getAbsolutePath(), verbose, save);
|
||||
}
|
||||
|
||||
@ -1106,15 +1113,32 @@ public class Sketch {
|
||||
*
|
||||
* @return null if compilation failed, main class name if not
|
||||
*/
|
||||
private String build(String buildPath, boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
|
||||
private String build(String buildPath, boolean verbose, boolean save) throws RunnerException, PreferencesMapException, IOException {
|
||||
// run the preprocessor
|
||||
editor.status.progressUpdate(20);
|
||||
|
||||
ensureExistence();
|
||||
|
||||
ProgressListener pl = editor.status::progressUpdate;
|
||||
|
||||
return Compiler.build(data, buildPath, tempBuildFolder, pl, verbose, save);
|
||||
|
||||
CompilerProgressListener progressListener = editor.status::progressUpdate;
|
||||
|
||||
String pathToSketch = data.getMainFilePath();
|
||||
if (isModified()) {
|
||||
pathToSketch = saveSketchInTempFolder();
|
||||
}
|
||||
|
||||
return new Compiler(pathToSketch, data, buildPath).build(progressListener, save);
|
||||
}
|
||||
|
||||
private String saveSketchInTempFolder() throws IOException {
|
||||
File tempFolder = FileUtils.createTempFolder();
|
||||
DeleteFilesOnShutdown.add(tempFolder);
|
||||
FileUtils.copy(getFolder(), tempFolder);
|
||||
|
||||
for (SketchCode sc : Stream.of(data.getCodes()).filter(SketchCode::isModified).collect(Collectors.toList())) {
|
||||
Files.write(Paths.get(tempFolder.getAbsolutePath(), sc.getFileName()), sc.getProgram().getBytes());
|
||||
}
|
||||
|
||||
return Paths.get(tempFolder.getAbsolutePath(), data.getPrimaryFile().getName()).toString();
|
||||
}
|
||||
|
||||
protected boolean exportApplet(boolean usingProgrammer) throws Exception {
|
||||
@ -1153,7 +1177,7 @@ public class Sketch {
|
||||
|
||||
private boolean upload(String buildPath, String suggestedClassName, boolean usingProgrammer) throws Exception {
|
||||
|
||||
Uploader uploader = Compiler.getUploaderByPreferences(false);
|
||||
Uploader uploader = new UploaderUtils().getUploaderByPreferences(false);
|
||||
|
||||
boolean success = false;
|
||||
do {
|
||||
@ -1172,7 +1196,7 @@ public class Sketch {
|
||||
|
||||
List<String> warningsAccumulator = new LinkedList<>();
|
||||
try {
|
||||
success = Compiler.upload(data, uploader, buildPath, suggestedClassName, usingProgrammer, false, warningsAccumulator);
|
||||
success = new UploaderUtils().upload(data, uploader, buildPath, suggestedClassName, usingProgrammer, false, warningsAccumulator);
|
||||
} finally {
|
||||
if (uploader.requiresAuthorization() && !success) {
|
||||
PreferencesData.remove(uploader.getAuthorizationKey());
|
||||
|
@ -1,62 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2004-08 Ben Fry and Casey Reas
|
||||
Copyright (c) 2001-04 Massachusetts Institute of Technology
|
||||
|
||||
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; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.app.debug;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
||||
/**
|
||||
* OutputStream to handle stdout/stderr messages.
|
||||
* <P>
|
||||
* This is used by Editor, System.err is set to
|
||||
* new PrintStream(new MessageStream()).
|
||||
* It's also used by Compiler.
|
||||
*/
|
||||
class MessageStream extends OutputStream {
|
||||
|
||||
MessageConsumer messageConsumer;
|
||||
|
||||
public MessageStream(MessageConsumer messageConsumer) {
|
||||
this.messageConsumer = messageConsumer;
|
||||
}
|
||||
|
||||
public void close() { }
|
||||
|
||||
public void flush() { }
|
||||
|
||||
public void write(byte b[]) {
|
||||
// this never seems to get called
|
||||
System.out.println("leech1: " + new String(b));
|
||||
}
|
||||
|
||||
public void write(byte b[], int offset, int length) {
|
||||
//System.out.println("leech2: " + new String(b));
|
||||
this.messageConsumer.message(new String(b, offset, length));
|
||||
}
|
||||
|
||||
public void write(int b) {
|
||||
// this never seems to get called
|
||||
System.out.println("leech3: '" + ((char)b) + "'");
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
|
||||
package cc.arduino.i18n;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class ExternalProcessOutputParserTest {
|
||||
|
||||
@Test
|
||||
public void testParser1() throws Exception {
|
||||
Map<String, Object> output = new ExternalProcessOutputParser().parse("===WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}' ||| [ Wire Uncategorized]");
|
||||
|
||||
assertEquals("WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}'", output.get("msg"));
|
||||
Object[] args = (Object[]) output.get("args");
|
||||
assertEquals(3, args.length);
|
||||
assertEquals("", args[0]);
|
||||
assertEquals("Wire", args[1]);
|
||||
assertEquals("Uncategorized", args[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParser2() throws Exception {
|
||||
Map<String, Object> output = new ExternalProcessOutputParser().parse("===Using previously compiled file: {0} ||| [%2Ftmp%2Farduino-sketch-456612873D8321DA02916066CB8B2FE6%2Flibraries%2FBridge%2FBridge.cpp.o]");
|
||||
|
||||
assertEquals("Using previously compiled file: {0}", output.get("msg"));
|
||||
Object[] args = (Object[]) output.get("args");
|
||||
assertEquals(1, args.length);
|
||||
assertEquals("/tmp/arduino-sketch-456612873D8321DA02916066CB8B2FE6/libraries/Bridge/Bridge.cpp.o", args[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParser3() throws Exception {
|
||||
Map<String, Object> output = new ExternalProcessOutputParser().parse("===Using library {0} at version {1} in folder: {2} {3} {4} ||| [Stepper 1.1.1 %2Fhome%2Ffederico%2Fmateriale%2Fworks_Arduino%2FArduino%2Fbuild%2Flinux%2Fwork%2Flibraries%2FStepper ]");
|
||||
|
||||
assertEquals("Using library {0} at version {1} in folder: {2} {3} {4}", output.get("msg"));
|
||||
Object[] args = (Object[]) output.get("args");
|
||||
assertEquals(5, args.length);
|
||||
assertEquals("Stepper", args[0]);
|
||||
assertEquals("1.1.1", args[1]);
|
||||
assertEquals("/home/federico/materiale/works_Arduino/Arduino/build/linux/work/libraries/Stepper", args[2]);
|
||||
assertEquals("", args[3]);
|
||||
assertEquals("", args[4]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParser4() throws Exception {
|
||||
Map<String, Object> output = new ExternalProcessOutputParser().parse("==={0} ||| []");
|
||||
|
||||
assertEquals("{0}", output.get("msg"));
|
||||
Object[] args = (Object[]) output.get("args");
|
||||
assertEquals(0, args.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParser5() throws Exception {
|
||||
Map<String, Object> output = new ExternalProcessOutputParser().parse("==={0} ||| [ ]");
|
||||
|
||||
assertEquals("{0}", output.get("msg"));
|
||||
Object[] args = (Object[]) output.get("args");
|
||||
assertEquals(1, args.length);
|
||||
assertEquals("", args[0]);
|
||||
}
|
||||
|
||||
}
|
56
app/test/cc/arduino/i18n/I18NTest.java
Normal file
56
app/test/cc/arduino/i18n/I18NTest.java
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
|
||||
package cc.arduino.i18n;
|
||||
|
||||
import org.junit.Test;
|
||||
import processing.app.AbstractWithPreferencesTest;
|
||||
import processing.app.I18n;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class I18NTest extends AbstractWithPreferencesTest {
|
||||
|
||||
@Test
|
||||
public void testMessageFormat() throws Exception {
|
||||
Object[] args = new Object[]{"a", "b", "c"};
|
||||
String actual = I18n.format("WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}'", args);
|
||||
assertEquals("WARNING: Category 'a' in library b is not valid. Setting to 'c'", actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageFormatFromExternalProcess() throws Exception {
|
||||
Map<String, Object> output = new ExternalProcessOutputParser().parse("===WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}' ||| [ Wire Uncategorized]");
|
||||
|
||||
String actual = I18n.format((String) output.get("msg"), (Object[])output.get("args"));
|
||||
assertEquals("WARNING: Category '' in library Wire is not valid. Setting to 'Uncategorized'", actual);
|
||||
}
|
||||
}
|
@ -30,13 +30,13 @@
|
||||
package processing.app.debug;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static processing.app.debug.Compiler.unescapeDepFile;
|
||||
import static processing.app.debug.OldCompiler.unescapeDepFile;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import processing.app.AbstractWithPreferencesTest;
|
||||
|
||||
public class CompilerTest extends AbstractWithPreferencesTest {
|
||||
public class OldCompilerTest extends AbstractWithPreferencesTest {
|
||||
|
||||
@Test
|
||||
public void makeDepUnescapeTest() throws Exception {
|
584
arduino-core/src/cc/arduino/Compiler.java
Normal file
584
arduino-core/src/cc/arduino/Compiler.java
Normal file
@ -0,0 +1,584 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
|
||||
package cc.arduino;
|
||||
|
||||
import cc.arduino.i18n.I18NAwareMessageConsumer;
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.DefaultExecutor;
|
||||
import org.apache.commons.exec.PumpStreamHandler;
|
||||
import processing.app.*;
|
||||
import processing.app.debug.*;
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
import processing.app.helpers.PreferencesMapException;
|
||||
import processing.app.helpers.StringReplacer;
|
||||
import processing.app.legacy.PApplet;
|
||||
import processing.app.tools.DoubleQuotedArgumentsOnWindowsCommandLine;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static processing.app.I18n.tr;
|
||||
|
||||
public class Compiler implements MessageConsumer {
|
||||
|
||||
//used by transifex integration
|
||||
static {
|
||||
tr("'arch' folder is no longer supported! See http://goo.gl/gfFJzU for more information");
|
||||
tr("Board {0} (platform {1}, package {2}) is unknown");
|
||||
tr("Bootloader file specified but missing: {0}");
|
||||
tr("Build options changed, rebuilding all");
|
||||
tr("Unable to find {0} in {1}");
|
||||
tr("Invalid quoting: no closing [{0}] char found.");
|
||||
tr("(legacy)");
|
||||
tr("Multiple libraries were found for \"{0}\"");
|
||||
tr(" Not used: {0}");
|
||||
tr(" Used: {0}");
|
||||
tr("Library can't use both 'src' and 'utility' folders.");
|
||||
tr("WARNING: library {0} claims to run on {1} architecture(s) and may be incompatible with your current board which runs on {2} architecture(s).");
|
||||
tr("Looking for recipes like {0}*{1}");
|
||||
tr("Board {0}:{1}:{2} doesn''t define a ''build.board'' preference. Auto-set to: {3}");
|
||||
tr("Third-party platform.txt does not define compiler.path. Please report this to the third-party hardware maintainer.");
|
||||
tr("Selected board depends on '{0}' core (not installed).");
|
||||
tr("{0} must be a folder");
|
||||
tr("{0}: Unknown package");
|
||||
tr("{0} pattern is missing");
|
||||
tr("Platform {0} (package {1}) is unknown");
|
||||
tr("Progress {0}");
|
||||
tr("Missing '{0}' from library in {1}");
|
||||
tr("Running: {0}");
|
||||
tr("Running recipe: {0}");
|
||||
tr("Setting build path to {0}");
|
||||
tr("Unhandled type {0} in context {1} key");
|
||||
tr("Unknown sketch file extension: {0}");
|
||||
tr("Using library {0} at version {1} in folder: {2} {3}");
|
||||
tr("Using library {0} in folder: {1} {2}");
|
||||
tr("Using previously compiled file: {0}");
|
||||
tr("WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}'");
|
||||
tr("Warning: platform.txt from core '{0}' misses property '{1}', using default value '{2}'. Consider upgrading this core.");
|
||||
tr("Warning: platform.txt from core '{0}' contains deprecated {1}, automatically converted to {2}. Consider upgrading this core.");
|
||||
tr("WARNING: Spurious {0} folder in '{1}' library");
|
||||
}
|
||||
|
||||
enum BuilderAction {
|
||||
COMPILE("-compile"), DUMP_PREFS("-dump-prefs");
|
||||
|
||||
private final String value;
|
||||
|
||||
BuilderAction(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private final String pathToSketch;
|
||||
private final SketchData sketch;
|
||||
private final String buildPath;
|
||||
private boolean verbose;
|
||||
private RunnerException exception;
|
||||
|
||||
public Compiler(SketchData data, String buildPath) {
|
||||
this(data.getMainFilePath(), data, buildPath);
|
||||
}
|
||||
|
||||
public Compiler(String pathToSketch, SketchData sketch, String buildPath) {
|
||||
this.pathToSketch = pathToSketch;
|
||||
this.sketch = sketch;
|
||||
this.buildPath = buildPath;
|
||||
this.verbose = PreferencesData.getBoolean("build.verbose");
|
||||
}
|
||||
|
||||
public String build(CompilerProgressListener progListener, boolean exportHex) throws RunnerException, PreferencesMapException, IOException {
|
||||
TargetBoard board = BaseNoGui.getTargetBoard();
|
||||
if (board == null) {
|
||||
throw new RunnerException("Board is not selected");
|
||||
}
|
||||
|
||||
TargetPlatform platform = board.getContainerPlatform();
|
||||
TargetPackage aPackage = platform.getContainerPackage();
|
||||
|
||||
PreferencesMap prefs = loadPreferences(board, platform, aPackage);
|
||||
|
||||
MessageConsumerOutputStream out = new MessageConsumerOutputStream(new ProgressAwareMessageConsumer(new I18NAwareMessageConsumer(System.out), progListener), "\n");
|
||||
MessageConsumerOutputStream err = new MessageConsumerOutputStream(new I18NAwareMessageConsumer(System.err, Compiler.this), "\n");
|
||||
|
||||
callArduinoBuilder(board, platform, aPackage, BuilderAction.COMPILE, new PumpStreamHandler(out, err));
|
||||
|
||||
out.flush();
|
||||
err.flush();
|
||||
|
||||
if (exportHex) {
|
||||
runActions("hooks.savehex.presavehex", prefs);
|
||||
|
||||
saveHex(prefs);
|
||||
|
||||
runActions("hooks.savehex.postsavehex", prefs);
|
||||
}
|
||||
|
||||
size(prefs);
|
||||
|
||||
return sketch.getName() + ".ino";
|
||||
}
|
||||
|
||||
private PreferencesMap loadPreferences(TargetBoard board, TargetPlatform platform, TargetPackage aPackage) throws RunnerException, IOException {
|
||||
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
|
||||
MessageConsumerOutputStream err = new MessageConsumerOutputStream(new I18NAwareMessageConsumer(new PrintStream(stderr), Compiler.this), "\n");
|
||||
try {
|
||||
callArduinoBuilder(board, platform, aPackage, BuilderAction.DUMP_PREFS, new PumpStreamHandler(stdout, err));
|
||||
} catch (RunnerException e) {
|
||||
System.err.println(new String(stderr.toByteArray()));
|
||||
throw e;
|
||||
}
|
||||
PreferencesMap prefs = new PreferencesMap();
|
||||
prefs.load(new ByteArrayInputStream(stdout.toByteArray()));
|
||||
return prefs;
|
||||
}
|
||||
|
||||
private void callArduinoBuilder(TargetBoard board, TargetPlatform platform, TargetPackage aPackage, BuilderAction action, PumpStreamHandler streamHandler) throws RunnerException {
|
||||
File executable = BaseNoGui.getContentFile("arduino-builder");
|
||||
CommandLine commandLine = new CommandLine(executable);
|
||||
commandLine.addArgument(action.value, false);
|
||||
commandLine.addArgument("-logger=machine", false);
|
||||
|
||||
Stream.of(BaseNoGui.getHardwarePath(), new File(BaseNoGui.getSettingsFolder(), "packages").getAbsolutePath(), BaseNoGui.getSketchbookHardwareFolder().getAbsolutePath())
|
||||
.forEach(p -> {
|
||||
if (Files.exists(Paths.get(p))) {
|
||||
commandLine.addArgument("-hardware=\"" + p + "\"", false);
|
||||
}
|
||||
});
|
||||
|
||||
Stream.of(BaseNoGui.getContentFile("tools-builder").getAbsolutePath(), Paths.get(BaseNoGui.getHardwarePath(), "tools", "avr").toAbsolutePath().toString(), new File(BaseNoGui.getSettingsFolder(), "packages").getAbsolutePath())
|
||||
.forEach(p -> {
|
||||
if (Files.exists(Paths.get(p))) {
|
||||
commandLine.addArgument("-tools=\"" + p + "\"", false);
|
||||
}
|
||||
});
|
||||
|
||||
commandLine.addArgument("-libraries=\"" + BaseNoGui.getSketchbookLibrariesFolder().getAbsolutePath() + "\"", false);
|
||||
commandLine.addArgument("-libraries=\"" + BaseNoGui.getContentFile("libraries").getAbsolutePath() + "\"", false);
|
||||
|
||||
String fqbn = Stream.of(aPackage.getId(), platform.getId(), board.getId(), boardOptions(board)).filter(s -> !s.isEmpty()).collect(Collectors.joining(":"));
|
||||
commandLine.addArgument("-fqbn=" + fqbn, false);
|
||||
|
||||
commandLine.addArgument("-ide-version=" + BaseNoGui.REVISION, false);
|
||||
commandLine.addArgument("-build-path=\"" + buildPath + "\"", false);
|
||||
commandLine.addArgument("-warnings=" + PreferencesData.get("compiler.warning_level"), false);
|
||||
|
||||
PreferencesData.getMap()
|
||||
.subTree("build_properties_custom")
|
||||
.entrySet()
|
||||
.stream()
|
||||
.forEach(kv -> commandLine.addArgument("-prefs=\"" + kv.getKey() + "=" + kv.getValue() + "\"", false));
|
||||
|
||||
commandLine.addArgument("-prefs=build.warn_data_percentage=" + PreferencesData.get("build.warn_data_percentage"));
|
||||
|
||||
//commandLine.addArgument("-debug-level=10", false);
|
||||
|
||||
if (verbose) {
|
||||
commandLine.addArgument("-verbose", false);
|
||||
}
|
||||
|
||||
commandLine.addArgument("\"" + pathToSketch + "\"", false);
|
||||
|
||||
if (verbose) {
|
||||
System.out.println(commandLine);
|
||||
}
|
||||
|
||||
DefaultExecutor executor = new DefaultExecutor();
|
||||
executor.setStreamHandler(streamHandler);
|
||||
|
||||
int result;
|
||||
executor.setExitValues(null);
|
||||
try {
|
||||
result = executor.execute(commandLine);
|
||||
} catch (IOException e) {
|
||||
RunnerException re = new RunnerException(e.getMessage());
|
||||
re.hideStackTrace();
|
||||
throw re;
|
||||
}
|
||||
executor.setExitValues(new int[0]);
|
||||
|
||||
if (exception != null)
|
||||
throw exception;
|
||||
|
||||
if (result > 1) {
|
||||
System.err.println(I18n.format(tr("{0} returned {1}"), executable.getName(), result));
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
RunnerException re = new RunnerException(tr("Error compiling."));
|
||||
re.hideStackTrace();
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
|
||||
protected void size(PreferencesMap prefs) throws RunnerException {
|
||||
String maxTextSizeString = prefs.get("upload.maximum_size");
|
||||
String maxDataSizeString = prefs.get("upload.maximum_data_size");
|
||||
|
||||
if (maxTextSizeString == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
long maxTextSize = Integer.parseInt(maxTextSizeString);
|
||||
long maxDataSize = -1;
|
||||
|
||||
if (maxDataSizeString != null) {
|
||||
maxDataSize = Integer.parseInt(maxDataSizeString);
|
||||
}
|
||||
|
||||
Sizer sizer = new Sizer(prefs);
|
||||
long[] sizes;
|
||||
try {
|
||||
sizes = sizer.computeSize();
|
||||
} catch (RunnerException e) {
|
||||
System.err.println(I18n.format(tr("Couldn't determine program size: {0}"), e.getMessage()));
|
||||
return;
|
||||
}
|
||||
|
||||
long textSize = sizes[0];
|
||||
long dataSize = sizes[1];
|
||||
System.out.println();
|
||||
System.out.println(I18n.format(tr("Sketch uses {0} bytes ({2}%%) of program storage space. Maximum is {1} bytes."), textSize, maxTextSize, textSize * 100 / maxTextSize));
|
||||
if (dataSize >= 0) {
|
||||
if (maxDataSize > 0) {
|
||||
System.out.println(I18n.format(tr("Global variables use {0} bytes ({2}%%) of dynamic memory, leaving {3} bytes for local variables. Maximum is {1} bytes."), dataSize, maxDataSize, dataSize * 100 / maxDataSize, maxDataSize - dataSize));
|
||||
} else {
|
||||
System.out.println(I18n.format(tr("Global variables use {0} bytes of dynamic memory."), dataSize));
|
||||
}
|
||||
}
|
||||
|
||||
if (textSize > maxTextSize) {
|
||||
throw new RunnerException(tr("Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it."));
|
||||
}
|
||||
|
||||
if (maxDataSize > 0 && dataSize > maxDataSize) {
|
||||
throw new RunnerException(tr("Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint."));
|
||||
}
|
||||
|
||||
int warnDataPercentage = Integer.parseInt(prefs.get("build.warn_data_percentage"));
|
||||
if (maxDataSize > 0 && dataSize > maxDataSize * warnDataPercentage / 100) {
|
||||
System.err.println(tr("Low memory available, stability problems may occur."));
|
||||
}
|
||||
}
|
||||
|
||||
void saveHex(PreferencesMap prefs) throws RunnerException {
|
||||
List<String> compiledSketches = new ArrayList<>(prefs.subTree("recipe.output.tmp_file", 1).values());
|
||||
List<String> copyOfCompiledSketches = new ArrayList<>(prefs.subTree("recipe.output.save_file", 1).values());
|
||||
|
||||
if (isExportCompiledSketchSupported(compiledSketches, copyOfCompiledSketches, prefs)) {
|
||||
System.err.println(tr("Warning: This core does not support exporting sketches. Please consider upgrading it or contacting its author"));
|
||||
return;
|
||||
}
|
||||
|
||||
PreferencesMap dict = new PreferencesMap(prefs);
|
||||
dict.put("ide_version", "" + BaseNoGui.REVISION);
|
||||
PreferencesMap withBootloaderDict = new PreferencesMap(dict);
|
||||
dict.put("build.project_name", dict.get("build.project_name") + ".with_bootloader");
|
||||
|
||||
if (!compiledSketches.isEmpty()) {
|
||||
for (int i = 0; i < compiledSketches.size(); i++) {
|
||||
saveHex(compiledSketches.get(i), copyOfCompiledSketches.get(i), dict);
|
||||
saveHex(compiledSketches.get(i), copyOfCompiledSketches.get(i), withBootloaderDict);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
saveHex(prefs.getOrExcept("recipe.output.tmp_file"), prefs.getOrExcept("recipe.output.save_file"), dict);
|
||||
saveHex(prefs.getOrExcept("recipe.output.tmp_file"), prefs.getOrExcept("recipe.output.save_file"), withBootloaderDict);
|
||||
} catch (PreferencesMapException e) {
|
||||
throw new RunnerException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveHex(String compiledSketch, String copyOfCompiledSketch, PreferencesMap prefs) throws RunnerException {
|
||||
try {
|
||||
compiledSketch = StringReplacer.replaceFromMapping(compiledSketch, prefs);
|
||||
copyOfCompiledSketch = StringReplacer.replaceFromMapping(copyOfCompiledSketch, prefs);
|
||||
|
||||
Path compiledSketchPath;
|
||||
Path compiledSketchPathInSubfolder = Paths.get(prefs.get("build.path"), "sketch", compiledSketch);
|
||||
Path compiledSketchPathInBuildPath = Paths.get(prefs.get("build.path"), compiledSketch);
|
||||
if (Files.exists(compiledSketchPathInSubfolder)) {
|
||||
compiledSketchPath = compiledSketchPathInSubfolder;
|
||||
} else {
|
||||
compiledSketchPath = compiledSketchPathInBuildPath;
|
||||
}
|
||||
|
||||
Path copyOfCompiledSketchFilePath = Paths.get(this.sketch.getFolder().getAbsolutePath(), copyOfCompiledSketch);
|
||||
|
||||
Files.copy(compiledSketchPath, copyOfCompiledSketchFilePath, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
throw new RunnerException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isExportCompiledSketchSupported(List<String> compiledSketches, List<String> copyOfCompiledSketches, PreferencesMap prefs) {
|
||||
return (compiledSketches.isEmpty() || copyOfCompiledSketches.isEmpty() || copyOfCompiledSketches.size() < compiledSketches.size()) && (!prefs.containsKey("recipe.output.tmp_file") || !prefs.containsKey("recipe.output.save_file"));
|
||||
}
|
||||
|
||||
void runActions(String recipeClass, PreferencesMap prefs) throws RunnerException, PreferencesMapException {
|
||||
List<String> patterns = new ArrayList<>();
|
||||
for (String key : prefs.keySet()) {
|
||||
if (key.startsWith("recipe." + recipeClass) && key.endsWith(".pattern"))
|
||||
patterns.add(key);
|
||||
}
|
||||
Collections.sort(patterns);
|
||||
for (String recipe : patterns) {
|
||||
runRecipe(recipe, prefs);
|
||||
}
|
||||
}
|
||||
|
||||
void runRecipe(String recipe, PreferencesMap prefs) throws RunnerException, PreferencesMapException {
|
||||
PreferencesMap dict = new PreferencesMap(prefs);
|
||||
dict.put("ide_version", "" + BaseNoGui.REVISION);
|
||||
dict.put("sketch_path", sketch.getFolder().getAbsolutePath());
|
||||
|
||||
String[] cmdArray;
|
||||
String cmd = prefs.getOrExcept(recipe);
|
||||
try {
|
||||
cmdArray = StringReplacer.formatAndSplit(cmd, dict, true);
|
||||
} catch (Exception e) {
|
||||
throw new RunnerException(e);
|
||||
}
|
||||
exec(cmdArray);
|
||||
}
|
||||
|
||||
private void exec(String[] command) throws RunnerException {
|
||||
// eliminate any empty array entries
|
||||
List<String> stringList = new ArrayList<String>();
|
||||
for (String string : command) {
|
||||
string = string.trim();
|
||||
if (string.length() != 0)
|
||||
stringList.add(string);
|
||||
}
|
||||
command = stringList.toArray(new String[stringList.size()]);
|
||||
if (command.length == 0)
|
||||
return;
|
||||
|
||||
if (verbose) {
|
||||
for (String c : command)
|
||||
System.out.print(c + " ");
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
DefaultExecutor executor = new DefaultExecutor();
|
||||
executor.setStreamHandler(new PumpStreamHandler() {
|
||||
|
||||
@Override
|
||||
protected Thread createPump(InputStream is, OutputStream os, boolean closeWhenExhausted) {
|
||||
final Thread result = new Thread(new MyStreamPumper(is, Compiler.this));
|
||||
result.setDaemon(true);
|
||||
return result;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
CommandLine commandLine = new DoubleQuotedArgumentsOnWindowsCommandLine(command[0]);
|
||||
for (int i = 1; i < command.length; i++) {
|
||||
commandLine.addArgument(command[i], false);
|
||||
}
|
||||
|
||||
int result;
|
||||
executor.setExitValues(null);
|
||||
try {
|
||||
result = executor.execute(commandLine);
|
||||
} catch (IOException e) {
|
||||
RunnerException re = new RunnerException(e.getMessage());
|
||||
re.hideStackTrace();
|
||||
throw re;
|
||||
}
|
||||
executor.setExitValues(new int[0]);
|
||||
|
||||
// an error was queued up by message(), barf this back to compile(),
|
||||
// which will barf it back to Editor. if you're having trouble
|
||||
// discerning the imagery, consider how cows regurgitate their food
|
||||
// to digest it, and the fact that they have five stomaches.
|
||||
//
|
||||
//System.out.println("throwing up " + exception);
|
||||
if (exception != null)
|
||||
throw exception;
|
||||
|
||||
if (result > 1) {
|
||||
// a failure in the tool (e.g. unable to locate a sub-executable)
|
||||
System.err
|
||||
.println(I18n.format(tr("{0} returned {1}"), command[0], result));
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
RunnerException re = new RunnerException(tr("Error compiling."));
|
||||
re.hideStackTrace();
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
|
||||
private String boardOptions(TargetBoard board) {
|
||||
return board.getMenuIds().stream()
|
||||
.filter(board::hasMenu)
|
||||
.filter(menuId -> {
|
||||
String entry = PreferencesData.get("custom_" + menuId);
|
||||
return entry != null && entry.startsWith(board.getId());
|
||||
})
|
||||
.map(menuId -> {
|
||||
String entry = PreferencesData.get("custom_" + menuId);
|
||||
String selectionId = entry.substring(board.getId().length() + 1);
|
||||
return menuId + "=" + selectionId;
|
||||
})
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the MessageConsumer interface, this is called
|
||||
* whenever a piece (usually a line) of error message is spewed
|
||||
* out from the compiler. The errors are parsed for their contents
|
||||
* and line number, which is then reported back to Editor.
|
||||
*/
|
||||
public void message(String s) {
|
||||
int i;
|
||||
|
||||
if (!verbose) {
|
||||
while ((i = s.indexOf(buildPath + File.separator)) != -1) {
|
||||
s = s.substring(0, i) + s.substring(i + (buildPath + File.separator).length());
|
||||
}
|
||||
}
|
||||
|
||||
String errorFormat = "(.+\\.\\w+):(\\d+)(:\\d+)*:\\s*error:\\s*(.*)\\s*";
|
||||
String[] pieces = PApplet.match(s, errorFormat);
|
||||
|
||||
if (pieces != null) {
|
||||
String error = pieces[pieces.length - 1], msg = "";
|
||||
|
||||
if (error.trim().equals("SPI.h: No such file or directory")) {
|
||||
error = tr("Please import the SPI library from the Sketch > Import Library menu.");
|
||||
msg = tr("\nAs of Arduino 0019, the Ethernet library depends on the SPI library." +
|
||||
"\nYou appear to be using it or another library that depends on the SPI library.\n\n");
|
||||
}
|
||||
|
||||
if (error.trim().equals("'BYTE' was not declared in this scope")) {
|
||||
error = tr("The 'BYTE' keyword is no longer supported.");
|
||||
msg = tr("\nAs of Arduino 1.0, the 'BYTE' keyword is no longer supported." +
|
||||
"\nPlease use Serial.write() instead.\n\n");
|
||||
}
|
||||
|
||||
if (error.trim().equals("no matching function for call to 'Server::Server(int)'")) {
|
||||
error = tr("The Server class has been renamed EthernetServer.");
|
||||
msg = tr("\nAs of Arduino 1.0, the Server class in the Ethernet library " +
|
||||
"has been renamed to EthernetServer.\n\n");
|
||||
}
|
||||
|
||||
if (error.trim().equals("no matching function for call to 'Client::Client(byte [4], int)'")) {
|
||||
error = tr("The Client class has been renamed EthernetClient.");
|
||||
msg = tr("\nAs of Arduino 1.0, the Client class in the Ethernet library " +
|
||||
"has been renamed to EthernetClient.\n\n");
|
||||
}
|
||||
|
||||
if (error.trim().equals("'Udp' was not declared in this scope")) {
|
||||
error = tr("The Udp class has been renamed EthernetUdp.");
|
||||
msg = tr("\nAs of Arduino 1.0, the Udp class in the Ethernet library " +
|
||||
"has been renamed to EthernetUdp.\n\n");
|
||||
}
|
||||
|
||||
if (error.trim().equals("'class TwoWire' has no member named 'send'")) {
|
||||
error = tr("Wire.send() has been renamed Wire.write().");
|
||||
msg = tr("\nAs of Arduino 1.0, the Wire.send() function was renamed " +
|
||||
"to Wire.write() for consistency with other libraries.\n\n");
|
||||
}
|
||||
|
||||
if (error.trim().equals("'class TwoWire' has no member named 'receive'")) {
|
||||
error = tr("Wire.receive() has been renamed Wire.read().");
|
||||
msg = tr("\nAs of Arduino 1.0, the Wire.receive() function was renamed " +
|
||||
"to Wire.read() for consistency with other libraries.\n\n");
|
||||
}
|
||||
|
||||
if (error.trim().equals("'Mouse' was not declared in this scope")) {
|
||||
error = tr("'Mouse' only supported on the Arduino Leonardo");
|
||||
//msg = _("\nThe 'Mouse' class is only supported on the Arduino Leonardo.\n\n");
|
||||
}
|
||||
|
||||
if (error.trim().equals("'Keyboard' was not declared in this scope")) {
|
||||
error = tr("'Keyboard' only supported on the Arduino Leonardo");
|
||||
//msg = _("\nThe 'Keyboard' class is only supported on the Arduino Leonardo.\n\n");
|
||||
}
|
||||
|
||||
RunnerException exception = placeException(error, pieces[1], PApplet.parseInt(pieces[2]) - 1);
|
||||
|
||||
// replace full file path with the name of the sketch tab (unless we're
|
||||
// in verbose mode, in which case don't modify the compiler output)
|
||||
if (exception != null && !verbose) {
|
||||
SketchCode code = sketch.getCode(exception.getCodeIndex());
|
||||
String fileName = (code.isExtension("ino") || code.isExtension("pde")) ? code.getPrettyName() : code.getFileName();
|
||||
int lineNum = exception.getCodeLine() + 1;
|
||||
s = fileName + ":" + lineNum + ": error: " + error + msg;
|
||||
}
|
||||
|
||||
if (exception != null) {
|
||||
if (this.exception == null || this.exception.getMessage().equals(exception.getMessage())) {
|
||||
this.exception = exception;
|
||||
this.exception.hideStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s.contains("undefined reference to `SPIClass::begin()'") &&
|
||||
s.contains("libraries/Robot_Control")) {
|
||||
String error = tr("Please import the SPI library from the Sketch > Import Library menu.");
|
||||
exception = new RunnerException(error);
|
||||
}
|
||||
|
||||
if (s.contains("undefined reference to `Wire'") &&
|
||||
s.contains("libraries/Robot_Control")) {
|
||||
String error = tr("Please import the Wire library from the Sketch > Import Library menu.");
|
||||
exception = new RunnerException(error);
|
||||
}
|
||||
|
||||
System.err.println(s);
|
||||
}
|
||||
|
||||
public RunnerException placeException(String message,
|
||||
String dotJavaFilename,
|
||||
int dotJavaLine) {
|
||||
// Placing errors is simple, because we inserted #line directives
|
||||
// into the preprocessed source. The compiler gives us correct
|
||||
// the file name and line number. :-)
|
||||
for (SketchCode code : sketch.getCodes()) {
|
||||
if (dotJavaFilename.equals(code.getFileName())) {
|
||||
return new RunnerException(message, sketch.indexOfCode(code), dotJavaLine);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
36
arduino-core/src/cc/arduino/CompilerProgressListener.java
Normal file
36
arduino-core/src/cc/arduino/CompilerProgressListener.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
|
||||
package cc.arduino;
|
||||
|
||||
public interface CompilerProgressListener {
|
||||
|
||||
void progress(int value);
|
||||
|
||||
}
|
62
arduino-core/src/cc/arduino/CompilerUtils.java
Normal file
62
arduino-core/src/cc/arduino/CompilerUtils.java
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Arduino 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*/
|
||||
|
||||
package cc.arduino;
|
||||
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
import processing.app.helpers.PreferencesMapException;
|
||||
import processing.app.helpers.StringReplacer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static processing.app.I18n.tr;
|
||||
|
||||
public class CompilerUtils {
|
||||
|
||||
public File findCompiledSketch(PreferencesMap prefs) throws PreferencesMapException {
|
||||
List<String> paths = Arrays.asList(
|
||||
"{build.path}/sketch/{build.project_name}.with_bootloader.hex",
|
||||
"{build.path}/sketch/{build.project_name}.hex",
|
||||
"{build.path}/{build.project_name}.with_bootloader.hex",
|
||||
"{build.path}/{build.project_name}.hex",
|
||||
"{build.path}/sketch/{build.project_name}.bin",
|
||||
"{build.path}/{build.project_name}.bin"
|
||||
);
|
||||
Optional<File> sketch = paths.stream().
|
||||
map(path -> StringReplacer.replaceFromMapping(path, prefs)).
|
||||
map(File::new).
|
||||
filter(File::exists).
|
||||
findFirst();
|
||||
return sketch.orElseThrow(() -> new IllegalStateException(tr("No compiled sketch found")));
|
||||
}
|
||||
|
||||
}
|
46
arduino-core/src/cc/arduino/MessageConsumerOutputStream.java
Normal file
46
arduino-core/src/cc/arduino/MessageConsumerOutputStream.java
Normal file
@ -0,0 +1,46 @@
|
||||
package cc.arduino;
|
||||
|
||||
import processing.app.debug.MessageConsumer;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class MessageConsumerOutputStream extends ByteArrayOutputStream {
|
||||
|
||||
private final MessageConsumer consumer;
|
||||
private final String lineSeparator;
|
||||
|
||||
public MessageConsumerOutputStream(MessageConsumer consumer) {
|
||||
this(consumer, System.getProperty("line.separator"));
|
||||
}
|
||||
|
||||
public MessageConsumerOutputStream(MessageConsumer consumer, String lineSeparator) {
|
||||
this.consumer = consumer;
|
||||
this.lineSeparator = lineSeparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) {
|
||||
super.write(b, off, len);
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
String asString = toString();
|
||||
if (!asString.contains(lineSeparator)) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (asString.contains(lineSeparator)) {
|
||||
String line = asString.substring(0, asString.indexOf(lineSeparator));
|
||||
reset();
|
||||
byte[] bytes = asString.substring(asString.indexOf(lineSeparator) + lineSeparator.length()).getBytes();
|
||||
super.write(bytes, 0, bytes.length);
|
||||
asString = toString();
|
||||
|
||||
consumer.message(line);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -73,7 +73,7 @@ public class MyStreamPumper implements Runnable {
|
||||
try {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
messageConsumer.message(line + "\n");
|
||||
messageConsumer.message(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nothing to do - happens quite often with watchdog
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
|
||||
package cc.arduino;
|
||||
|
||||
import cc.arduino.i18n.ExternalProcessOutputParser;
|
||||
import processing.app.debug.MessageConsumer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ProgressAwareMessageConsumer implements MessageConsumer {
|
||||
|
||||
private final MessageConsumer parent;
|
||||
private final CompilerProgressListener progressListener;
|
||||
private final ExternalProcessOutputParser parser;
|
||||
|
||||
public ProgressAwareMessageConsumer(MessageConsumer parent, CompilerProgressListener progressListener) {
|
||||
this.parent = parent;
|
||||
this.progressListener = progressListener;
|
||||
this.parser = new ExternalProcessOutputParser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void message(String s) {
|
||||
if (s.startsWith("===Progress")) {
|
||||
Map<String, Object> parsedMessage = parser.parse(s);
|
||||
Object[] args = (Object[]) parsedMessage.get("args");
|
||||
progressListener.progress(Double.valueOf(args[0].toString()).intValue());
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent != null) {
|
||||
parent.message(s);
|
||||
}
|
||||
}
|
||||
}
|
97
arduino-core/src/cc/arduino/UploaderUtils.java
Normal file
97
arduino-core/src/cc/arduino/UploaderUtils.java
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Arduino 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*/
|
||||
|
||||
package cc.arduino;
|
||||
|
||||
import cc.arduino.packages.BoardPort;
|
||||
import cc.arduino.packages.Uploader;
|
||||
import cc.arduino.packages.UploaderFactory;
|
||||
import processing.app.BaseNoGui;
|
||||
import processing.app.PreferencesData;
|
||||
import processing.app.SketchData;
|
||||
import processing.app.debug.TargetPlatform;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static processing.app.I18n.tr;
|
||||
|
||||
public class UploaderUtils {
|
||||
|
||||
public Uploader getUploaderByPreferences(boolean noUploadPort) {
|
||||
TargetPlatform target = BaseNoGui.getTargetPlatform();
|
||||
String board = PreferencesData.get("board");
|
||||
|
||||
BoardPort boardPort = null;
|
||||
if (!noUploadPort) {
|
||||
boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port"));
|
||||
}
|
||||
|
||||
return new UploaderFactory().newUploader(target.getBoards().get(board), boardPort, noUploadPort);
|
||||
}
|
||||
|
||||
public boolean upload(SketchData data, Uploader uploader, String buildPath, String suggestedClassName, boolean usingProgrammer, boolean noUploadPort, List<String> warningsAccumulator) throws Exception {
|
||||
|
||||
if (uploader == null)
|
||||
uploader = getUploaderByPreferences(noUploadPort);
|
||||
|
||||
boolean success = false;
|
||||
|
||||
if (uploader.requiresAuthorization() && !PreferencesData.has(uploader.getAuthorizationKey())) {
|
||||
BaseNoGui.showError(tr("Authorization required"),
|
||||
tr("No authorization data found"), null);
|
||||
}
|
||||
|
||||
boolean useNewWarningsAccumulator = false;
|
||||
if (warningsAccumulator == null) {
|
||||
warningsAccumulator = new LinkedList<String>();
|
||||
useNewWarningsAccumulator = true;
|
||||
}
|
||||
|
||||
try {
|
||||
success = uploader.uploadUsingPreferences(data.getFolder(), buildPath, suggestedClassName, usingProgrammer, warningsAccumulator);
|
||||
} finally {
|
||||
if (uploader.requiresAuthorization() && !success) {
|
||||
PreferencesData.remove(uploader.getAuthorizationKey());
|
||||
}
|
||||
}
|
||||
|
||||
if (useNewWarningsAccumulator) {
|
||||
for (String warning : warningsAccumulator) {
|
||||
System.out.print(tr("Warning"));
|
||||
System.out.print(": ");
|
||||
System.out.println(warning);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
|
||||
package cc.arduino.i18n;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ExternalProcessOutputParser {
|
||||
|
||||
public Map<String, Object> parse(String s) {
|
||||
if (!s.startsWith("===")) {
|
||||
throw new IllegalArgumentException(s);
|
||||
}
|
||||
|
||||
s = s.substring(3);
|
||||
|
||||
Map<String, Object> output = new HashMap<>();
|
||||
|
||||
String[] parts = s.split(" \\|\\|\\| ");
|
||||
|
||||
output.put("msg", parts[0]);
|
||||
output.put("args", parseArgs(parts[1]));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private Object[] parseArgs(String argsAsString) {
|
||||
if (!argsAsString.startsWith("[") || !argsAsString.endsWith("]")) {
|
||||
throw new IllegalArgumentException(argsAsString);
|
||||
}
|
||||
|
||||
argsAsString = argsAsString.substring(1, argsAsString.length() - 1);
|
||||
if (argsAsString.isEmpty()) {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
List<String> args = new ArrayList<>(Arrays.asList(argsAsString.split(" ")));
|
||||
List<String> additionalArgs = addAsManyEmptyArgsAsEndingSpaces(argsAsString, args);
|
||||
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
try {
|
||||
args.set(i, URLDecoder.decode(args.get(i), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
args.addAll(additionalArgs);
|
||||
|
||||
return args.toArray();
|
||||
}
|
||||
|
||||
private List<String> addAsManyEmptyArgsAsEndingSpaces(String argsAsString, List<String> args) {
|
||||
List<String> additionalArgs = new LinkedList<>();
|
||||
|
||||
if (argsAsString.charAt(argsAsString.length() - 1) == ' ') {
|
||||
String allArgsButEndingSpacesAsString = args.stream().collect(Collectors.joining(" "));
|
||||
String endingSpacesOnly = argsAsString.replace(allArgsButEndingSpacesAsString, "");
|
||||
for (int i = 0; i < endingSpacesOnly.length(); i++) {
|
||||
additionalArgs.add("");
|
||||
}
|
||||
}
|
||||
return additionalArgs;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
|
||||
package cc.arduino.i18n;
|
||||
|
||||
import processing.app.I18n;
|
||||
import processing.app.debug.MessageConsumer;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.Map;
|
||||
|
||||
import static processing.app.I18n.tr;
|
||||
|
||||
public class I18NAwareMessageConsumer implements MessageConsumer {
|
||||
|
||||
private final PrintStream ps;
|
||||
private final MessageConsumer parent;
|
||||
private final ExternalProcessOutputParser parser;
|
||||
|
||||
public I18NAwareMessageConsumer(PrintStream ps) {
|
||||
this(ps, null);
|
||||
}
|
||||
|
||||
public I18NAwareMessageConsumer(PrintStream ps, MessageConsumer parent) {
|
||||
this.ps = ps;
|
||||
this.parent = parent;
|
||||
this.parser = new ExternalProcessOutputParser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void message(String s) {
|
||||
if (s.startsWith("===")) {
|
||||
Map<String, Object> parsedMessage = parser.parse(s);
|
||||
ps.println(I18n.format(tr((String) parsedMessage.get("msg")), (Object[]) parsedMessage.get("args")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent != null) {
|
||||
parent.message(s);
|
||||
} else {
|
||||
ps.println(s);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Uploader - abstract uploading baseclass (common to both uisp and avrdude)
|
||||
Part of the Arduino project - http://www.arduino.cc/
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
package cc.arduino.packages.uploaders;
|
||||
|
||||
import cc.arduino.Compiler;
|
||||
import cc.arduino.CompilerUtils;
|
||||
import cc.arduino.packages.BoardPort;
|
||||
import cc.arduino.packages.Uploader;
|
||||
import cc.arduino.packages.ssh.*;
|
||||
@ -117,7 +119,7 @@ public class SSHUploader extends Uploader {
|
||||
if (!coreMissesRemoteUploadTool && mergedSketch.exists()) {
|
||||
sketchToCopy = mergedSketch;
|
||||
} else {
|
||||
sketchToCopy = processing.app.debug.Compiler.findCompiledSketch(prefs);
|
||||
sketchToCopy = new CompilerUtils().findCompiledSketch(prefs);
|
||||
}
|
||||
scpFiles(scp, ssh, sourcePath, sketchToCopy, warningsAccumulator);
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
BasicUploader - generic command line uploader implementation
|
||||
Part of the Arduino project - http://www.arduino.cc/
|
||||
|
@ -1,6 +1,8 @@
|
||||
package processing.app;
|
||||
|
||||
import cc.arduino.Compiler;
|
||||
import cc.arduino.Constants;
|
||||
import cc.arduino.UploaderUtils;
|
||||
import cc.arduino.contributions.GPGDetachedSignatureVerifier;
|
||||
import cc.arduino.contributions.SignatureVerificationFailedException;
|
||||
import cc.arduino.contributions.libraries.LibrariesIndexer;
|
||||
@ -13,7 +15,6 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
import org.apache.commons.logging.impl.LogFactoryImpl;
|
||||
import org.apache.commons.logging.impl.NoOpLog;
|
||||
import processing.app.debug.Compiler;
|
||||
import processing.app.debug.*;
|
||||
import processing.app.helpers.*;
|
||||
import processing.app.helpers.filefilters.OnlyDirs;
|
||||
@ -504,16 +505,16 @@ public class BaseNoGui {
|
||||
if (!data.getFolder().exists()) {
|
||||
showError(tr("No sketch"), tr("Can't find the sketch in the specified path"), null);
|
||||
}
|
||||
String suggestedClassName = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, parser.isDoVerboseBuild(), false);
|
||||
String suggestedClassName = new Compiler(data, tempBuildFolder.getAbsolutePath()).build(null, false);
|
||||
if (suggestedClassName == null) {
|
||||
showError(tr("Error while verifying"), tr("An error occurred while verifying the sketch"), null);
|
||||
}
|
||||
showMessage(tr("Done compiling"), tr("Done compiling"));
|
||||
|
||||
Uploader uploader = Compiler.getUploaderByPreferences(parser.isNoUploadPort());
|
||||
Uploader uploader = new UploaderUtils().getUploaderByPreferences(parser.isNoUploadPort());
|
||||
if (uploader.requiresAuthorization() && !PreferencesData.has(uploader.getAuthorizationKey())) showError("...", "...", null);
|
||||
try {
|
||||
success = Compiler.upload(data, uploader, tempBuildFolder.getAbsolutePath(), suggestedClassName, parser.isDoUseProgrammer(), parser.isNoUploadPort(), warningsAccumulator);
|
||||
success = new UploaderUtils().upload(data, uploader, tempBuildFolder.getAbsolutePath(), suggestedClassName, parser.isDoUseProgrammer(), parser.isNoUploadPort(), warningsAccumulator);
|
||||
showMessage(tr("Done uploading"), tr("Done uploading"));
|
||||
} finally {
|
||||
if (uploader.requiresAuthorization() && !success) {
|
||||
@ -550,7 +551,7 @@ public class BaseNoGui {
|
||||
// if (!data.getFolder().exists()) showError(...);
|
||||
// String ... = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, verbose);
|
||||
if (!data.getFolder().exists()) showError(tr("No sketch"), tr("Can't find the sketch in the specified path"), null);
|
||||
String suggestedClassName = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, parser.isDoVerboseBuild(), false);
|
||||
String suggestedClassName = new Compiler(data, tempBuildFolder.getAbsolutePath()).build(null, false);
|
||||
if (suggestedClassName == null) showError(tr("Error while verifying"), tr("An error occurred while verifying the sketch"), null);
|
||||
showMessage(tr("Done compiling"), tr("Done compiling"));
|
||||
} catch (Exception e) {
|
||||
|
@ -26,17 +26,17 @@ package processing.app.debug;
|
||||
|
||||
/**
|
||||
* Interface for dealing with parser/compiler output.
|
||||
* <P>
|
||||
* <p>
|
||||
* Different instances of MessageStream need to do different things with
|
||||
* messages. In particular, a stream instance used for parsing output from
|
||||
* the compiler compiler has to interpret its messages differently than one
|
||||
* parsing output from the runtime.
|
||||
* <P>
|
||||
* <p>
|
||||
* Classes which consume messages and do something with them
|
||||
* should implement this interface.
|
||||
*/
|
||||
public interface MessageConsumer {
|
||||
|
||||
public void message(String s);
|
||||
void message(String s);
|
||||
|
||||
}
|
||||
|
@ -61,7 +61,8 @@ import java.util.stream.Stream;
|
||||
|
||||
import static processing.app.I18n.tr;
|
||||
|
||||
public class Compiler implements MessageConsumer {
|
||||
@Deprecated
|
||||
public class OldCompiler implements MessageConsumer {
|
||||
|
||||
/**
|
||||
* File inside the build directory that contains the build options
|
||||
@ -96,7 +97,7 @@ public class Compiler implements MessageConsumer {
|
||||
tr("Bad sketch primary file or bad sketch directory structure"), null);
|
||||
|
||||
String primaryClassName = data.getName() + ".cpp";
|
||||
Compiler compiler = new Compiler(data, buildPath, primaryClassName);
|
||||
OldCompiler compiler = new OldCompiler(data, buildPath, primaryClassName);
|
||||
File buildPrefsFile = new File(buildPath, BUILD_PREFS_FILE);
|
||||
String newBuildPrefs = compiler.buildPrefsString();
|
||||
|
||||
@ -208,7 +209,7 @@ public class Compiler implements MessageConsumer {
|
||||
* @param _buildPath Where the temporary files live and will be built from.
|
||||
* @param _primaryClassName the name of the combined sketch file w/ extension
|
||||
*/
|
||||
public Compiler(SketchData _sketch, String _buildPath, String _primaryClassName)
|
||||
public OldCompiler(SketchData _sketch, String _buildPath, String _primaryClassName)
|
||||
throws RunnerException {
|
||||
sketch = _sketch;
|
||||
prefs = createBuildPreferences(_buildPath, _primaryClassName);
|
||||
@ -808,7 +809,7 @@ public class Compiler implements MessageConsumer {
|
||||
|
||||
@Override
|
||||
protected Thread createPump(InputStream is, OutputStream os, boolean closeWhenExhausted) {
|
||||
final Thread result = new Thread(new MyStreamPumper(is, Compiler.this));
|
||||
final Thread result = new Thread(new MyStreamPumper(is, OldCompiler.this));
|
||||
result.setDaemon(true);
|
||||
return result;
|
||||
|
@ -277,6 +277,7 @@ public class CommandlineParser {
|
||||
BaseNoGui.showError(null, I18n.format(tr("{0}: Invalid argument to --pref, should be of the form \"pref=value\""), arg), 3);
|
||||
|
||||
PreferencesData.set(split[0], split[1]);
|
||||
PreferencesData.set("build_properties_custom." + split[0], split[1]);
|
||||
}
|
||||
|
||||
public boolean isDoVerboseBuild() {
|
||||
|
1
build/arduino-builder-linux32-1.0.0-beta3.tar.bz2.sha
Normal file
1
build/arduino-builder-linux32-1.0.0-beta3.tar.bz2.sha
Normal file
@ -0,0 +1 @@
|
||||
4b72651bf25dc056c430c9160e7c6a4aa9909214
|
1
build/arduino-builder-linux64-1.0.0-beta3.tar.bz2.sha
Normal file
1
build/arduino-builder-linux64-1.0.0-beta3.tar.bz2.sha
Normal file
@ -0,0 +1 @@
|
||||
68d07baf4cb12f270ca1fe6c669018695614a304
|
1
build/arduino-builder-macosx-1.0.0-beta3.tar.bz2.sha
Normal file
1
build/arduino-builder-macosx-1.0.0-beta3.tar.bz2.sha
Normal file
@ -0,0 +1 @@
|
||||
15c8230a431669e629e9cbb635df6d90731cf144
|
1
build/arduino-builder-windows-1.0.0-beta3.zip.sha
Normal file
1
build/arduino-builder-windows-1.0.0-beta3.zip.sha
Normal file
@ -0,0 +1 @@
|
||||
5979a9ea20c7b982433a1119875aa6518b859bb6
|
@ -71,6 +71,8 @@
|
||||
</or>
|
||||
</condition>
|
||||
|
||||
<property name="ARDUINO-BUILDER-VERSION" value="1.0.0-beta3" />
|
||||
|
||||
<!-- Libraries required for running arduino -->
|
||||
<fileset dir=".." id="runtime.jars">
|
||||
<include name="arduino-core/arduino-core.jar" />
|
||||
@ -372,6 +374,21 @@
|
||||
<copy file="macosx/libastylej-2.05.1/libastylej.jnilib" tofile="macosx/work/${staging_hardware_folder}/../lib/libastylej.dylib" />
|
||||
<chmod perm="755" file="macosx/work/${staging_hardware_folder}/../lib/libastylej.dylib" />
|
||||
|
||||
<mkdir dir="${staging_folder}/arduino-builder-macosx"/>
|
||||
<antcall target="untar">
|
||||
<param name="archive_file" value="./arduino-builder-macosx-${ARDUINO-BUILDER-VERSION}.tar.bz2" />
|
||||
<param name="archive_url" value="http://downloads.arduino.cc/tools/arduino-builder-macosx-${ARDUINO-BUILDER-VERSION}.tar.bz2" />
|
||||
<param name="final_folder" value="${staging_folder}/arduino-builder-macosx/arduino-builder" />
|
||||
<param name="dest_folder" value="${staging_folder}/arduino-builder-macosx" />
|
||||
</antcall>
|
||||
<copy file="${staging_folder}/arduino-builder-macosx/arduino-builder" tofile="macosx/work/${staging_hardware_folder}/../arduino-builder" />
|
||||
<chmod perm="755" file="macosx/work/${staging_hardware_folder}/../arduino-builder" />
|
||||
<move file="${staging_folder}/arduino-builder-macosx/tools" tofile="macosx/work/${staging_hardware_folder}/../tools-builder"/>
|
||||
<copy todir="macosx/work/${staging_hardware_folder}" overwrite="true">
|
||||
<fileset dir="${staging_folder}/arduino-builder-macosx/hardware" includes="*.txt"/>
|
||||
</copy>
|
||||
<delete dir="${staging_folder}/arduino-builder-macosx" includeemptydirs="true"/>
|
||||
|
||||
</target>
|
||||
|
||||
<!-- Unzip AVR tools -->
|
||||
@ -483,6 +500,9 @@
|
||||
<delete>
|
||||
<fileset dir="linux" includes="arduino-*linux*.tar.xz"/>
|
||||
</delete>
|
||||
<delete>
|
||||
<fileset dir="linux" includes="arduino-*linux*.tar.xz"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target name="linux-checkos" unless="linux">
|
||||
@ -541,6 +561,21 @@
|
||||
<param name="JVM" value="${LINUX32_BUNDLED_JVM}"/>
|
||||
</antcall>
|
||||
|
||||
<mkdir dir="${staging_folder}/arduino-builder-linux32"/>
|
||||
<antcall target="untar">
|
||||
<param name="archive_file" value="./arduino-builder-linux32-${ARDUINO-BUILDER-VERSION}.tar.bz2" />
|
||||
<param name="archive_url" value="http://downloads.arduino.cc/tools/arduino-builder-linux32-${ARDUINO-BUILDER-VERSION}.tar.bz2" />
|
||||
<param name="final_folder" value="${staging_folder}/arduino-builder-linux32/arduino-builder" />
|
||||
<param name="dest_folder" value="${staging_folder}/arduino-builder-linux32" />
|
||||
</antcall>
|
||||
<copy file="${staging_folder}/arduino-builder-linux32/arduino-builder" tofile="linux/work/arduino-builder" />
|
||||
<chmod perm="755" file="linux/work/arduino-builder" />
|
||||
<move file="${staging_folder}/arduino-builder-linux32/tools" tofile="linux/work/tools-builder"/>
|
||||
<copy todir="linux/work/hardware" overwrite="true">
|
||||
<fileset dir="${staging_folder}/arduino-builder-linux32/hardware" includes="*.txt"/>
|
||||
</copy>
|
||||
<delete dir="${staging_folder}/arduino-builder-linux32" includeemptydirs="true"/>
|
||||
|
||||
<antcall target="avr-toolchain-bundle">
|
||||
<param name="unpack_target" value="untar"/>
|
||||
<param name="gcc_archive_file" value="avr-gcc-4.8.1-arduino5-i686-pc-linux-gnu.tar.bz2"/>
|
||||
@ -557,6 +592,21 @@
|
||||
<param name="JVM" value="${LINUX64_BUNDLED_JVM}"/>
|
||||
</antcall>
|
||||
|
||||
<mkdir dir="${staging_folder}/arduino-builder-linux64"/>
|
||||
<antcall target="untar">
|
||||
<param name="archive_file" value="./arduino-builder-linux64-${ARDUINO-BUILDER-VERSION}.tar.bz2" />
|
||||
<param name="archive_url" value="http://downloads.arduino.cc/tools/arduino-builder-linux64-${ARDUINO-BUILDER-VERSION}.tar.bz2" />
|
||||
<param name="final_folder" value="${staging_folder}/arduino-builder-linux64/arduino-builder" />
|
||||
<param name="dest_folder" value="${staging_folder}/arduino-builder-linux64" />
|
||||
</antcall>
|
||||
<copy file="${staging_folder}/arduino-builder-linux64/arduino-builder" tofile="linux/work/arduino-builder" />
|
||||
<chmod perm="755" file="linux/work/arduino-builder" />
|
||||
<move file="${staging_folder}/arduino-builder-linux64/tools" tofile="linux/work/tools-builder"/>
|
||||
<copy todir="linux/work/hardware" overwrite="true">
|
||||
<fileset dir="${staging_folder}/arduino-builder-linux64/hardware" includes="*.txt"/>
|
||||
</copy>
|
||||
<delete dir="${staging_folder}/arduino-builder-linux64" includeemptydirs="true"/>
|
||||
|
||||
<antcall target="avr-toolchain-bundle">
|
||||
<param name="unpack_target" value="untar"/>
|
||||
<param name="gcc_archive_file" value="avr-gcc-4.8.1-arduino5-x86_64-pc-linux-gnu.tar.bz2"/>
|
||||
@ -762,6 +812,21 @@
|
||||
<fileset file="windows/work/hardware/tools/listComPorts.exe" />
|
||||
</chmod>
|
||||
|
||||
<mkdir dir="${staging_folder}/arduino-builder-windows"/>
|
||||
<antcall target="unzip">
|
||||
<param name="archive_file" value="./arduino-builder-windows-${ARDUINO-BUILDER-VERSION}.zip" />
|
||||
<param name="archive_url" value="http://downloads.arduino.cc/tools/arduino-builder-windows-${ARDUINO-BUILDER-VERSION}.zip" />
|
||||
<param name="final_folder" value="${staging_folder}/arduino-builder-windows/arduino-builder.exe" />
|
||||
<param name="dest_folder" value="${staging_folder}/arduino-builder-windows" />
|
||||
</antcall>
|
||||
<copy file="${staging_folder}/arduino-builder-windows/arduino-builder.exe" tofile="windows/work/arduino-builder.exe" />
|
||||
<chmod perm="755" file="windows/work/arduino-builder.exe" />
|
||||
<move file="${staging_folder}/arduino-builder-windows/tools" tofile="windows/work/tools-builder"/>
|
||||
<copy todir="windows/work/hardware" overwrite="true">
|
||||
<fileset dir="${staging_folder}/arduino-builder-windows/hardware" includes="*.txt"/>
|
||||
</copy>
|
||||
<delete dir="${staging_folder}/arduino-builder-windows" includeemptydirs="true"/>
|
||||
|
||||
<antcall target="assemble">
|
||||
<param name="target.path" value="windows/work" />
|
||||
</antcall>
|
||||
|
Loading…
Reference in New Issue
Block a user