From e747b21ae0de48c47aed06265e16dca98f789a13 Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Tue, 9 Aug 2016 15:52:10 -0400 Subject: [PATCH] Propagate fixes for Arduino from CDT 9.0 to master. Change-Id: If7d02530ba46f01f7f58724cba7b4921b93ca895 --- .../arduino/core/tests/FullIntegration.java | 2 +- .../core/internal/ArduinoPreferences.java | 8 +- .../core/internal/HierarchicalProperties.java | 8 +- .../core/internal/LinkedProperties.java | 34 +++ .../core/internal/board/ArduinoBoard.java | 7 + .../core/internal/board/ArduinoLibrary.java | 1 + .../core/internal/board/ArduinoManager.java | 149 ++++++---- .../core/internal/board/ArduinoPackage.java | 119 +++++--- .../core/internal/board/ArduinoPlatform.java | 56 +++- .../core/internal/board/ArduinoTool.java | 23 +- .../internal/board/ArduinoToolSystem.java | 1 + .../core/internal/board/ToolDependency.java | 6 +- .../build/ArduinoBuildConfiguration.java | 259 ++++++++---------- .../ArduinoBuildConfigurationProvider.java | 75 ++--- .../ArduinoLaunchConfigurationDelegate.java | 6 +- .../ArduinoLaunchConfigurationProvider.java | 8 +- .../remote/ArduinoRemoteConnection.java | 45 ++- .../templates/Makefile | 113 ++++---- .../templates/cppsketch/manifest.xml | 3 +- .../downloads/ArduinoDownloadsManager.java | 34 ++- .../downloads/LibrariesTabControl.java | 20 +- .../downloads/PlatformsTabControl.java | 20 +- .../preferences/ArduinoPreferencePage.java | 41 +++ .../project/NewArduinoProjectWizard.java | 21 +- .../internal/remote/BoardPropertyControl.java | 37 ++- 25 files changed, 677 insertions(+), 419 deletions(-) create mode 100644 toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/LinkedProperties.java diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/FullIntegration.java b/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/FullIntegration.java index 41994a8e053..3df532ce624 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/FullIntegration.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/FullIntegration.java @@ -172,7 +172,7 @@ public class FullIntegration { ArduinoRemoteConnection arduinoTarget = createTarget(board); ArduinoBuildConfigurationProvider provider = (ArduinoBuildConfigurationProvider) buildConfigManager .getProvider(ArduinoBuildConfigurationProvider.ID); - ArduinoBuildConfiguration config = provider.createConfiguration(project, arduinoTarget, "run", monitor); + ArduinoBuildConfiguration config = provider.getConfiguration(project, arduinoTarget, "run", monitor); System.out.println(String.format("Building board: %s\n %s - %s", board.getName(), board.getId(), board.getPlatform().getInstallPath())); diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java index 988ef26d933..fb532504bc7 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java @@ -39,7 +39,13 @@ public class ArduinoPreferences { } public static void setArduinoHome(Path home) { - getPrefs().put(ARDUINO_HOME, home.toString()); + IEclipsePreferences prefs = getPrefs(); + prefs.put(ARDUINO_HOME, home.toString()); + try { + prefs.flush(); + } catch (BackingStoreException e) { + Activator.log(e); + } } public static String getBoardUrls() { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/HierarchicalProperties.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/HierarchicalProperties.java index 382257608db..dea25707f39 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/HierarchicalProperties.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/HierarchicalProperties.java @@ -23,10 +23,10 @@ public class HierarchicalProperties { public HierarchicalProperties() { } - public HierarchicalProperties(Properties properties) { - for (Map.Entry entry : properties.entrySet()) { - String key = (String) entry.getKey(); - String value = (String) entry.getValue(); + public HierarchicalProperties(LinkedProperties properties) { + for (Object keyObj : properties.orderedKeys()) { + String key = (String) keyObj; + String value = (String) properties.get(key); putProperty(key, value); } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/LinkedProperties.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/LinkedProperties.java new file mode 100644 index 00000000000..8d8853f77a1 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/LinkedProperties.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.arduino.core.internal; + +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Properties; + +public class LinkedProperties extends Properties { + + private static final long serialVersionUID = 1L; + + private final HashSet keys = new LinkedHashSet(); + + public Iterable orderedKeys() { + return Collections.list(keys()); + } + + public Enumeration keys() { + return Collections.enumeration(keys); + } + + public Object put(Object key, Object value) { + keys.add(key); + return super.put(key, value); + } +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoard.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoard.java index 0bb2b8d667d..bf9e4421410 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoard.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoard.java @@ -93,4 +93,11 @@ public class ArduinoBoard { return true; } + @Override + public String toString() { + String arch = getPlatform().getArchitecture(); + String pkg = getPlatform().getPackage().getName(); + return pkg + ',' + arch + ',' + id + ',' + name; + } + } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoLibrary.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoLibrary.java index db11c42b44f..90ed3b1f0e9 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoLibrary.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoLibrary.java @@ -190,6 +190,7 @@ public class ArduinoLibrary { public Path getInstallPath() { return installPath == null ? ArduinoPreferences.getArduinoHome().resolve("libraries").resolve(name.replaceAll("[ ()]", "_")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + .resolve(version) : installPath; } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java index d894855033b..6fe12c5d5c9 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java @@ -83,6 +83,7 @@ public class ArduinoManager { private Properties props; + private Path arduinoHome = ArduinoPreferences.getArduinoHome(); private Map packages; private Map installedLibraries; @@ -91,6 +92,14 @@ public class ArduinoManager { } private synchronized void init() throws CoreException { + if (!arduinoHome.equals(ArduinoPreferences.getArduinoHome())) { + // Arduino Home changed, reset. + props = null; + packages = null; + installedLibraries = null; + arduinoHome = ArduinoPreferences.getArduinoHome(); + } + if (props == null) { if (!Files.exists(ArduinoPreferences.getArduinoHome())) { try { @@ -113,9 +122,6 @@ public class ArduinoManager { // See if we need a conversion int version = Integer.parseInt(props.getProperty(VERSION_KEY, "1")); //$NON-NLS-1$ if (version < Integer.parseInt(VERSION)) { - // Need to move the directories around - convertPackageDirs(); - props.setProperty(VERSION_KEY, VERSION); try (FileWriter writer = new FileWriter(getVersionFile().toFile())) { props.store(writer, ""); //$NON-NLS-1$ @@ -126,42 +132,6 @@ public class ArduinoManager { } } - private void convertPackageDirs() throws CoreException { - Path packagesDir = ArduinoPreferences.getArduinoHome().resolve("packages"); //$NON-NLS-1$ - if (!Files.isDirectory(packagesDir)) { - return; - } - - try { - Files.list(packagesDir).forEach(path -> { - try { - Path hardwarePath = path.resolve("hardware"); //$NON-NLS-1$ - Path badPath = hardwarePath.resolve(path.getFileName()); - Path tmpDir = Files.createTempDirectory(packagesDir, "tbd"); //$NON-NLS-1$ - Path badPath2 = tmpDir.resolve(badPath.getFileName()); - Files.move(badPath, badPath2); - Files.list(badPath2).forEach(archPath -> { - try { - Optional latest = Files.list(archPath) - .reduce((path1, path2) -> compareVersions(path1.getFileName().toString(), - path2.getFileName().toString()) > 0 ? path1 : path2); - if (latest.isPresent()) { - Files.move(latest.get(), hardwarePath.resolve(archPath.getFileName())); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - recursiveDelete(tmpDir); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - } catch (RuntimeException | IOException e) { - throw Activator.coreException(e); - } - } - public void convertLibrariesDir() throws CoreException { Path librariesDir = ArduinoPreferences.getArduinoHome().resolve("libraries"); //$NON-NLS-1$ if (!Files.isDirectory(librariesDir)) { @@ -219,15 +189,15 @@ public class ArduinoManager { return pkg != null ? pkg.getInstalledPlatform(architecture) : null; } - public synchronized Collection getAvailablePlatforms(IProgressMonitor monitor) throws CoreException { + public synchronized Collection getAvailablePlatforms(IProgressMonitor monitor) + throws CoreException { List platforms = new ArrayList<>(); URL[] urls = ArduinoPreferences.getBoardUrlList(); SubMonitor sub = SubMonitor.convert(monitor, urls.length + 1); sub.beginTask("Downloading package descriptions", urls.length); //$NON-NLS-1$ for (URL url : urls) { - Path packagePath = ArduinoPreferences.getArduinoHome() - .resolve(Paths.get(url.getPath()).getFileName()); + Path packagePath = ArduinoPreferences.getArduinoHome().resolve(Paths.get(url.getPath()).getFileName()); try { Files.createDirectories(ArduinoPreferences.getArduinoHome()); try (InputStream in = url.openStream()) { @@ -249,6 +219,36 @@ public class ArduinoManager { return platforms; } + public synchronized Collection getPlatformUpdates(IProgressMonitor monitor) + throws CoreException { + List platforms = new ArrayList<>(); + URL[] urls = ArduinoPreferences.getBoardUrlList(); + SubMonitor sub = SubMonitor.convert(monitor, urls.length + 1); + + sub.beginTask("Downloading package descriptions", urls.length); //$NON-NLS-1$ + for (URL url : urls) { + Path packagePath = ArduinoPreferences.getArduinoHome().resolve(Paths.get(url.getPath()).getFileName()); + try { + Files.createDirectories(ArduinoPreferences.getArduinoHome()); + try (InputStream in = url.openStream()) { + Files.copy(in, packagePath, StandardCopyOption.REPLACE_EXISTING); + } + } catch (IOException e) { + throw Activator.coreException(String.format("Error loading %s", url.toString()), e); //$NON-NLS-1$ + } + sub.worked(1); + } + + sub.beginTask("Loading available package updates", 1); //$NON-NLS-1$ + resetPackages(); + for (ArduinoPackage pkg : getPackages()) { + platforms.addAll(pkg.getPlatformUpdates()); + } + sub.done(); + + return platforms; + } + public void installPlatforms(Collection platforms, IProgressMonitor monitor) throws CoreException { SubMonitor sub = SubMonitor.convert(monitor, platforms.size()); for (ArduinoPlatform platform : platforms) { @@ -293,8 +293,8 @@ public class ArduinoManager { } private synchronized void initPackages() throws CoreException { + init(); if (packages == null) { - init(); packages = new HashMap<>(); try { @@ -304,8 +304,13 @@ public class ArduinoManager { try (Reader reader = new FileReader(path.toFile())) { PackageIndex index = new Gson().fromJson(reader, PackageIndex.class); for (ArduinoPackage pkg : index.getPackages()) { - pkg.init(); - packages.put(pkg.getName(), pkg); + ArduinoPackage p = packages.get(pkg.getName()); + if (p == null) { + pkg.init(); + packages.put(pkg.getName(), pkg); + } else { + p.merge(pkg); + } } } catch (IOException e) { Activator.log(e); @@ -353,8 +358,7 @@ public class ArduinoManager { // For backwards compat, check platform name for (ArduinoPlatform platform : getInstalledPlatforms()) { - if (platform.getPackage().getName().equals(packageName) - && platform.getName().equals(architecture)) { + if (platform.getPackage().getName().equals(packageName) && platform.getName().equals(architecture)) { return platform.getBoardByName(boardId); } } @@ -367,7 +371,7 @@ public class ArduinoManager { return pkg != null ? pkg.getTool(toolName, version) : null; } - public void initInstalledLibraries() throws CoreException { + private void initInstalledLibraries() throws CoreException { init(); if (installedLibraries == null) { installedLibraries = new HashMap<>(); @@ -375,7 +379,7 @@ public class ArduinoManager { Path librariesDir = ArduinoPreferences.getArduinoHome().resolve("libraries"); //$NON-NLS-1$ if (Files.isDirectory(librariesDir)) { try { - Files.find(librariesDir, 2, + Files.find(librariesDir, 3, (path, attrs) -> path.getFileName().toString().equals("library.properties")) //$NON-NLS-1$ .forEach(path -> { try { @@ -434,6 +438,39 @@ public class ArduinoManager { } } + public Collection getLibraryUpdates(IProgressMonitor monitor) throws CoreException { + try { + initInstalledLibraries(); + Map libs = new HashMap<>(); + + SubMonitor sub = SubMonitor.convert(monitor, "Downloading library index", 2); + Path librariesPath = ArduinoPreferences.getArduinoHome().resolve(LIBRARIES_FILE); + URL librariesUrl = new URL(LIBRARIES_URL); + Files.createDirectories(ArduinoPreferences.getArduinoHome()); + Files.copy(librariesUrl.openStream(), librariesPath, StandardCopyOption.REPLACE_EXISTING); + sub.worked(1); + + try (Reader reader = new FileReader(librariesPath.toFile())) { + sub.setTaskName("Calculating library updates"); + LibraryIndex libraryIndex = new Gson().fromJson(reader, LibraryIndex.class); + for (ArduinoLibrary library : libraryIndex.getLibraries()) { + String libraryName = library.getName(); + ArduinoLibrary installed = installedLibraries.get(libraryName); + if (installed != null && compareVersions(library.getVersion(), installed.getVersion()) > 0) { + ArduinoLibrary current = libs.get(libraryName); + if (current == null || compareVersions(library.getVersion(), current.getVersion()) > 0) { + libs.put(libraryName, library); + } + } + } + } + sub.done(); + return libs.values(); + } catch (IOException e) { + throw Activator.coreException(e); + } + } + public void installLibraries(Collection libraries, IProgressMonitor monitor) throws CoreException { SubMonitor sub = SubMonitor.convert(monitor, libraries.size()); for (ArduinoLibrary library : libraries) { @@ -462,8 +499,7 @@ public class ArduinoManager { sub.done(); } - public Collection getLibraries(IProject project) - throws CoreException { + public Collection getLibraries(IProject project) throws CoreException { initInstalledLibraries(); IEclipsePreferences settings = getSettings(project); String librarySetting = settings.get(LIBRARIES, "[]"); //$NON-NLS-1$ @@ -577,7 +613,16 @@ public class ArduinoManager { } // Strip the first directory of the path - Path entryPath = installPath.resolve(path.subpath(1, path.getNameCount())); + Path entryPath; + switch (path.getName(0).toString()) { + case "i586": + case "i686": + // Cheat for Intel + entryPath = installPath.resolve(path); + break; + default: + entryPath = installPath.resolve(path.subpath(1, path.getNameCount())); + } Files.createDirectories(entryPath.getParent()); diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPackage.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPackage.java index 19a9fffa1b9..b0aa273292b 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPackage.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPackage.java @@ -7,19 +7,14 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.core.internal.board; -import java.io.FileReader; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Properties; -import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.core.runtime.CoreException; @@ -36,6 +31,7 @@ public class ArduinoPackage { // end JSON fields private Map installedPlatforms; + private Map latestTools; public String getName() { return name; @@ -70,6 +66,34 @@ public class ArduinoPackage { } } + void merge(ArduinoPackage other) { + // Redo calculated fields + installedPlatforms = null; + latestTools = null; + + if (other.platforms != null) { + if (platforms != null) { + platforms.addAll(other.platforms); + } else { + platforms = other.platforms; + } + for (ArduinoPlatform platform : other.platforms) { + platform.init(this); + } + } + + if (other.tools != null) { + if (tools != null) { + tools.addAll(other.tools); + } else { + tools = other.tools; + } + for (ArduinoTool tool : other.tools) { + tool.init(this); + } + } + } + public ArduinoPlatform getPlatform(String architecture, String version) { if (platforms != null) { for (ArduinoPlatform plat : platforms) { @@ -85,36 +109,23 @@ public class ArduinoPackage { return ArduinoPreferences.getArduinoHome().resolve("packages").resolve(getName()); //$NON-NLS-1$ } - private void initInstalledPlatforms() throws CoreException { + private synchronized void initInstalledPlatforms() throws CoreException { if (installedPlatforms == null) { installedPlatforms = new HashMap<>(); - if (Files.isDirectory(getInstallPath())) { - Path platformTxt = Paths.get("platform.txt"); //$NON-NLS-1$ - try { - Path hardware = getInstallPath().resolve("hardware"); - if (Files.exists(hardware)) { - Files.find(hardware, 2, // $NON-NLS-1$ - (path, attrs) -> path.getFileName().equals(platformTxt)).forEach(path -> { - try (FileReader reader = new FileReader(path.toFile())) { - Properties platformProperties = new Properties(); - platformProperties.load(reader); - String arch = path.getName(path.getNameCount() - 2).toString(); - String version = platformProperties.getProperty("version"); //$NON-NLS-1$ + Path hardware = getInstallPath().resolve("hardware"); //$NON-NLS-1$ + if (Files.isDirectory(hardware)) { + for (ArduinoPlatform platform : platforms) { + String arch = platform.getArchitecture(); + String version = platform.getVersion(); - ArduinoPlatform platform = getPlatform(arch, version); - if (platform != null) { - platform.setPlatformProperties(platformProperties); - installedPlatforms.put(arch, platform); - } // TODO manually add it if was removed - // from index - } catch (IOException e) { - throw new RuntimeException(e); - } - }); + Path platPath = hardware.resolve(arch).resolve(version); + if (Files.exists(platPath)) { + ArduinoPlatform current = installedPlatforms.get(arch); + if (current == null || ArduinoManager.compareVersions(version, current.getVersion()) > 0) { + installedPlatforms.put(arch, platform); + } } - } catch (IOException e) { - throw Activator.coreException(e); } } } @@ -147,9 +158,24 @@ public class ArduinoPackage { Map platformMap = new HashMap<>(); for (ArduinoPlatform platform : platforms) { if (!installedPlatforms.containsKey(platform.getArchitecture())) { - ArduinoPlatform p = platformMap.get(platform.getName()); + ArduinoPlatform p = platformMap.get(platform.getArchitecture()); if (p == null || ArduinoManager.compareVersions(platform.getVersion(), p.getVersion()) > 0) { - platformMap.put(platform.getName(), platform); + platformMap.put(platform.getArchitecture(), platform); + } + } + } + return platformMap.values(); + } + + public Collection getPlatformUpdates() throws CoreException { + initInstalledPlatforms(); + Map platformMap = new HashMap<>(); + for (ArduinoPlatform platform : platforms) { + ArduinoPlatform installed = installedPlatforms.get(platform.getArchitecture()); + if (installed != null && ArduinoManager.compareVersions(platform.getVersion(), installed.getVersion()) > 0) { + ArduinoPlatform current = platformMap.get(platform.getArchitecture()); + if (current == null || ArduinoManager.compareVersions(platform.getVersion(), current.getVersion()) > 0) { + platformMap.put(platform.getArchitecture(), platform); } } } @@ -169,29 +195,40 @@ public class ArduinoPackage { return null; } - public ArduinoTool getLatestTool(String toolName) { - ArduinoTool latest = null; - for (ArduinoTool tool : tools) { - if (tool.getName().equals(toolName) && tool.isInstalled()) { - if (latest == null || ArduinoManager.compareVersions(tool.getVersion(), latest.getVersion()) > 0) { - latest = tool; + private void initLatestTools() { + if (latestTools == null) { + latestTools = new HashMap<>(); + + for (ArduinoTool tool : tools) { + ArduinoTool current = latestTools.get(tool.getName()); + if (current == null || ArduinoManager.compareVersions(tool.getVersion(), current.getVersion()) > 0) { + latestTools.put(tool.getName(), tool); } } } - return latest; + } + + public ArduinoTool getLatestTool(String toolName) { + initLatestTools(); + return latestTools.get(toolName); + } + + public Collection getLatestTools() { + initLatestTools(); + return latestTools.values(); } @Override public boolean equals(Object obj) { if (obj instanceof ArduinoPackage) { - return ((ArduinoPackage) obj).getName().equals(name); + return ((ArduinoPackage) obj).getName().equals(getName()); } return super.equals(obj); } @Override public int hashCode() { - return name.hashCode(); + return getName().hashCode(); } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java index 26110ac91c0..e2f8fa3e31e 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java @@ -24,11 +24,11 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Properties; import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties; +import org.eclipse.cdt.arduino.core.internal.LinkedProperties; import org.eclipse.cdt.arduino.core.internal.Messages; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -52,9 +52,11 @@ public class ArduinoPlatform { private List toolsDependencies; // end JSON fields + private Path installPath; private ArduinoPackage pkg; private HierarchicalProperties boardsProperties; - private Properties platformProperties; + private LinkedProperties platformProperties; + private HierarchicalProperties programmerProperties; private Map menus = new HashMap<>(); private Map libraries; @@ -81,7 +83,7 @@ public class ArduinoPlatform { } public String getVersion() { - return version; + return version.replace('+', '_'); } public String getCategory() { @@ -104,13 +106,13 @@ public class ArduinoPlatform { return size; } - public void setPlatformProperties(Properties platformProperties) { + public void setPlatformProperties(LinkedProperties platformProperties) { this.platformProperties = platformProperties; } public List getBoards() { if (boardsProperties == null) { - Properties boardProps = new Properties(); + LinkedProperties boardProps = new LinkedProperties(); if (Files.exists(getInstallPath())) { try (InputStream is = new FileInputStream(getInstallPath().resolve("boards.txt").toFile()); //$NON-NLS-1$ @@ -182,9 +184,9 @@ public class ArduinoPlatform { return null; } - public Properties getPlatformProperties() throws CoreException { + public LinkedProperties getPlatformProperties() throws CoreException { if (platformProperties == null) { - platformProperties = new Properties(); + platformProperties = new LinkedProperties(); try (BufferedReader reader = new BufferedReader( new FileReader(getInstallPath().resolve("platform.txt").toFile()))) { //$NON-NLS-1$ // There are regex's here and need to preserve the \'s @@ -197,14 +199,50 @@ public class ArduinoPlatform { platformProperties.load(reader1); } } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading platform.txt", e)); //$NON-NLS-1$ + throw Activator.coreException(e); } } return platformProperties; } + public HierarchicalProperties getProgrammers() throws CoreException { + if (programmerProperties == null) { + LinkedProperties props = new LinkedProperties(); + Path programmersTxt = getInstallPath().resolve("programmers.txt"); //$NON-NLS-1$ + if (Files.exists(programmersTxt)) { + try (FileInputStream in = new FileInputStream(programmersTxt.toFile())) { + props.load(in); + programmerProperties = new HierarchicalProperties(props); + } catch (IOException e) { + throw Activator.coreException(e); + } + } else { + // TODO for now, grab the one from the arduino package + ArduinoManager manager = Activator.getService(ArduinoManager.class); + ArduinoPackage arduinoPkg = manager.getPackage("arduino"); //$NON-NLS-1$ + if (arduinoPkg != null) { + ArduinoPlatform arduinoPlat = arduinoPkg.getInstalledPlatform(getArchitecture()); + if (arduinoPlat != null) { + programmerProperties = arduinoPlat.getProgrammers(); + } + } + } + } + return programmerProperties; + } + public Path getInstallPath() { - return getPackage().getInstallPath().resolve("hardware").resolve(architecture); //$NON-NLS-1$ + if (installPath == null) { + Path oldPath = getPackage().getInstallPath().resolve("hardware").resolve(getPackage().getName()) //$NON-NLS-1$ + .resolve(getArchitecture()).resolve(getVersion()); + if (Files.exists(oldPath)) { + installPath = oldPath; + } else { + installPath = getPackage().getInstallPath().resolve("hardware").resolve(getArchitecture()) //$NON-NLS-1$ + .resolve(getVersion()); + } + } + return installPath; } private void initLibraries() throws CoreException { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java index 2561cbcc2bd..8329942d1cd 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java @@ -38,7 +38,7 @@ public class ArduinoTool { } public String getVersion() { - return version; + return version.replace('+', '_'); } public List getSystems() { @@ -53,26 +53,7 @@ public class ArduinoTool { } public Path getInstallPath() { - // TODO remove migration in Neon - Path oldPath = ArduinoPreferences.getArduinoHome().resolve("tools").resolve(pkg.getName()).resolve(name) //$NON-NLS-1$ - .resolve(version); - Path newPath = getPackage().getInstallPath().resolve("tools").resolve(name).resolve(version); //$NON-NLS-1$ - if (Files.exists(oldPath)) { - try { - Files.createDirectories(newPath.getParent()); - Files.move(oldPath, newPath); - for (Path parent = oldPath.getParent(); parent != null; parent = parent.getParent()) { - if (Files.newDirectoryStream(parent).iterator().hasNext()) { - break; - } else { - Files.delete(parent); - } - } - } catch (IOException e) { - Activator.log(e); - } - } - return newPath; + return getPackage().getInstallPath().resolve("tools").resolve(getName()).resolve(getVersion()); //$NON-NLS-1$ } public boolean isInstalled() { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoToolSystem.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoToolSystem.java index cf457af06ff..a4a14135bfc 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoToolSystem.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoToolSystem.java @@ -55,6 +55,7 @@ public class ArduinoToolSystem { case Platform.OS_MACOSX: switch (host) { case "i386-apple-darwin11": //$NON-NLS-1$ + case "i386-apple-darwin": //$NON-NLS-1$ case "x86_64-apple-darwin": //$NON-NLS-1$ return true; default: diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ToolDependency.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ToolDependency.java index ac9f5c0dff0..8659ba5310d 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ToolDependency.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ToolDependency.java @@ -28,18 +28,18 @@ public class ToolDependency { } public String getVersion() { - return version; + return version.replace('+', '_'); } public ArduinoTool getTool() throws CoreException { - return Activator.getService(ArduinoManager.class).getTool(packager, name, version); + return Activator.getService(ArduinoManager.class).getTool(getPackager(), getName(), getVersion()); } public void install(IProgressMonitor monitor) throws CoreException { ArduinoTool tool = getTool(); if (tool == null) { throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), - String.format("Tool not found %s %s", name, version))); + String.format("Tool not found %s %s", getName(), getVersion()))); } getTool().install(monitor); } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java index 9f302ea230c..f307fcc4117 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java @@ -69,108 +69,57 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.content.IContentType; -import org.osgi.service.prefs.BackingStoreException; -import org.osgi.service.prefs.Preferences; +import org.eclipse.remote.core.IRemoteConnectionChangeListener; +import org.eclipse.remote.core.IRemoteServicesManager; +import org.eclipse.remote.core.RemoteConnectionChangeEvent; import freemarker.cache.TemplateLoader; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; -public class ArduinoBuildConfiguration extends CBuildConfiguration implements TemplateLoader { +public class ArduinoBuildConfiguration extends CBuildConfiguration + implements TemplateLoader, IRemoteConnectionChangeListener { - private static final String PACKAGE_NAME = "packageName"; //$NON-NLS-1$ - private static final String PLATFORM_NAME = "platformName"; //$NON-NLS-1$ - private static final String BOARD_NAME = "boardName"; //$NON-NLS-1$ - private static final String MENU_QUALIFIER = "menu_"; //$NON-NLS-1$ + private static final ArduinoManager manager = Activator.getService(ArduinoManager.class); + private static final boolean isWindows = Platform.getOS().equals(Platform.OS_WIN32); - private static ArduinoManager manager = Activator.getService(ArduinoManager.class); - - private final ArduinoBoard board; + private final ArduinoRemoteConnection target; private final String launchMode; + private ArduinoBoard defaultBoard; private Properties properties; // for Makefile generation private Configuration templateConfig; - private final static boolean isWindows = Platform.getOS().equals(Platform.OS_WIN32); - - public ArduinoBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { - super(config, name); - - Preferences settings = getSettings(); - String packageName = settings.get(PACKAGE_NAME, ""); //$NON-NLS-1$ - String platformName = settings.get(PLATFORM_NAME, ""); //$NON-NLS-1$ - String boardName = settings.get(BOARD_NAME, ""); //$NON-NLS-1$ - ArduinoBoard b = manager.getBoard(packageName, platformName, boardName); - - if (b == null) { - // Default to Uno or first one we find - b = manager.getBoard("Arduino/Genuino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if (b == null) { - Collection boards = manager.getInstalledBoards(); - if (!boards.isEmpty()) { - b = boards.iterator().next(); - } - } - } - board = b; - - int i = name.lastIndexOf('.'); - this.launchMode = name.substring(i + 1); + /** + * Default configuration. + * + * @param config + */ + ArduinoBuildConfiguration(IBuildConfiguration config, String name, String launchMode, ArduinoBoard defaultBoard, IToolChain toolChain) throws CoreException { + super(config, ".default", toolChain); //$NON-NLS-1$ + this.target = null; + this.launchMode = launchMode; + this.defaultBoard = defaultBoard; } - ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoBoard board, String launchMode, + ArduinoBuildConfiguration(IBuildConfiguration config, String name, String launchMode, ArduinoRemoteConnection target, IToolChain toolChain) throws CoreException { super(config, name, toolChain); - this.board = board; + this.target = target; this.launchMode = launchMode; - - // Store the board identifer - ArduinoPlatform platform = board.getPlatform(); - ArduinoPackage pkg = platform.getPackage(); - - Preferences settings = getSettings(); - settings.put(PACKAGE_NAME, pkg.getName()); - settings.put(PLATFORM_NAME, platform.getName()); - settings.put(BOARD_NAME, board.getName()); - - try { - settings.flush(); - } catch (BackingStoreException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e)); //$NON-NLS-1$ - } + IRemoteServicesManager remoteManager = Activator.getService(IRemoteServicesManager.class); + remoteManager.addRemoteConnectionChangeListener(this); } - ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoRemoteConnection target, - String launchMode, IToolChain toolChain) throws CoreException { - this(config, name, target.getBoard(), launchMode, toolChain); - - // Store the menu settings - HierarchicalProperties menus = board.getMenus(); - if (menus != null) { - Preferences settings = getSettings(); - for (String id : menus.getChildren().keySet()) { - String value = target.getMenuValue(id); - if (value != null) { - settings.put(MENU_QUALIFIER + id, value); - } - } - - try { - settings.flush(); - } catch (BackingStoreException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e)); //$NON-NLS-1$ - } + @Override + public synchronized void connectionChanged(RemoteConnectionChangeEvent event) { + if (event.getConnection().equals(target.getRemoteConnection())) { + properties = null; } } - static String generateName(ArduinoBoard board, String launchMode) { - ArduinoPlatform platform = board.getPlatform(); - ArduinoPackage pkg = platform.getPackage(); - return pkg.getName() + '.' + platform.getArchitecture() + '.' + board.getId() + '.' + launchMode; - } - @SuppressWarnings("unchecked") @Override public T getAdapter(Class adapter) { @@ -184,31 +133,21 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te return launchMode; } - public boolean matches(ArduinoRemoteConnection target) throws CoreException { - ArduinoBoard otherBoard = target.getBoard(); - if (!getBoard().equals(otherBoard)) { - return false; - } - - Preferences settings = getSettings(); - HierarchicalProperties menus = board.getMenus(); - if (menus != null) { - for (String id : menus.getChildren().keySet()) { - if (!settings.get(MENU_QUALIFIER + id, "").equals(target.getMenuValue(id))) { //$NON-NLS-1$ - return false; - } - } - } - - return true; + public ArduinoRemoteConnection getTarget() { + return target; } public ArduinoBoard getBoard() throws CoreException { - return board; + if (target != null) { + return target.getBoard(); + } else { + return defaultBoard; + } } private synchronized Properties getProperties() throws CoreException { if (properties == null) { + ArduinoBoard board = getBoard(); ArduinoPlatform platform = board.getPlatform(); // IDE generated properties @@ -219,20 +158,21 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te properties.put("build.arch", platform.getArchitecture().toUpperCase()); //$NON-NLS-1$ properties.put("build.path", "."); //$NON-NLS-1$ //$NON-NLS-2$ properties.put("build.core.path", //$NON-NLS-1$ - platform.getInstallPath().resolve("core").resolve("{build.core}").toString()); //$NON-NLS-1$ //$NON-NLS-2$ + platform.getInstallPath().resolve("cores").resolve("{build.core}").toString()); //$NON-NLS-1$ //$NON-NLS-2$ properties.put("build.system.path", platform.getInstallPath().resolve("system").toString()); //$NON-NLS-1$ //$NON-NLS-2$ properties.put("build.variant.path", //$NON-NLS-1$ platform.getInstallPath().resolve("variants").resolve("{build.variant}").toString()); //$NON-NLS-1$ //$NON-NLS-2$ - // Everyone seems to want to use the avr-gcc and avrdude tools + // Everyone seems to want to use arduino package tools ArduinoPackage arduinoPackage = manager.getPackage("arduino"); //$NON-NLS-1$ - ArduinoTool avrgcc = arduinoPackage.getLatestTool("avr-gcc"); //$NON-NLS-1$ - if (avrgcc != null) { - properties.put("runtime.tools.avr-gcc.path", avrgcc.getInstallPath().toString()); //$NON-NLS-1$ - } - ArduinoTool avrdude = arduinoPackage.getLatestTool("avrdude"); //$NON-NLS-1$ - if (avrdude != null) { - properties.put("runtime.tools.avrdude.path", avrdude.getInstallPath().toString()); //$NON-NLS-1$ + if (arduinoPackage != null) { + for (ArduinoTool tool : arduinoPackage.getLatestTools()) { + properties.put("runtime.tools." + tool.getName() + ".path", tool.getInstallPath().toString()); //$NON-NLS-1$ //$NON-NLS-2$ + } + for (ArduinoTool tool : arduinoPackage.getTools()) { + properties.put("runtime.tools." + tool.getName() + '-' + tool.getVersion() + ".path", //$NON-NLS-1$ //$NON-NLS-2$ + tool.getInstallPath().toString()); + } } // Super Platform @@ -257,24 +197,22 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te } // Board - ArduinoBoard board = getBoard(); properties.putAll(board.getBoardProperties()); // Menus - Preferences settings = getSettings(); HierarchicalProperties menus = board.getMenus(); if (menus != null) { for (Entry menuEntry : menus.getChildren().entrySet()) { String key = menuEntry.getKey(); - String defaultValue; - Iterator i = menuEntry.getValue().getChildren().values().iterator(); - if (i.hasNext()) { - defaultValue = i.next().getValue(); - } else { - defaultValue = ""; //$NON-NLS-1$ + String value = target.getMenuValue(key); + if (value == null || value.isEmpty()) { + Iterator i = menuEntry.getValue().getChildren().values().iterator(); + if (i.hasNext()) { + HierarchicalProperties first = i.next(); + value = first.getValue(); + } } - String value = settings.get(MENU_QUALIFIER + key, defaultValue); - if (!value.isEmpty()) { + if (value != null && !value.isEmpty()) { properties.putAll(board.getMenuProperties(key, value)); } } @@ -291,8 +229,11 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te ArduinoBoard board = getBoard(); ArduinoPlatform platform = board.getPlatform(); + Properties properties = new Properties(); Map buildModel = new HashMap<>(); buildModel.put("boardId", board.getId()); //$NON-NLS-1$ + properties.put("object_file", "$@"); //$NON-NLS-1$ //$NON-NLS-2$ + properties.put("source_file", "$<"); //$NON-NLS-1$ //$NON-NLS-2$ // The list of source files in the project final Path projectPath = new File(project.getLocationURI()).toPath(); @@ -322,7 +263,6 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te buildModel.put("libraries_path", pathString(ArduinoPreferences.getArduinoHome().resolve("libraries"))); //$NON-NLS-1$ //$NON-NLS-2$ // the recipes - Properties properties = new Properties(); properties.putAll(getProperties()); buildModel.put("build_path", properties.get("build.path")); //$NON-NLS-1$ //$NON-NLS-2$ buildModel.put("project_name", project.getName()); //$NON-NLS-1$ @@ -336,12 +276,18 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te } includes += '"' + pathString(include) + '"'; } + for (ArduinoLibrary lib : manager.getLibraries(project)) { for (Path include : lib.getIncludePath()) { includes += " -I\"" + pathString(include) + '"'; //$NON-NLS-1$ } } + + // Magic recipes for platform builds with platform includes properties.put("includes", includes); //$NON-NLS-1$ + buildModel.put("recipe_cpp_o_pattern_plat", resolveProperty("recipe.cpp.o.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$ + buildModel.put("recipe_c_o_pattern_plat", resolveProperty("recipe.c.o.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$ + buildModel.put("recipe_S_o_pattern_plat", resolveProperty("recipe.S.o.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$ ArduinoPlatform corePlatform = platform; String core = properties.getProperty("build.core"); //$NON-NLS-1$ @@ -352,29 +298,30 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te core = segments[1]; } } + buildModel.put("platform_path", pathString(corePlatform.getInstallPath())); //$NON-NLS-1$ Path corePath = corePlatform.getInstallPath().resolve("cores").resolve(core); //$NON-NLS-1$ buildModel.put("platform_core_path", pathString(corePath)); //$NON-NLS-1$ List coreSources = new ArrayList<>(); getSources(coreSources, corePath, true); buildModel.put("platform_core_srcs", coreSources); //$NON-NLS-1$ - ArduinoPlatform variantPlatform = platform; - String variant = properties.getProperty("build.variant"); //$NON-NLS-1$ - if (variant.contains(":")) { //$NON-NLS-1$ - String[] segments = variant.split(":"); //$NON-NLS-1$ - if (segments.length == 2) { - variantPlatform = manager.getInstalledPlatform(segments[0], platform.getArchitecture()); - variant = segments[1]; - } - } - Path variantPath = variantPlatform.getInstallPath().resolve("variants").resolve(variant); //$NON-NLS-1$ - buildModel.put("platform_variant_path", pathString(variantPath)); //$NON-NLS-1$ List variantSources = new ArrayList<>(); - getSources(variantSources, variantPath, true); + String variant = properties.getProperty("build.variant"); //$NON-NLS-1$ + if (variant != null) { + ArduinoPlatform variantPlatform = platform; + if (variant.contains(":")) { //$NON-NLS-1$ + String[] segments = variant.split(":"); //$NON-NLS-1$ + if (segments.length == 2) { + variantPlatform = manager.getInstalledPlatform(segments[0], platform.getArchitecture()); + variant = segments[1]; + } + } + Path variantPath = variantPlatform.getInstallPath().resolve("variants").resolve(variant); //$NON-NLS-1$ + buildModel.put("platform_variant_path", pathString(variantPath)); //$NON-NLS-1$ + getSources(variantSources, variantPath, true); + } buildModel.put("platform_variant_srcs", variantSources); //$NON-NLS-1$ - properties.put("object_file", "$@"); //$NON-NLS-1$ //$NON-NLS-2$ - properties.put("source_file", "$<"); //$NON-NLS-1$ //$NON-NLS-2$ properties.put("archive_file", "core.a"); //$NON-NLS-1$ //$NON-NLS-2$ properties.put("archive_file_path", "{build.path}/{archive_file}"); //$NON-NLS-1$ //$NON-NLS-2$ properties.put("object_files", "$(PROJECT_OBJS) $(LIBRARIES_OBJS)"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -538,7 +485,10 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te } public String[] getUploadCommand(String serialPort) throws CoreException { - String toolName = getProperties().getProperty("upload.tool"); //$NON-NLS-1$ + Properties properties = new Properties(); + properties.putAll(getProperties()); + + String toolName = properties.getProperty("upload.tool"); //$NON-NLS-1$ ArduinoPlatform platform = getBoard().getPlatform(); if (toolName.contains(":")) { //$NON-NLS-1$ String[] segments = toolName.split(":"); //$NON-NLS-1$ @@ -548,8 +498,6 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te } } - Properties properties = getProperties(); - ArduinoTool uploadTool = platform.getPackage().getLatestTool(toolName); if (uploadTool != null) { properties.putAll(uploadTool.getToolProperties()); @@ -577,14 +525,33 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te } } - // TODO make this a preference - properties.put("upload.verbose", properties.getProperty("upload.params.verbose", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - properties.put("upload.verify", properties.getProperty("upload.params.verify", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + String command; + if (properties.get("upload.protocol") != null) { //$NON-NLS-1$ + // TODO make this a preference + properties.put("upload.verbose", properties.getProperty("upload.params.verbose", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + properties.put("upload.verify", properties.getProperty("upload.params.verify", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - // TODO needed this for esptool - properties.put("upload.resetmethod", "ck"); //$NON-NLS-1$ //$NON-NLS-2$ + command = resolveProperty("upload.pattern", properties); //$NON-NLS-1$ + } else { + // use the bootloader + String programmer = target.getProgrammer(); + if (programmer != null) { + HierarchicalProperties programmers = getBoard().getPlatform().getProgrammers(); + if (programmers != null) { + HierarchicalProperties programmerProps = programmers.getChild(programmer); + if (programmerProps != null) { + properties.putAll(programmerProps.flatten()); + } + } + } + + // TODO preference + properties.put("program.verbose", properties.getProperty("program.params.verbose", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + properties.put("program.verify", properties.getProperty("program.params.verify", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + command = resolveProperty("program.pattern", properties); //$NON-NLS-1$ + } - String command = resolveProperty("upload.pattern", properties); //$NON-NLS-1$ if (command == null) { throw Activator.coreException("Upload command not specified", null); } @@ -608,12 +575,16 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te ArduinoPlatform variantPlatform = platform; String variant = properties.getProperty("build.variant"); //$NON-NLS-1$ - if (variant.contains(":")) { //$NON-NLS-1$ - String[] segments = variant.split(":"); //$NON-NLS-1$ - if (segments.length == 2) { - variantPlatform = manager.getInstalledPlatform(segments[0], platform.getArchitecture()); - variant = segments[1]; + if (variant != null) { + if (variant.contains(":")) { //$NON-NLS-1$ + String[] segments = variant.split(":"); //$NON-NLS-1$ + if (segments.length == 2) { + variantPlatform = manager.getInstalledPlatform(segments[0], platform.getArchitecture()); + variant = segments[1]; + } } + } else { + return Arrays.asList(corePlatform.getInstallPath().resolve("cores").resolve(core)); //$NON-NLS-1$ } return Arrays.asList(corePlatform.getInstallPath().resolve("cores").resolve(core), //$NON-NLS-1$ diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java index 7b4f6adbe5d..94599855ca1 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java @@ -23,6 +23,9 @@ import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.remote.core.IRemoteConnection; +import org.eclipse.remote.core.IRemoteConnectionType; +import org.eclipse.remote.core.IRemoteServicesManager; public class ArduinoBuildConfigurationProvider implements ICBuildConfigurationProvider { @@ -49,52 +52,54 @@ public class ArduinoBuildConfigurationProvider implements ICBuildConfigurationPr } } if (board != null) { - // Create the toolChain - IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); - IToolChainProvider provider = toolChainManager.getProvider(ArduinoToolChainProvider.ID); - IToolChain toolChain = new ArduinoToolChain(provider, config); - toolChainManager.addToolChain(toolChain); - - return new ArduinoBuildConfiguration(config, name, board, "run", toolChain); //$NON-NLS-1$ + IToolChain toolChain = createToolChain(config); + return new ArduinoBuildConfiguration(config, name, "run", board, toolChain); //$NON-NLS-1$ } - return null; } else { - return new ArduinoBuildConfiguration(config, name); - } - } + IRemoteServicesManager remoteManager = Activator.getService(IRemoteServicesManager.class); + IRemoteConnectionType connectionType = remoteManager.getConnectionType(ArduinoRemoteConnection.TYPE_ID); + IRemoteConnection connection = connectionType.getConnection(name); + if (connection == null) { + throw Activator.coreException(String.format("Unknown connection: %s", name), null); + } - public ArduinoBuildConfiguration getConfiguration(IProject project, ArduinoRemoteConnection target, - String launchMode, - IProgressMonitor monitor) throws CoreException { - ArduinoBoard board = target.getBoard(); - for (IBuildConfiguration config : project.getBuildConfigs()) { - ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); - if (cconfig != null) { - ArduinoBuildConfiguration arduinoConfig = cconfig.getAdapter(ArduinoBuildConfiguration.class); - if (arduinoConfig != null && arduinoConfig.getLaunchMode().equals(launchMode) - && arduinoConfig.getBoard().equals(board) && arduinoConfig.matches(target)) { - return arduinoConfig; - } + ArduinoRemoteConnection target = connection.getService(ArduinoRemoteConnection.class); + if (target != null) { + IToolChain toolChain = createToolChain(config); + return new ArduinoBuildConfiguration(config, name, "run", target, toolChain); //$NON-NLS-1$ } } return null; } - public ArduinoBuildConfiguration createConfiguration(IProject project, ArduinoRemoteConnection target, - String launchMode, - IProgressMonitor monitor) throws CoreException { - ArduinoBoard board = target.getBoard(); - String configName = ArduinoBuildConfiguration.generateName(board, launchMode); - IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, - monitor); - IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); - IToolChainProvider provider = toolChainManager.getProvider(ArduinoToolChainProvider.ID); - IToolChain toolChain = new ArduinoToolChain(provider, config); - toolChainManager.addToolChain(toolChain); - ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, target, launchMode, + public ArduinoBuildConfiguration getConfiguration(IProject project, ArduinoRemoteConnection target, + String launchMode, IProgressMonitor monitor) throws CoreException { + for (IBuildConfiguration config : project.getBuildConfigs()) { + ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); + if (cconfig != null) { + ArduinoBuildConfiguration arduinoConfig = cconfig.getAdapter(ArduinoBuildConfiguration.class); + if (arduinoConfig != null && target.equals(arduinoConfig.getTarget()) + && arduinoConfig.getLaunchMode().equals(launchMode)) { + return arduinoConfig; + } + } + } + + // Make a new one + String configName = target.getRemoteConnection().getName(); + IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, monitor); + IToolChain toolChain = createToolChain(config); + ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, "run", target, //$NON-NLS-1$ toolChain); configManager.addBuildConfiguration(config, arduinoConfig); return arduinoConfig; } + private IToolChain createToolChain(IBuildConfiguration config) throws CoreException { + IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); + IToolChainProvider provider = toolChainManager.getProvider(ArduinoToolChainProvider.ID); + IToolChain toolChain = new ArduinoToolChain(provider, config); + toolChainManager.addToolChain(toolChain); + return toolChain; + } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java index 6ec1d0c9385..0dd456e7076 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java @@ -115,10 +115,6 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge IProgressMonitor monitor) throws CoreException { ArduinoBuildConfigurationProvider provider = (ArduinoBuildConfigurationProvider) buildConfigManager .getProvider(ArduinoBuildConfigurationProvider.ID); - ArduinoBuildConfiguration config = provider.getConfiguration(project, arduinoTarget, launchMode, monitor); - if (config == null) { - config = provider.createConfiguration(project, arduinoTarget, launchMode, monitor); - } - return config; + return provider.getConfiguration(project, arduinoTarget, launchMode, monitor); } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationProvider.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationProvider.java index 9858f1ba956..8e70e209910 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationProvider.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationProvider.java @@ -23,9 +23,11 @@ public class ArduinoLaunchConfigurationProvider extends ProjectLaunchConfigProvi @Override public boolean supports(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException { - IRemoteConnection connection = target.getAdapter(IRemoteConnection.class); - if (connection != null) { - return connection.getConnectionType().getId().equals(ArduinoRemoteConnection.TYPE_ID); + if (target != null) { + IRemoteConnection connection = target.getAdapter(IRemoteConnection.class); + if (connection != null) { + return connection.getConnectionType().getId().equals(ArduinoRemoteConnection.TYPE_ID); + } } return false; } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/remote/ArduinoRemoteConnection.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/remote/ArduinoRemoteConnection.java index 30d3ca89230..24bf42c9a33 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/remote/ArduinoRemoteConnection.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/remote/ArduinoRemoteConnection.java @@ -40,10 +40,12 @@ public class ArduinoRemoteConnection private static final String PLATFORM_NAME = "arduinoPlatformName"; //$NON-NLS-1$ private static final String BOARD_NAME = "arduinoBoardName"; //$NON-NLS-1$ private static final String MENU_QUALIFIER = "menu_"; //$NON-NLS-1$ + private static final String PROGRAMMER = "programmer"; //$NON-NLS-1$ private final IRemoteConnection remoteConnection; private SerialPort serialPort; private SerialPortCommandShell commandShell; + private ArduinoBoard board; private static final Map connectionMap = new HashMap<>(); @@ -61,19 +63,27 @@ public class ArduinoRemoteConnection ArduinoPackage pkg = platform.getPackage(); workingCopy.setAttribute(PACKAGE_NAME, pkg.getName()); } - + public static void setPortName(IRemoteConnectionWorkingCopy workingCopy, String portName) { workingCopy.setAttribute(PORT_NAME, portName); } - + public static void setMenuValue(IRemoteConnectionWorkingCopy workingCopy, String key, String value) { workingCopy.setAttribute(MENU_QUALIFIER + key, value); } - + + public static void setProgrammer(IRemoteConnectionWorkingCopy workingCopy, String programmer) { + workingCopy.setAttribute(PROGRAMMER, programmer); + } + public String getMenuValue(String key) { return remoteConnection.getAttribute(MENU_QUALIFIER + key); } + public String getProgrammer() { + return remoteConnection.getAttribute(PROGRAMMER); + } + @Override public void connectionChanged(RemoteConnectionChangeEvent event) { if (event.getType() == RemoteConnectionChangeEvent.CONNECTION_REMOVED) { @@ -122,8 +132,33 @@ public class ArduinoRemoteConnection } public ArduinoBoard getBoard() throws CoreException { - return Activator.getService(ArduinoManager.class).getBoard(remoteConnection.getAttribute(PACKAGE_NAME), - remoteConnection.getAttribute(PLATFORM_NAME), remoteConnection.getAttribute(BOARD_NAME)); + if (board == null) { + String pkgName = remoteConnection.getAttribute(PACKAGE_NAME); + String platName = remoteConnection.getAttribute(PLATFORM_NAME); + String boardName = remoteConnection.getAttribute(BOARD_NAME); + ArduinoManager manager = Activator.getService(ArduinoManager.class); + board = manager.getBoard(pkgName, platName, boardName); + + if (board == null) { + // Old style board attributes? + ArduinoPackage pkg = manager.getPackage(pkgName); + if (pkg != null) { + for (ArduinoPlatform plat : pkg.getAvailablePlatforms()) { + if (plat.getName().equals(platName)) { + platName = plat.getArchitecture(); + for (ArduinoBoard b : plat.getBoards()) { + if (b.getName().equals(boardName)) { + board = b; + return board; + } + } + } + } + } + } + } + + return board; } public String getPortName() { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/Makefile b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/Makefile index 8efa79cf7bd..fc81e8086e7 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/Makefile +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/Makefile @@ -1,9 +1,11 @@ ifeq ($(OS),Windows_NT) SHELL = $(ComSpec) RMDIR = rmdir /s /q +RM = del /q mymkdir = if not exist "$1" mkdir "$1" else RMDIR = rm -fr +RM = rm -f mymkdir = mkdir -p $1 endif @@ -11,7 +13,7 @@ PROJECT_OBJS = \ <#list project_srcs as file> <#assign cpp = file?matches("(.*)\\.cpp")> <#if cpp> - ${build_path}/project/${cpp?groups[1]}.cpp.o \ + project/${cpp?groups[1]}.cpp.o \ @@ -19,15 +21,15 @@ PLATFORM_CORE_OBJS = \ <#list platform_core_srcs as file> <#assign cpp = file?matches("${platform_core_path}/(.*)\\.cpp")> <#if cpp> - ${build_path}/core/${cpp?groups[1]}.cpp.o \ + core/${cpp?groups[1]}.cpp.o \ <#assign c = file?matches("${platform_core_path}/(.*)\\.c")> <#if c> - ${build_path}/core/${c?groups[1]}.c.o \ + core/${c?groups[1]}.c.o \ <#assign S = file?matches("${platform_core_path}/(.*)\\.S")> <#if S> - ${build_path}/core/${S?groups[1]}.S.o \ + core/${S?groups[1]}.S.o \ @@ -35,15 +37,15 @@ PLATFORM_VARIANT_OBJS = \ <#list platform_variant_srcs as file> <#assign cpp = file?matches("${platform_variant_path}/(.*)\\.cpp")> <#if cpp> - ${build_path}/variant/${cpp?groups[1]}.cpp.o \ + variant/${cpp?groups[1]}.cpp.o \ <#assign c = file?matches("${platform_variant_path}/(.*)\\.c")> <#if c> - ${build_path}/variant/${c?groups[1]}.c.o \ + variant/${c?groups[1]}.c.o \ <#assign S = file?matches("${platform_variant_path}/(.*)\\.S")> <#if S> - ${build_path}/variant/${S?groups[1]}.S.o \ + variant/${S?groups[1]}.S.o \ @@ -51,62 +53,63 @@ LIBRARIES_OBJS = \ <#list libraries_srcs as file> <#assign cpp = file?matches("${libraries_path}/(.*?)/(.*)\\.cpp")> <#if !cpp> -<#assign cpp = file?matches("${platform_core_path}/libraries/(.*?)/(.*)\\.cpp")> +<#assign cpp = file?matches("${platform_path}/libraries/(.*?)/(.*)\\.cpp")> <#if cpp> - ${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.o \ + libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.o \ <#assign c = file?matches("${libraries_path}/(.*?)/(.*)\\.c")> <#if !c> -<#assign c = file?matches("${platform_core_path}/libraries/(.*?)/(.*)\\.c")> +<#assign c = file?matches("${platform_path}/libraries/(.*?)/(.*)\\.c")> <#if c> - ${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.c.o \ + libraries/${c?groups[1]}/${c?groups[2]}.c.o \ <#assign S = file?matches("${libraries_path}/(.*?)/(.*)\\.S")> <#if !S> -<#assign S = file?matches("${platform_core_path}/libraries/(.*?)/(.*)\\.S")> +<#assign S = file?matches("${platform_path}/libraries/(.*?)/(.*)\\.S")> <#if S> - ${build_path}/libraries/${S?groups[1]}/${S?groups[2]}.S.o \ + libraries/${S?groups[1]}/${S?groups[2]}.S.o \ TARGETS = \ <#if recipe_objcopy_hex_pattern??> - ${build_path}/${project_name}.hex \ + ${project_name}.hex \ <#if recipe_objcopy_epp_pattern??> - ${build_path}/${project_name}.eep \ + ${project_name}.eep \ <#if recipe_objcopy_bin_pattern??> - ${build_path}/${project_name}.bin \ + ${project_name}.bin \ all: $(TARGETS) <#if recipe_objcopy_hex_pattern??> -${build_path}/${project_name}.hex: ${build_path}/${project_name}.elf +${project_name}.hex: ${project_name}.elf ${recipe_objcopy_hex_pattern} <#if recipe_objcopy_epp_pattern??> -${build_path}/${project_name}.eep: ${build_path}/${project_name}.elf +${project_name}.eep: ${project_name}.elf ${recipe_objcopy_eep_pattern} <#if recipe_objcopy_bin_pattern??> -${build_path}/${project_name}.bin: ${build_path}/${project_name}.elf +${project_name}.bin: ${project_name}.elf ${recipe_objcopy_bin_pattern} -${build_path}/${project_name}.elf: $(PROJECT_OBJS) $(LIBRARIES_OBJS) ${build_path}/core.a +${project_name}.elf: $(PROJECT_OBJS) $(LIBRARIES_OBJS) core.a ${recipe_c_combine_pattern} -${build_path}/core.a: $(PLATFORM_CORE_OBJS) $(PLATFORM_VARIANT_OBJS) +core.a: $(PLATFORM_CORE_OBJS) $(PLATFORM_VARIANT_OBJS) clean: - $(RMDIR) ${build_path}/* + -$(RMDIR) project core variant libraries + -$(RM) *.hex *.eep *.bin *.elf *.a *.ar *.d size: ${recipe_size_pattern} @@ -114,13 +117,13 @@ size: <#list project_srcs as file> <#assign cpp = file?matches("(.*)\\.cpp")> <#if cpp> -${build_path}/project/${cpp?groups[1]}.cpp.o: ../../${file} ${build_path}/project/${cpp?groups[1]}.cpp.d +project/${cpp?groups[1]}.cpp.o: ../../${file} project/${cpp?groups[1]}.cpp.d @$(call mymkdir,$(dir $@)) ${recipe_cpp_o_pattern} -${build_path}/project/${cpp?groups[1]}.cpp.d: ; +project/${cpp?groups[1]}.cpp.d: ; --include ${build_path}/project/${cpp?groups[1]}.cpp.d +-include project/${cpp?groups[1]}.cpp.d @@ -128,33 +131,33 @@ ${build_path}/project/${cpp?groups[1]}.cpp.d: ; <#list platform_core_srcs as file> <#assign cpp = file?matches("${platform_core_path}/(.*)\\.cpp")> <#if cpp> -${build_path}/core/${cpp?groups[1]}.cpp.o: ${file} ${build_path}/core/${cpp?groups[1]}.cpp.d +core/${cpp?groups[1]}.cpp.o: ${file} core/${cpp?groups[1]}.cpp.d @$(call mymkdir,$(dir $@)) - ${recipe_cpp_o_pattern} + ${recipe_cpp_o_pattern_plat} ${recipe_ar_pattern} -${build_path}/core/${cpp?groups[1]}.cpp.d: ; +core/${cpp?groups[1]}.cpp.d: ; --include ${build_path}/core/${cpp?groups[1]}.cpp.d +-include core/${cpp?groups[1]}.cpp.d <#assign c = file?matches("${platform_core_path}/(.*)\\.c")> <#if c> -${build_path}/core/${c?groups[1]}.c.o: ${file} ${build_path}/core/${c?groups[1]}.c.d +core/${c?groups[1]}.c.o: ${file} core/${c?groups[1]}.c.d @$(call mymkdir,$(dir $@)) - ${recipe_c_o_pattern} + ${recipe_c_o_pattern_plat} ${recipe_ar_pattern} -${build_path}/core/${c?groups[1]}.c.d: ; +core/${c?groups[1]}.c.d: ; --include ${build_path}/core/${c?groups[1]}.c.d +-include core/${c?groups[1]}.c.d <#assign S = file?matches("${platform_core_path}/(.*)\\.S")> <#if S> -${build_path}/core/${S?groups[1]}.S.o: ${file} +core/${S?groups[1]}.S.o: ${file} @$(call mymkdir,$(dir $@)) - ${recipe_S_o_pattern} + ${recipe_S_o_pattern_plat} ${recipe_ar_pattern} @@ -163,33 +166,33 @@ ${build_path}/core/${S?groups[1]}.S.o: ${file} <#list platform_variant_srcs as file> <#assign cpp = file?matches("${platform_variant_path}/(.*)\\.cpp")> <#if cpp> -${build_path}/variant/${cpp?groups[1]}.cpp.o: ${file} ${build_path}/variant/${cpp?groups[1]}.cpp.d +variant/${cpp?groups[1]}.cpp.o: ${file} variant/${cpp?groups[1]}.cpp.d @$(call mymkdir,$(dir $@)) - ${recipe_cpp_o_pattern} + ${recipe_cpp_o_pattern_plat} ${recipe_ar_pattern} -${build_path}/variant/${cpp?groups[1]}.cpp.d: ; +variant/${cpp?groups[1]}.cpp.d: ; --include ${build_path}/variant/${cpp?groups[1]}.cpp.d +-include variant/${cpp?groups[1]}.cpp.d <#assign c = file?matches("${platform_variant_path}/(.*)\\.c")> <#if c> -${build_path}/variant/${c?groups[1]}.c.o: ${file} ${build_path}/variant/${c?groups[1]}.c.d +variant/${c?groups[1]}.c.o: ${file} variant/${c?groups[1]}.c.d @$(call mymkdir,$(dir $@)) - ${recipe_c_o_pattern} + ${recipe_c_o_pattern_plat} ${recipe_ar_pattern} -${build_path}/variant/${c?groups[1]}.c.d: ; +variant/${c?groups[1]}.c.d: ; --include ${build_path}/variant/${c?groups[1]}.c.d +-include variant/${c?groups[1]}.c.d <#assign S = file?matches("${platform_variant_path}/(.*)\\.S")> <#if S> -${build_path}/variant/${S?groups[1]}.S.o: ${file} +variant/${S?groups[1]}.S.o: ${file} @$(call mymkdir,$(dir $@)) - ${recipe_S_o_pattern} + ${recipe_S_o_pattern_plat} ${recipe_ar_pattern} @@ -198,38 +201,38 @@ ${build_path}/variant/${S?groups[1]}.S.o: ${file} <#list libraries_srcs as file> <#assign cpp = file?matches("${libraries_path}/(.*?)/(.*)\\.cpp")> <#if !cpp> -<#assign cpp = file?matches("${platform_core_path}/libraries/(.*?)/(.*)\\.cpp")> +<#assign cpp = file?matches("${platform_path}/libraries/(.*?)/(.*)\\.cpp")> <#if cpp> -${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.o: ${file} ${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.d +libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.o: ${file} libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.d @$(call mymkdir,$(dir $@)) ${recipe_cpp_o_pattern} -${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.d: ; +libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.d: ; --include ${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.d +-include libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.d <#assign c = file?matches("${libraries_path}/(.*?)/(.*)\\.c")> <#if !c> -<#assign c = file?matches("${platform_core_path}/libraries/(.*?)/(.*)\\.c")> +<#assign c = file?matches("${platform_path}/libraries/(.*?)/(.*)\\.c")> <#if c> -${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.c.o: ${file} ${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.c.d +libraries/${c?groups[1]}/${c?groups[2]}.c.o: ${file} libraries/${c?groups[1]}/${c?groups[2]}.c.d @$(call mymkdir,$(dir $@)) ${recipe_c_o_pattern} -${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.c.d: ; +libraries/${c?groups[1]}/${c?groups[2]}.c.d: ; --include ${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.c.d +-include libraries/${c?groups[1]}/${c?groups[2]}.c.d <#assign S = file?matches("${libraries_path}/(.*?)/(.*)\\.S")> <#if !S> -<#assign S = file?matches("${platform_core_path}/libraries/(.*?)/(.*)\\.S")> +<#assign S = file?matches("${platform_path}/libraries/(.*?)/(.*)\\.S")> <#if S> -${build_path}/libraries/${S?groups[1]}/${S?groups[2]}.S.o: ${file} +libraries/${S?groups[1]}/${S?groups[2]}.S.o: ${file} @$(call mymkdir,$(dir $@)) ${recipe_S_o_pattern} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/cppsketch/manifest.xml b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/cppsketch/manifest.xml index 148f5c807ca..2b8b3f07fca 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/cppsketch/manifest.xml +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/cppsketch/manifest.xml @@ -1,4 +1,5 @@ - \ No newline at end of file diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/ArduinoDownloadsManager.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/ArduinoDownloadsManager.java index 1c47fc9d11f..c1bb94e8249 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/ArduinoDownloadsManager.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/ArduinoDownloadsManager.java @@ -7,8 +7,13 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.ui.internal.downloads; +import java.io.File; +import java.io.IOException; + +import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.cdt.arduino.ui.internal.Activator; import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.wizard.Wizard; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.jface.wizard.WizardPage; @@ -19,7 +24,9 @@ import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Shell; public class ArduinoDownloadsManager extends WizardDialog { @@ -84,7 +91,32 @@ public class ArduinoDownloadsManager extends WizardDialog { protected void createButtonsForButtonBar(Composite parent) { super.createButtonsForButtonBar(parent); getButton(IDialogConstants.CANCEL_ID).setVisible(false); - getButton(IDialogConstants.FINISH_ID).setText("OK"); + Button finishButton = getButton(IDialogConstants.FINISH_ID); + finishButton.setText("Done"); + // make sure it's far right + finishButton.moveBelow(null); + } + + static boolean checkLicense(Shell shell) { + File acceptedFile = ArduinoPreferences.getArduinoHome().resolve(".accepted").toFile(); //$NON-NLS-1$ + if (!acceptedFile.exists()) { + String message = "Do you accept the licenses for the platforms and libraries you are downloading?"; + MessageDialog dialog = new MessageDialog(shell, "Arduino Licensing", null, message, + MessageDialog.QUESTION, new String[] { "Yes", "No" }, 0); + int rc = dialog.open(); + if (rc == 0) { + try { + acceptedFile.createNewFile(); + } catch (IOException e) { + Activator.log(e); + } + return true; + } else { + return false; + } + } else { + return true; + } } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/LibrariesTabControl.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/LibrariesTabControl.java index 401a79b4ccb..8a39fb26534 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/LibrariesTabControl.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/LibrariesTabControl.java @@ -199,7 +199,7 @@ public class LibrariesTabControl extends Composite { try { container.run(true, true, monitor -> { try { - for (ArduinoLibrary available : manager.getAvailableLibraries(monitor)) { + for (ArduinoLibrary available : manager.getLibraryUpdates(monitor)) { ArduinoLibrary installed = manager.getInstalledLibrary(available.getName()); if (installed != null) { if (ArduinoManager.compareVersions(available.getVersion(), installed.getVersion()) > 0) { @@ -263,14 +263,16 @@ public class LibrariesTabControl extends Composite { SelectLibrariesDialog selectDialog = new SelectLibrariesDialog(getShell()); selectDialog.setLibraries(availableLibraries); if (selectDialog.open() == Window.OK) { - Collection selectedLibraries = selectDialog.getChecked(); - container.run(true, true, monitor -> { - try { - manager.installLibraries(selectedLibraries, monitor); - } catch (CoreException e) { - Activator.log(e); - } - }); + if (ArduinoDownloadsManager.checkLicense(getShell())) { + Collection selectedLibraries = selectDialog.getChecked(); + container.run(true, true, monitor -> { + try { + manager.installLibraries(selectedLibraries, monitor); + } catch (CoreException e) { + Activator.log(e); + } + }); + } } populateTable(); } catch (InterruptedException | InvocationTargetException e) { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/PlatformsTabControl.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/PlatformsTabControl.java index 2861a7d7fad..2a35036066f 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/PlatformsTabControl.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/downloads/PlatformsTabControl.java @@ -197,7 +197,7 @@ public class PlatformsTabControl extends Composite { try { container.run(true, true, monitor -> { try { - for (ArduinoPlatform available : manager.getAvailablePlatforms(monitor)) { + for (ArduinoPlatform available : manager.getPlatformUpdates(monitor)) { ArduinoPlatform installed = manager.getInstalledPlatform(available.getPackage().getName(), available.getArchitecture()); if (installed != null) { @@ -257,14 +257,16 @@ public class PlatformsTabControl extends Composite { SelectPlatformsDialog selectDialog = new SelectPlatformsDialog(getShell()); selectDialog.setPlatforms(availablePlatforms); if (selectDialog.open() == Window.OK) { - Collection selectedPlatforms = selectDialog.getSelectedPlatforms(); - container.run(true, true, monitor -> { - try { - manager.installPlatforms(selectedPlatforms, monitor); - } catch (CoreException e) { - Activator.log(e); - } - }); + if (ArduinoDownloadsManager.checkLicense(getShell())) { + Collection selectedPlatforms = selectDialog.getSelectedPlatforms(); + container.run(true, true, monitor -> { + try { + manager.installPlatforms(selectedPlatforms, monitor); + } catch (CoreException e) { + Activator.log(e); + } + }); + } } populateTable(); } catch (InterruptedException | InvocationTargetException e) { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPreferencePage.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPreferencePage.java index 55414d233e9..07d896e0aea 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPreferencePage.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoPreferencePage.java @@ -10,14 +10,21 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.ui.internal.preferences; +import java.nio.file.Paths; + import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.cdt.arduino.ui.internal.Messages; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; @@ -25,6 +32,7 @@ import org.eclipse.ui.IWorkbenchPreferencePage; public class ArduinoPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { private Text urlsText; + private Text homeText; @Override public void init(IWorkbench workbench) { @@ -35,6 +43,33 @@ public class ArduinoPreferencePage extends PreferencePage implements IWorkbenchP Composite control = new Composite(parent, SWT.NONE); control.setLayout(new GridLayout()); + Composite homeComp = new Composite(control, SWT.NONE); + homeComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + homeComp.setLayout(new GridLayout(3, false)); + + Label label = new Label(homeComp, SWT.NONE); + label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + label.setText("Arduino home:"); + + homeText = new Text(homeComp, SWT.BORDER); + homeText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + homeText.setText(ArduinoPreferences.getArduinoHome().toString()); + + Button browse = new Button(homeComp, SWT.NONE); + browse.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + browse.setText("Browse..."); + browse.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + DirectoryDialog dialog = new DirectoryDialog(getShell()); + dialog.setMessage("Select directory for the Arduino SDKs and toolchains."); + String dir = dialog.open(); + if (dir != null) { + homeText.setText(dir); + } + } + }); + Text desc = new Text(control, SWT.READ_ONLY | SWT.WRAP); GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false); layoutData.widthHint = 500; @@ -52,14 +87,20 @@ public class ArduinoPreferencePage extends PreferencePage implements IWorkbenchP @Override public boolean performOk() { ArduinoPreferences.setBoardUrls(urlsText.getText()); + ArduinoPreferences.setArduinoHome(Paths.get(homeText.getText())); return true; } @Override protected void performDefaults() { + String defaultHome = ArduinoPreferences.getDefaultArduinoHome(); + homeText.setText(defaultHome); + ArduinoPreferences.setArduinoHome(Paths.get(defaultHome)); + String defaultBoardUrl = ArduinoPreferences.getDefaultBoardUrls(); urlsText.setText(defaultBoardUrl); ArduinoPreferences.setBoardUrls(defaultBoardUrl); + super.performDefaults(); } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoProjectWizard.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoProjectWizard.java index 7280d958f74..1efdf44d375 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoProjectWizard.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoProjectWizard.java @@ -7,29 +7,14 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.ui.internal.project; -import org.eclipse.tools.templates.ui.TemplateSelectionPage; -import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard; +import org.eclipse.tools.templates.ui.NewWizard; -public class NewArduinoProjectWizard extends BasicNewProjectResourceWizard { +public class NewArduinoProjectWizard extends NewWizard { private static final String ARDUINO_TAG_ID = "org.eclipse.cdt.arduino.ui.tag"; //$NON-NLS-1$ - private TemplateSelectionPage templateSelectionPage; - public NewArduinoProjectWizard() { - setForcePreviousAndNextButtons(true); - } - - @Override - public void addPages() { - templateSelectionPage = new TemplateSelectionPage("templateSelection", ARDUINO_TAG_ID); //$NON-NLS-1$ - templateSelectionPage.setTitle("Template for New Arduino Project"); - this.addPage(templateSelectionPage); - } - - @Override - public boolean performFinish() { - return true; + super(ARDUINO_TAG_ID); } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/BoardPropertyControl.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/BoardPropertyControl.java index 38362faf463..570c990af9e 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/BoardPropertyControl.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/BoardPropertyControl.java @@ -17,8 +17,6 @@ import java.util.Map.Entry; import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform; import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection; import org.eclipse.cdt.arduino.ui.internal.Activator; import org.eclipse.cdt.arduino.ui.internal.Messages; @@ -49,6 +47,9 @@ public class BoardPropertyControl extends Composite { private List listeners = Collections.synchronizedList(new ArrayList()); private List menuControls = new ArrayList<>(); + + private Label programmerLabel; + private Combo programmerCombo; public BoardPropertyControl(Composite parent, int style) { super(parent, style); @@ -158,6 +159,28 @@ public class BoardPropertyControl extends Composite { combo.select(0); } } + + try { + HierarchicalProperties programmers = board.getPlatform().getProgrammers(); + if (programmers != null && programmers.getChildren() != null) { + programmerLabel = new Label(this, SWT.NONE); + programmerLabel.setText("Programmer:"); + + programmerCombo = new Combo(this, SWT.READ_ONLY); + programmerCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + List ids = new ArrayList<>(); + for (Entry programmer : programmers.getChildren().entrySet()) { + ids.add(programmer.getKey()); + String name = programmer.getValue().getChild("name").getValue(); //$NON-NLS-1$ + programmerCombo.add(name); + } + programmerCombo.setData(ids); + programmerCombo.select(0); + } + } catch (CoreException e) { + Activator.log(e); + } } private void boardChanged() { @@ -169,6 +192,10 @@ public class BoardPropertyControl extends Composite { control.dispose(); } menuControls.clear(); + if (programmerLabel != null) { + programmerLabel.dispose(); + programmerCombo.dispose(); + } board = newBoard; updateBoardMenu(); @@ -205,6 +232,12 @@ public class BoardPropertyControl extends Composite { } } } + + if (programmerCombo != null && !programmerCombo.isDisposed()) { + @SuppressWarnings("unchecked") + String programmer = ((List) programmerCombo.getData()).get(programmerCombo.getSelectionIndex()); + ArduinoRemoteConnection.setProgrammer(workingCopy, programmer); + } } }