diff options
17 files changed, 659 insertions, 40 deletions
diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/BoardManagerTests.java b/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/BoardManagerTests.java index 862f9adfa17..86416879f7b 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/BoardManagerTests.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core.tests/src/org/eclipse/cdt/arduino/core/tests/BoardManagerTests.java @@ -2,14 +2,14 @@ package org.eclipse.cdt.arduino.core.tests; import static org.junit.Assert.assertNotNull; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; import org.junit.Test; public class BoardManagerTests { @Test public void loadPackagesTest() throws Exception { - assertNotNull(ArduinoBoardManager.instance.getPackageIndex()); + assertNotNull(ArduinoManager.instance.getPackageIndex()); } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoProjectGenerator.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoProjectGenerator.java index c74b7a2d75d..ccf734665c8 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoProjectGenerator.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoProjectGenerator.java @@ -14,7 +14,7 @@ import java.util.HashMap; import java.util.Map; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration; import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder; import org.eclipse.cdt.core.CCProjectNature; @@ -64,7 +64,7 @@ public class ArduinoProjectGenerator { IBuildConfiguration config = project.getBuildConfig("uno"); //$NON-NLS-1$ ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class); - ArduinoBoard board = ArduinoBoardManager.instance.getBoard("Arduino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + ArduinoBoard board = ArduinoManager.instance.getBoard("Arduino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ arduinoConfig.setBoard(board); // Generate files 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 new file mode 100644 index 00000000000..31ea5052ee3 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoLibrary.java @@ -0,0 +1,204 @@ +package org.eclipse.cdt.arduino.core.internal.board; + +import java.io.File; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +public class ArduinoLibrary { + + private String name; + private String version; + private String author; + private String maintainer; + private String sentence; + private String paragraph; + private String website; + private String category; + private List<String> architectures; + private List<String> types; + private String url; + private String archiveFileName; + private int size; + private String checksum; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getMaintainer() { + return maintainer; + } + + public void setMaintainer(String maintainer) { + this.maintainer = maintainer; + } + + public String getSentence() { + return sentence; + } + + public void setSentence(String sentence) { + this.sentence = sentence; + } + + public String getParagraph() { + return paragraph; + } + + public void setParagraph(String paragraph) { + this.paragraph = paragraph; + } + + public String getWebsite() { + return website; + } + + public void setWebsite(String website) { + this.website = website; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public List<String> getArchitectures() { + return architectures; + } + + public void setArchitectures(List<String> architectures) { + this.architectures = architectures; + } + + public List<String> getTypes() { + return types; + } + + public void setTypes(List<String> types) { + this.types = types; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getArchiveFileName() { + return archiveFileName; + } + + public void setArchiveFileName(String archiveFileName) { + this.archiveFileName = archiveFileName; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public String getChecksum() { + return checksum; + } + + public void setChecksum(String checksum) { + this.checksum = checksum; + } + + public Path getInstallPath() { + return ArduinoPreferences.getArduinoHome().resolve("libraries").resolve(name.replace(' ', '_')) //$NON-NLS-1$ + .resolve(version); + } + + public boolean isInstalled() { + return getInstallPath().toFile().exists(); + } + + public IStatus install(IProgressMonitor monitor) { + if (isInstalled()) { + return Status.OK_STATUS; + } + + return ArduinoManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor); + } + + public Collection<Path> getIncludePath() { + Path installPath = getInstallPath(); + Path srcPath = installPath.resolve("src"); //$NON-NLS-1$ + if (srcPath.toFile().isDirectory()) { + return Collections.singletonList(srcPath); + } else { + // TODO do I need the 'utility' directory? + return Collections.singletonList(installPath); + } + } + + private void getSources(IProject project, Collection<Path> sources, Path dir, boolean recurse) { + for (File file : dir.toFile().listFiles()) { + if (file.isDirectory()) { + if (recurse) { + getSources(project, sources, file.toPath(), recurse); + } + } else { + if (CoreModel.isValidSourceUnitName(project, file.getName())) { + sources.add(file.toPath()); + } + } + } + } + + public Collection<Path> getSources(IProject project) { + List<Path> sources = new ArrayList<>(); + Path installPath = getInstallPath(); + Path srcPath = installPath.resolve("src"); //$NON-NLS-1$ + if (srcPath.toFile().isDirectory()) { + getSources(project, sources, srcPath, true); + } else { + getSources(project, sources, installPath, false); + Path utilityPath = installPath.resolve("utility"); //$NON-NLS-1$ + if (utilityPath.toFile().isDirectory()) { + getSources(project, sources, utilityPath, false); + } + } + return sources; + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoardManager.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java index f5f9bb3ed9c..d712bc4d463 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoardManager.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java @@ -16,12 +16,14 @@ import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Type; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -36,19 +38,26 @@ import org.apache.commons.compress.compressors.CompressorStreamFactory; import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.cdt.arduino.core.internal.Messages; +import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration; +import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.osgi.service.prefs.BackingStoreException; import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; -// Closeable isn't API yet but it's recommended. -public class ArduinoBoardManager { +public class ArduinoManager { - public static final ArduinoBoardManager instance = new ArduinoBoardManager(); + public static final ArduinoManager instance = new ArduinoManager(); // Build tool ids public static final String BOARD_OPTION_ID = "org.eclipse.cdt.arduino.option.board"; //$NON-NLS-1$ @@ -59,13 +68,25 @@ public class ArduinoBoardManager { private Path packageIndexPath = ArduinoPreferences.getArduinoHome().resolve("package_index.json"); //$NON-NLS-1$ private PackageIndex packageIndex; - public ArduinoBoardManager() { + private Path libraryIndexPath = ArduinoPreferences.getArduinoHome().resolve("library_index.json"); //$NON-NLS-1$ + private LibraryIndex libraryIndex; + + public ArduinoManager() { new Job(Messages.ArduinoBoardManager_0) { protected IStatus run(IProgressMonitor monitor) { try { - URL url = new URL("http://downloads.arduino.cc/packages/package_index.json"); //$NON-NLS-1$ + // library index has the same parent right now Files.createDirectories(packageIndexPath.getParent()); - Files.copy(url.openStream(), packageIndexPath, StandardCopyOption.REPLACE_EXISTING); + + URL packageUrl = new URL("http://downloads.arduino.cc/packages/package_index.json"); //$NON-NLS-1$ + try (InputStream in = packageUrl.openStream()) { + Files.copy(in, packageIndexPath, StandardCopyOption.REPLACE_EXISTING); + } + + URL libraryUrl = new URL("http://downloads.arduino.cc/libraries/library_index.json"); //$NON-NLS-1$ + try (InputStream in = libraryUrl.openStream()) { + Files.copy(in, libraryIndexPath, StandardCopyOption.REPLACE_EXISTING); + } } catch (IOException e) { return new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e); } @@ -86,6 +107,18 @@ public class ArduinoBoardManager { return packageIndex; } + public LibraryIndex getLibraryIndex() throws CoreException { + if (libraryIndex == null) { + try (FileReader reader = new FileReader(libraryIndexPath.toFile())) { + libraryIndex = new Gson().fromJson(reader, LibraryIndex.class); + libraryIndex.resolve(); + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Reading library index", e)); + } + } + return libraryIndex; + } + public ArduinoBoard getBoard(String boardName, String platformName, String packageName) throws CoreException { return getPackageIndex().getPackage(packageName).getPlatform(platformName).getBoard(boardName); } @@ -115,6 +148,63 @@ public class ArduinoBoardManager { return pkg != null ? pkg.getTool(toolName, version) : null; } + private static final String LIBRARIES = "libraries"; //$NON-NLS-1$ + + private IEclipsePreferences getSettings(IProject project) { + return (IEclipsePreferences) new ProjectScope(project).getNode(Activator.getId()); + } + + public Collection<ArduinoLibrary> getLibraries(IProject project) throws CoreException { + IEclipsePreferences settings = getSettings(project); + String librarySetting = settings.get(LIBRARIES, "[]"); //$NON-NLS-1$ + Type stringSet = new TypeToken<Set<String>>() { + }.getType(); + Set<String> libraryNames = new Gson().fromJson(librarySetting, stringSet); + LibraryIndex index = ArduinoManager.instance.getLibraryIndex(); + List<ArduinoLibrary> libraries = new ArrayList<>(libraryNames.size()); + for (String name : libraryNames) { + libraries.add(index.getLibrary(name)); + } + return libraries; + } + + public void setLibraries(final IProject project, final Collection<ArduinoLibrary> libraries) throws CoreException { + List<String> libraryNames = new ArrayList<>(libraries.size()); + for (ArduinoLibrary library : libraries) { + libraryNames.add(library.getName()); + } + IEclipsePreferences settings = getSettings(project); + settings.put(LIBRARIES, new Gson().toJson(libraryNames)); + try { + settings.flush(); + } catch (BackingStoreException e) { + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e)); + } + + new Job("Install libraries") { + protected IStatus run(IProgressMonitor monitor) { + MultiStatus mstatus = new MultiStatus(Activator.getId(), 0, "Installing libraries", null); + for (ArduinoLibrary library : libraries) { + IStatus status = library.install(monitor); + if (!status.isOK()) { + mstatus.add(status); + } + } + + // Clear the scanner info caches to pick up new includes + try { + for (IBuildConfiguration config : project.getBuildConfigs()) { + ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class); + arduinoConfig.clearScannerInfoCache(); + } + } catch (CoreException e) { + mstatus.add(e.getStatus()); + } + return mstatus; + } + }.schedule(); + } + public static IStatus downloadAndInstall(String url, String archiveFileName, Path installPath, IProgressMonitor monitor) { try { 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 168e6aff76f..39f8329ea98 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 @@ -13,8 +13,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.eclipse.core.runtime.IProgressMonitor; - public class ArduinoPackage { private String name; @@ -25,9 +23,9 @@ public class ArduinoPackage { private List<ArduinoPlatform> platforms; private List<ArduinoTool> tools; - private transient ArduinoBoardManager manager; + private transient ArduinoManager manager; - void setOwner(ArduinoBoardManager manager) { + void setOwner(ArduinoManager manager) { this.manager = manager; for (ArduinoPlatform platform : platforms) { platform.setOwner(this); @@ -37,7 +35,7 @@ public class ArduinoPackage { } } - ArduinoBoardManager getManager() { + ArduinoManager getManager() { return manager; } @@ -94,7 +92,8 @@ public class ArduinoPackage { return Collections.unmodifiableCollection(platformMap.values()); } - private int compareVersions(String version1, String version2) { + // TODO move somewhere. + public static int compareVersions(String version1, String version2) { if (version1 == null) { return version2 == null ? 0 : -1; } @@ -169,10 +168,6 @@ public class ArduinoPackage { return null; } - public void install(IProgressMonitor monitor) { - - } - @Override public boolean equals(Object obj) { if (obj instanceof ArduinoPackage) { 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 9d733f82b05..5d6939112ac 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 @@ -179,7 +179,7 @@ public class ArduinoPlatform { } // Download platform archive - IStatus status = ArduinoBoardManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor); + IStatus status = ArduinoManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor); if (!status.isOK()) { return status; } 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 bb994a4dadf..0a5d9850267 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 @@ -72,7 +72,7 @@ public class ArduinoToolSystem { } public IStatus install(IProgressMonitor monitor) { - return ArduinoBoardManager.downloadAndInstall(url, archiveFileName, tool.getInstallPath(), monitor); + return ArduinoManager.downloadAndInstall(url, archiveFileName, tool.getInstallPath(), monitor); } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/LibraryIndex.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/LibraryIndex.java new file mode 100644 index 00000000000..a0bbef428ca --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/LibraryIndex.java @@ -0,0 +1,69 @@ +package org.eclipse.cdt.arduino.core.internal.board; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class LibraryIndex { + + private List<ArduinoLibrary> libraries; + + // category name to library name + private Map<String, Set<String>> categories = new HashMap<>(); + // library name to latest version of library + private Map<String, ArduinoLibrary> latestLibs = new HashMap<>(); + + public void resolve() { + for (ArduinoLibrary library : libraries) { + String name = library.getName(); + + String category = library.getCategory(); + if (category == null) { + category = "Uncategorized"; //$NON-NLS-1$ + } + + Set<String> categoryLibs = categories.get(category); + if (categoryLibs == null) { + categoryLibs = new HashSet<>(); + categories.put(category, categoryLibs); + } + categoryLibs.add(name); + + ArduinoLibrary current = latestLibs.get(name); + if (current != null) { + if (ArduinoPackage.compareVersions(library.getVersion(), current.getVersion()) > 0) { + latestLibs.put(name, library); + } + } else { + latestLibs.put(name, library); + } + } + } + + public ArduinoLibrary getLibrary(String name) { + return latestLibs.get(name); + } + + public Collection<String> getCategories() { + return Collections.unmodifiableCollection(categories.keySet()); + } + + public Collection<ArduinoLibrary> getLibraries(String category) { + Set<String> categoryLibs = categories.get(category); + if (categoryLibs == null) { + return new ArrayList<>(0); + } + + List<ArduinoLibrary> libs = new ArrayList<>(categoryLibs.size()); + for (String name : categoryLibs) { + libs.add(latestLibs.get(name)); + } + return libs; + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/PackageIndex.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/PackageIndex.java index c03c55c3699..9a1abc96c8b 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/PackageIndex.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/PackageIndex.java @@ -26,7 +26,7 @@ public class PackageIndex { return null; } - void setOwners(ArduinoBoardManager manager) { + void setOwners(ArduinoManager manager) { for (ArduinoPackage pkg : packages) { pkg.setOwner(manager); } 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 69e3eb5aec9..68349ae4b6e 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 @@ -8,6 +8,7 @@ import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -21,7 +22,8 @@ import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.cdt.arduino.core.internal.ArduinoTemplateGenerator; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary; +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.board.ArduinoTool; @@ -170,7 +172,7 @@ public class ArduinoBuildConfiguration { 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$ - board = ArduinoBoardManager.instance.getBoard(boardName, platformName, packageName); + board = ArduinoManager.instance.getBoard(boardName, platformName, packageName); } return board; } @@ -184,7 +186,7 @@ public class ArduinoBuildConfiguration { for (ToolDependency toolDep : platform.getToolsDependencies()) { properties.putAll(toolDep.getTool().getToolProperties()); } - properties.put("runtime.ide.version", "1.6.7"); //$NON-NLS-1$ //$NON-NLS-2$ + properties.put("runtime.ide.version", "10607"); //$NON-NLS-1$ //$NON-NLS-2$ properties.put("build.arch", platform.getArchitecture().toUpperCase()); //$NON-NLS-1$ properties.put("build.path", config.getName()); //$NON-NLS-1$ } @@ -252,6 +254,16 @@ public class ArduinoBuildConfiguration { } buildModel.put("project_srcs", sourceFiles); //$NON-NLS-1$ + // The list of library sources + List<String> librarySources = new ArrayList<>(); + for (ArduinoLibrary lib : ArduinoManager.instance.getLibraries(project)) { + for (Path path : lib.getSources(project)) { + librarySources.add(path.toString()); + } + } + buildModel.put("libraries_srcs", librarySources); //$NON-NLS-1$ + buildModel.put("libraries_path", ArduinoPreferences.getArduinoHome().resolve("libraries")); //$NON-NLS-1$ //$NON-NLS-2$ + // the recipes Properties properties = new Properties(); properties.putAll(getProperties()); @@ -267,6 +279,11 @@ public class ArduinoBuildConfiguration { } includes += '"' + include.toString() + '"'; } + for (ArduinoLibrary lib : ArduinoManager.instance.getLibraries(project)) { + for (Path include : lib.getIncludePath()) { + includes += " -I\"" + include.toString() + '"'; //$NON-NLS-1$ + } + } properties.put("includes", includes); //$NON-NLS-1$ Path platformPath = platform.getInstallPath(); @@ -290,8 +307,8 @@ public class ArduinoBuildConfiguration { properties.put("object_file", "$@"); //$NON-NLS-1$ //$NON-NLS-2$ properties.put("source_file", "$<"); //$NON-NLS-1$ //$NON-NLS-2$ - properties.put("archive_file", "libc.a"); //$NON-NLS-1$ //$NON-NLS-2$ - properties.put("object_files", "$(PROJECT_OBJS)"); //$NON-NLS-1$ //$NON-NLS-2$ + properties.put("archive_file", "core.a"); //$NON-NLS-1$ //$NON-NLS-2$ + properties.put("object_files", "$(PROJECT_OBJS) $(LIBRARIES_OBJS)"); //$NON-NLS-1$ //$NON-NLS-2$ buildModel.put("recipe_cpp_o_pattern", resolveProperty("recipe.cpp.o.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$ buildModel.put("recipe_c_o_pattern", resolveProperty("recipe.c.o.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$ @@ -442,6 +459,11 @@ public class ArduinoBuildConfiguration { } } + public void clearScannerInfoCache() { + cppScannerInfo = null; + cScannerInfo = null; + } + private IScannerInfo calculateScannerInfo(String recipe, IResource resource) throws CoreException { try { ArduinoPlatform platform = getBoard().getPlatform(); @@ -456,6 +478,12 @@ public class ArduinoBuildConfiguration { for (Path include : platform.getIncludePath()) { includes += " -I\"" + include.toString() + '"'; //$NON-NLS-1$ } + Collection<ArduinoLibrary> libs = ArduinoManager.instance.getLibraries(config.getProject()); + for (ArduinoLibrary lib : libs) { + for (Path path : lib.getIncludePath()) { + includes += " -I\"" + path.toString() + '"'; //$NON-NLS-1$ + } + } properties.put("includes", includes); //$NON-NLS-1$ // TODO Windows @@ -499,7 +527,7 @@ public class ArduinoBuildConfiguration { public ArduinoConsoleParser[] getBuildConsoleParsers() { // ../src/Test.cpp:4:1: error: 'x' was not declared in this scope - return new ArduinoConsoleParser[] { new ArduinoErrorParser("(.*?):(\\d+):(\\d+:)? error: (.*)") { //$NON-NLS-1$ + return new ArduinoConsoleParser[] { new ArduinoErrorParser("(.*?):(\\d+):(\\d+:)? (fatal )?error: (.*)") { //$NON-NLS-1$ @Override protected int getSeverity(Matcher matcher) { return IMarker.SEVERITY_ERROR; @@ -507,7 +535,7 @@ public class ArduinoBuildConfiguration { @Override protected String getMessage(Matcher matcher) { - return matcher.group(4); + return matcher.group(5); } @Override 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 088b35996de..2106c0f9f79 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 @@ -16,7 +16,7 @@ import java.util.Map; import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; import org.eclipse.cdt.serial.SerialPort; import org.eclipse.core.runtime.CoreException; import org.eclipse.remote.core.IRemoteCommandShellService; @@ -95,7 +95,7 @@ public class ArduinoRemoteConnection } public ArduinoBoard getBoard() throws CoreException { - return ArduinoBoardManager.instance.getBoard(remoteConnection.getAttribute(BOARD_NAME), + return ArduinoManager.instance.getBoard(remoteConnection.getAttribute(BOARD_NAME), remoteConnection.getAttribute(PLATFORM_NAME), remoteConnection.getAttribute(PACKAGE_NAME)); } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk index 51f22ea9994..8e9e03d55a9 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk @@ -26,6 +26,18 @@ PLATFORM_OBJS = \ </#if> </#list> +LIBRARIES_OBJS = \ +<#list libraries_srcs as file> +<#assign cpp = file?matches("${libraries_path}/(.*?)/.*?/(.*)\\.cpp")> +<#if cpp> + ${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.o \ +</#if> +<#assign c = file?matches("${libraries_path}/(.*?)/.*?/(.*)\\.c")> +<#if c> + ${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.o \ +</#if> +</#list> + all: ${build_path}/${project_name}.hex ${build_path}/${project_name}.eep ${build_path}/${project_name}.hex: ${build_path}/${project_name}.elf @@ -34,10 +46,10 @@ ${build_path}/${project_name}.hex: ${build_path}/${project_name}.elf ${build_path}/${project_name}.eep: ${build_path}/${project_name}.elf ${recipe_objcopy_eep_pattern} -${build_path}/${project_name}.elf: $(PROJECT_OBJS) ${build_path}/libc.a +${build_path}/${project_name}.elf: $(PROJECT_OBJS) $(LIBRARIES_OBJS) ${build_path}/core.a ${recipe_c_combine_pattern} -${build_path}/libc.a: $(PLATFORM_OBJS) +${build_path}/core.a: $(PLATFORM_OBJS) clean: $(RMDIR) ${build_path} @@ -73,3 +85,20 @@ ${build_path}/platform/${c?groups[1]}.o: ${file} </#if> </#list> + +<#list libraries_srcs as file> +<#assign cpp = file?matches("${libraries_path}/(.*?)/.*?/(.*)\\.cpp")> +<#if cpp> +${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.o: ${file} + @$(call mymkdir,$(dir $@)) + ${recipe_cpp_o_pattern} + +</#if> +<#assign c = file?matches("${libraries_path}/(.*?)/.*?/(.*)\\.c")> +<#if c> +${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.o: ${file} + @$(call mymkdir,$(dir $@)) + ${recipe_c_o_pattern} + +</#if> +</#list>
\ No newline at end of file diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml b/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml index 86ecabdea97..7971aae6958 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml @@ -49,6 +49,22 @@ </adapt> </enabledWhen> </page> + <page + class="org.eclipse.cdt.arduino.ui.internal.project.LibrariesPropertyPage" + id="org.eclipse.cdt.arduino.ui.librariesPropertyPage" + name="Libraries"> + <enabledWhen> + <and> + <instanceof + value="org.eclipse.core.resources.IProject"> + </instanceof> + <test + property="org.eclipse.core.resources.projectNature" + value="org.eclipse.cdt.arduino.core.arduinoNature"> + </test> + </and> + </enabledWhen> + </page> </extension> <extension point="org.eclipse.launchbar.ui.launchBarUIContributions"> diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoBoardsPreferencePage.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoBoardsPreferencePage.java index cfbed0431e5..379ca10e9a9 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoBoardsPreferencePage.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoBoardsPreferencePage.java @@ -15,7 +15,7 @@ import java.util.List; import java.util.Set; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; +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.board.PackageIndex; @@ -121,7 +121,7 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork table.removeAll(); try { - PackageIndex packageIndex = ArduinoBoardManager.instance.getPackageIndex(); + PackageIndex packageIndex = ArduinoManager.instance.getPackageIndex(); List<ArduinoBoard> boards = new ArrayList<>(); for (ArduinoPackage pkg : packageIndex.getPackages()) { for (ArduinoPlatform platform : pkg.getLatestPlatforms()) { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/LibrariesPropertyPage.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/LibrariesPropertyPage.java new file mode 100644 index 00000000000..a579f998fd1 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/LibrariesPropertyPage.java @@ -0,0 +1,188 @@ +package org.eclipse.cdt.arduino.ui.internal.project; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; +import org.eclipse.cdt.arduino.core.internal.board.LibraryIndex; +import org.eclipse.cdt.arduino.ui.internal.Activator; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.BaseLabelProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; +import org.eclipse.ui.dialogs.PropertyPage; + +public class LibrariesPropertyPage extends PropertyPage { + + private static class ContentProvider implements ITreeContentProvider { + private LibraryIndex index; + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + index = (LibraryIndex) newInput; + } + + @Override + public void dispose() { + } + + @Override + public boolean hasChildren(Object element) { + if (element instanceof LibraryIndex) { + return !index.getCategories().isEmpty(); + } else if (element instanceof String) { // category + return !index.getLibraries((String) element).isEmpty(); + } else if (element instanceof ArduinoLibrary) { + return false; + } else { + return false; + } + } + + @Override + public Object getParent(Object element) { + if (element instanceof ArduinoLibrary) { + return ((ArduinoLibrary) element).getCategory(); + } else if (element instanceof String) { + return index; + } else { + return null; + } + } + + @Override + public Object[] getElements(Object inputElement) { + return ((LibraryIndex) inputElement).getCategories().toArray(new String[0]); + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof String) { + return index.getLibraries((String) parentElement).toArray(new ArduinoLibrary[0]); + } else { + return null; + } + } + } + + private static class LabelProvider extends BaseLabelProvider implements ITableLabelProvider { + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if (element instanceof String) { + return columnIndex == 0 ? (String) element : null; + } else if (element instanceof ArduinoLibrary) { + switch (columnIndex) { + case 0: + return ((ArduinoLibrary) element).getName(); + case 1: + return ((ArduinoLibrary) element).getSentence(); + default: + return null; + } + } else { + return null; + } + } + + } + + private FilteredTree filteredTree; + + @Override + protected Control createContents(Composite parent) { + Composite comp = new Composite(parent, SWT.NULL); + comp.setLayout(new GridLayout()); + + filteredTree = new FilteredTree(comp, SWT.CHECK | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL, + new PatternFilter() { + @Override + protected boolean isLeafMatch(Viewer viewer, Object element) { + if (element instanceof String) { + return wordMatches((String) element); + } else if (element instanceof ArduinoLibrary) { + ArduinoLibrary lib = (ArduinoLibrary) element; + return wordMatches(lib.getName()) || wordMatches(lib.getSentence()) + || wordMatches(lib.getParagraph()); + } else { + return false; + } + } + }, true) { + @Override + protected TreeViewer doCreateTreeViewer(Composite parent, int style) { + return new ContainerCheckedTreeViewer(parent, style); + } + }; + filteredTree.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ContainerCheckedTreeViewer viewer = (ContainerCheckedTreeViewer) filteredTree.getViewer(); + + Tree tree = viewer.getTree(); + tree.setHeaderVisible(true); + TreeColumn column1 = new TreeColumn(tree, SWT.LEFT); + column1.setText("Name"); + column1.setWidth(200); + TreeColumn column2 = new TreeColumn(tree, SWT.LEFT); + column2.setText("Description"); + column2.setWidth(200); + + viewer.setContentProvider(new ContentProvider()); + viewer.setLabelProvider(new LabelProvider()); + + try { + viewer.setInput(ArduinoManager.instance.getLibraryIndex()); + // Set the check states for currently selected libraries + IProject project = getElement().getAdapter(IProject.class); + Collection<ArduinoLibrary> libraries = ArduinoManager.instance.getLibraries(project); + for (ArduinoLibrary lib : libraries) { + viewer.setChecked(lib, true); + } + } catch (CoreException e) { + Activator.log(e); + } + + return comp; + } + + @Override + public boolean performOk() { + List<ArduinoLibrary> libs = new ArrayList<>(); + for (TreeItem categoryItem : filteredTree.getViewer().getTree().getItems()) { + for (TreeItem libItem : categoryItem.getItems()) { + ArduinoLibrary lib = (ArduinoLibrary) libItem.getData(); + if (libItem.getChecked()) { + libs.add(lib); + } + } + } + try { + ArduinoManager.instance.setLibraries(getElement().getAdapter(IProject.class), libs); + } catch (CoreException e) { + Activator.log(e); + } + return true; + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/ArduinoTargetPropertyPage.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/ArduinoTargetPropertyPage.java index 0e9eae0003b..ca7f611fd79 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/ArduinoTargetPropertyPage.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/ArduinoTargetPropertyPage.java @@ -4,7 +4,7 @@ import java.io.IOException; import java.util.Collection; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; +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; @@ -76,7 +76,7 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc try { ArduinoBoard currentBoard = arduinoRemote.getBoard(); - Collection<ArduinoBoard> boardList = ArduinoBoardManager.instance.getBoards(); + Collection<ArduinoBoard> boardList = ArduinoManager.instance.getBoards(); boards = new ArduinoBoard[boardList.size()]; i = 0; int boardSel = 0; diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/NewArduinoTargetWizardPage.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/NewArduinoTargetWizardPage.java index 2e791ef44b3..756c434560f 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/NewArduinoTargetWizardPage.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/remote/NewArduinoTargetWizardPage.java @@ -6,7 +6,7 @@ import java.util.Comparator; import java.util.List; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; -import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; +import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; import org.eclipse.cdt.arduino.ui.internal.Activator; import org.eclipse.cdt.arduino.ui.internal.Messages; import org.eclipse.cdt.serial.SerialPort; @@ -93,7 +93,7 @@ public class NewArduinoTargetWizardPage extends WizardPage { boardCombo = new Combo(comp, SWT.READ_ONLY); boardCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); try { - List<ArduinoBoard> boardList = ArduinoBoardManager.instance.getInstalledBoards(); + List<ArduinoBoard> boardList = ArduinoManager.instance.getInstalledBoards(); Collections.sort(boardList, new Comparator<ArduinoBoard>() { @Override public int compare(ArduinoBoard o1, ArduinoBoard o2) { |