From e93760abc4fd1850d40c877ae05fcce693173e0c Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 24 Dec 2013 16:07:41 +0100 Subject: [PATCH 1/9] Implemented support for 1.5 libraries specification rev.2 - removed "arch" folder support - allow to optinally use "src" folder - slightly changed metadata For more information see: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification http://goo.gl/gfFJzU --- app/src/processing/app/debug/Compiler.java | 72 +++++----- app/src/processing/app/packages/Library.java | 142 +++++++++---------- 2 files changed, 101 insertions(+), 113 deletions(-) diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 5bdb7d2e989..08926e435f5 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -96,9 +96,8 @@ public boolean compile(boolean _verbose) throws RunnerException { if (verbose) System.out.println(I18n .format(_("Using library {0} in folder: {1} {2}"), lib.getName(), - lib.getFolder(), lib.isPre15Lib() ? "(pre-1.5)" : "")); - for (File folder : lib.getSrcFolders(targetArch)) - includePaths.add(folder.getPath()); + lib.getFolder(), lib.isLegacy() ? "(legacy)" : "")); + includePaths.add(lib.getSrcFolder().getPath()); } if (verbose) System.out.println(); @@ -615,47 +614,50 @@ void compileSketch(List includePaths) throws RunnerException { // 2. compile the libraries, outputting .o files to: // // void compileLibraries(List includePaths) throws RunnerException { - File outputPath = new File(prefs.get("build.path")); for (Library lib : sketch.getImportedLibraries()) { - for (File folder : lib.getSrcFolders(targetArch)) { - if (lib.isPre15Lib()) { - compileLibrary(outputPath, folder, includePaths); - } else { - recursiveCompileLibrary(outputPath, folder, includePaths); - } - } + compileLibrary(lib, includePaths); } } - private void recursiveCompileLibrary(File outputPath, File libraryFolder, List includePaths) throws RunnerException { - File newOutputPath = compileFilesInFolder(outputPath, libraryFolder, includePaths); - for (File subFolder : libraryFolder.listFiles(new OnlyDirs())) { - recursiveCompileLibrary(newOutputPath, subFolder, includePaths); + private void compileLibrary(Library lib, List includePaths) + throws RunnerException { + File libFolder = lib.getSrcFolder(); + File libBuildFolder = new File(prefs.get("build.path"), lib.getName()); + + if (lib.useRecursion()) { + // libBuildFolder == {build.path}/LibName + // libFolder == {lib.path}/src + recursiveCompileFilesInFolder(libBuildFolder, libFolder, includePaths); + + } else { + // libFolder == {lib.path}/ + // utilityFolder == {lib.path}/utility + // libBuildFolder == {build.path}/LibName + // utilityBuildFolder == {build.path}/LibName/utility + File utilityFolder = new File(libFolder, "utility"); + File utilityBuildFolder = new File(libBuildFolder, "utility"); + + includePaths.add(utilityFolder.getAbsolutePath()); + compileFilesInFolder(libBuildFolder, libFolder, includePaths); + compileFilesInFolder(utilityBuildFolder, utilityFolder, includePaths); + + // other libraries should not see this library's utility/ folder + includePaths.remove(utilityFolder.getAbsolutePath()); } } - private File compileFilesInFolder(File outputPath, File libraryFolder, List includePaths) throws RunnerException { - File outputFolder = new File(outputPath, libraryFolder.getName()); - createFolder(outputFolder); - objectFiles.addAll(compileFiles(outputFolder.getAbsolutePath(), libraryFolder, false, includePaths)); - return outputFolder; + private void recursiveCompileFilesInFolder(File srcBuildFolder, File srcFolder, List includePaths) throws RunnerException { + compileFilesInFolder(srcBuildFolder, srcFolder, includePaths); + for (File subFolder : srcFolder.listFiles(new OnlyDirs())) { + File subBuildFolder = new File(srcBuildFolder, subFolder.getName()); + recursiveCompileFilesInFolder(subBuildFolder, subFolder, includePaths); + } } - private void compileLibrary(File outputPath, File libraryFolder, List includePaths) throws RunnerException { - File outputFolder = new File(outputPath, libraryFolder.getName()); - File utilityFolder = new File(libraryFolder, "utility"); - createFolder(outputFolder); - // this library can use includes in its utility/ folder - includePaths.add(utilityFolder.getAbsolutePath()); - - objectFiles.addAll(compileFiles(outputFolder.getAbsolutePath(), - libraryFolder, false, includePaths)); - outputFolder = new File(outputFolder, "utility"); - createFolder(outputFolder); - objectFiles.addAll(compileFiles(outputFolder.getAbsolutePath(), - utilityFolder, false, includePaths)); - // other libraries should not see this library's utility/ folder - includePaths.remove(includePaths.size() - 1); + private void compileFilesInFolder(File buildFolder, File srcFolder, List includePaths) throws RunnerException { + createFolder(buildFolder); + List objects = compileFiles(buildFolder.getAbsolutePath(), srcFolder, false, includePaths); + objectFiles.addAll(objects); } // 3. compile the core, outputting .o files to and then diff --git a/app/src/processing/app/packages/Library.java b/app/src/processing/app/packages/Library.java index a6322ab449f..9fc96720f29 100644 --- a/app/src/processing/app/packages/Library.java +++ b/app/src/processing/app/packages/Library.java @@ -17,24 +17,23 @@ public class Library { private String name; private String version; private String author; - private String email; - private String url; + private String maintainer; private String sentence; private String paragraph; - private List coreDependencies; - private List dependencies; - private File folder, srcFolder, archFolder; + private String url; private List architectures; - private boolean pre15Lib; + private File folder; + private File srcFolder; + private boolean useRecursion; + private boolean isLegacy; private static final List MANDATORY_PROPERTIES = Arrays - .asList(new String[] { "architectures", "author", "core-dependencies", - "dependencies", "email", "name", "paragraph", "sentence", "url", - "version" }); + .asList(new String[] { "name", "version", "author", "maintainer", + "sentence", "paragraph", "url" }); /** * Scans inside a folder and create a Library object out of it. Automatically - * detects pre-1.5 libraries. Automatically fills metadata from + * detects legacy libraries. Automatically fills metadata from * library.properties file if found. * * @param libFolder @@ -45,7 +44,7 @@ static public Library create(File libFolder) throws IOException { // "library.properties" File check = new File(libFolder, "library.properties"); if (!check.exists() || !check.isFile()) - return createPre15Library(libFolder); + return createLegacyLibrary(libFolder); else return createLibrary(libFolder); } @@ -60,14 +59,34 @@ private static Library createLibrary(File libFolder) throws IOException { // --------------------- // 1. Check mandatory properties + + // provide compatibility with 1.5 rev.1 libs + // ("email" field changed to "maintainer") + if (!properties.containsKey("maintainer")) + properties.put("maintainer", properties.get("email")); + for (String p : MANDATORY_PROPERTIES) if (!properties.containsKey(p)) throw new IOException("Missing '" + p + "' from library"); - // 2. Check mandatory folders + // 2. Check layout + boolean useRecursion; File srcFolder = new File(libFolder, "src"); - if (!srcFolder.exists() || !srcFolder.isDirectory()) - throw new IOException("Missing 'src' folder"); + + if (srcFolder.exists() && srcFolder.isDirectory()) { + // Layout with a single "src" folder and recursive compilation + useRecursion = true; + + File utilFolder = new File(libFolder, "utility"); + if (utilFolder.exists() && utilFolder.isDirectory()) { + throw new IOException( + "Library can't use both 'src' and 'utility' folders."); + } + } else { + // Layout with source code on library's root and "utility" folders + srcFolder = libFolder; + useRecursion = false; + } // 3. Warn if root folder contains development leftovers for (File file : libFolder.listFiles()) { @@ -81,65 +100,38 @@ private static Library createLibrary(File libFolder) throws IOException { } // Extract metadata info + String architectures = properties.get("architectures"); + if (architectures == null) + architectures = "*"; // defaults to "any" List archs = new ArrayList(); - for (String arch : properties.get("architectures").split(",")) + for (String arch : architectures.split(",")) archs.add(arch.trim()); - List coreDeps = new ArrayList(); - for (String dep : properties.get("core-dependencies").split(",")) - coreDeps.add(dep.trim()); - - List dependencies = new ArrayList(); - for (String dependency : properties.get("dependencies").split(",")) { - dependency = dependency.trim(); - if (!dependency.equals("")) { - dependencies.add(dependency); - } - } - Library res = new Library(); res.folder = libFolder; res.srcFolder = srcFolder; - res.archFolder = new File(libFolder, "arch"); res.name = properties.get("name").trim(); + res.version = properties.get("version").trim(); res.author = properties.get("author").trim(); - res.email = properties.get("email").trim(); + res.maintainer = properties.get("maintainer").trim(); res.sentence = properties.get("sentence").trim(); res.paragraph = properties.get("paragraph").trim(); res.url = properties.get("url").trim(); res.architectures = archs; - res.coreDependencies = coreDeps; - res.dependencies = dependencies; - res.version = properties.get("version").trim(); - res.pre15Lib = false; + res.useRecursion = useRecursion; + res.isLegacy = false; return res; } - private static Library createPre15Library(File libFolder) { + private static Library createLegacyLibrary(File libFolder) { // construct an old style library Library res = new Library(); res.folder = libFolder; res.srcFolder = libFolder; + res.useRecursion = false; res.name = libFolder.getName(); res.architectures = Arrays.asList("*"); - res.pre15Lib = true; - return res; - } - - public List getSrcFolders(String reqArch) { - if (!supportsArchitecture(reqArch)) - return null; - List res = new ArrayList(); - res.add(srcFolder); - File archSpecificFolder = new File(archFolder, reqArch); - if (archSpecificFolder.exists() && archSpecificFolder.isDirectory()) { - res.add(archSpecificFolder); - } else { - // If specific architecture folder is not found try with "default" - archSpecificFolder = new File(archFolder, "default"); - if (archSpecificFolder.exists() && archSpecificFolder.isDirectory()) - res.add(archSpecificFolder); - } + res.isLegacy = true; return res; } @@ -157,18 +149,10 @@ public int compare(Library o1, Library o2) { } }; - public File getSrcFolder() { - return srcFolder; - } - public String getName() { return name; } - public boolean isPre15Lib() { - return pre15Lib; - } - public File getFolder() { return folder; } @@ -181,18 +165,6 @@ public String getAuthor() { return author; } - public List getCoreDependencies() { - return coreDependencies; - } - - public List getDependencies() { - return dependencies; - } - - public String getEmail() { - return email; - } - public String getParagraph() { return paragraph; } @@ -209,19 +181,33 @@ public String getVersion() { return version; } + public String getMaintainer() { + return maintainer; + } + + public boolean useRecursion() { + return useRecursion; + } + + public File getSrcFolder() { + return srcFolder; + } + + public boolean isLegacy() { + return isLegacy; + } + @Override public String toString() { String res = "Library:"; res += " (name=" + name + ")"; - res += " (architectures=" + architectures + ")"; + res += " (version=" + version + ")"; res += " (author=" + author + ")"; - res += " (core-dependencies=" + coreDependencies + ")"; - res += " (dependencies=" + dependencies + ")"; - res += " (email=" + email + ")"; - res += " (paragraph=" + paragraph + ")"; + res += " (maintainer=" + maintainer + ")"; res += " (sentence=" + sentence + ")"; + res += " (paragraph=" + paragraph + ")"; res += " (url=" + url + ")"; - res += " (version=" + version + ")"; + res += " (architectures=" + architectures + ")"; return res; } } From e045cd26ccda700a324409f7e6e13ab3f6670a0e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 24 Dec 2013 16:23:21 +0100 Subject: [PATCH 2/9] Added a warning for library using the no longer supported "arch" folder --- app/src/processing/app/packages/Library.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/processing/app/packages/Library.java b/app/src/processing/app/packages/Library.java index 9fc96720f29..1e95205c6a0 100644 --- a/app/src/processing/app/packages/Library.java +++ b/app/src/processing/app/packages/Library.java @@ -58,18 +58,24 @@ private static Library createLibrary(File libFolder) throws IOException { // Library sanity checks // --------------------- - // 1. Check mandatory properties - - // provide compatibility with 1.5 rev.1 libs - // ("email" field changed to "maintainer") + // Compatibility with 1.5 rev.1 libraries: + // "email" field changed to "maintainer" if (!properties.containsKey("maintainer")) properties.put("maintainer", properties.get("email")); + // Compatibility with 1.5 rev.1 libraries: + // "arch" folder no longer supported + File archFolder = new File(libFolder, "arch"); + if (archFolder.isDirectory()) + throw new IOException("'arch' folder is no longer supported! See " + + "http://goo.gl/gfFJzU for more information"); + + // Check mandatory properties for (String p : MANDATORY_PROPERTIES) if (!properties.containsKey(p)) throw new IOException("Missing '" + p + "' from library"); - // 2. Check layout + // Check layout boolean useRecursion; File srcFolder = new File(libFolder, "src"); @@ -88,7 +94,7 @@ private static Library createLibrary(File libFolder) throws IOException { useRecursion = false; } - // 3. Warn if root folder contains development leftovers + // Warn if root folder contains development leftovers for (File file : libFolder.listFiles()) { if (file.isDirectory()) { if (FileUtils.isSCCSOrHiddenFile(file)) { From 5e7663574bb9a002245e426bdb6199e7bfe09d3b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 24 Dec 2013 20:08:22 +0100 Subject: [PATCH 3/9] Use Files instead of String to handle paths in Compiler class. --- app/src/processing/app/debug/Compiler.java | 152 +++++++++--------- .../app/helpers/PreferencesMap.java | 33 ++++ 2 files changed, 105 insertions(+), 80 deletions(-) diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 08926e435f5..8abb1ee04b3 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -88,29 +88,29 @@ public boolean compile(boolean _verbose) throws RunnerException { // 0. include paths for core + all libraries sketch.setCompilingProgress(20); - List includePaths = new ArrayList(); - includePaths.add(prefs.get("build.core.path")); - if (prefs.get("build.variant.path").length() != 0) - includePaths.add(prefs.get("build.variant.path")); + List includeFolders = new ArrayList(); + includeFolders.add(prefs.getFile("build.core.path")); + if (prefs.getFile("build.variant.path") != null) + includeFolders.add(prefs.getFile("build.variant.path")); for (Library lib : sketch.getImportedLibraries()) { if (verbose) System.out.println(I18n .format(_("Using library {0} in folder: {1} {2}"), lib.getName(), lib.getFolder(), lib.isLegacy() ? "(legacy)" : "")); - includePaths.add(lib.getSrcFolder().getPath()); + includeFolders.add(lib.getSrcFolder()); } if (verbose) System.out.println(); // 1. compile the sketch (already in the buildPath) sketch.setCompilingProgress(30); - compileSketch(includePaths); + compileSketch(includeFolders); sketchIsCompiled = true; // 2. compile the libraries, outputting .o files to: // // Doesn't really use configPreferences sketch.setCompilingProgress(40); - compileLibraries(includePaths); + compileLibraries(includeFolders); // 3. compile the core, outputting .o files to and then // collecting them into the core.a library file. @@ -119,15 +119,15 @@ public boolean compile(boolean _verbose) throws RunnerException { // 4. link it all together into the .elf file sketch.setCompilingProgress(60); - compileLink(includePaths); + compileLink(); // 5. extract EEPROM data (from EEMEM directive) to .eep file. sketch.setCompilingProgress(70); - compileEep(includePaths); + compileEep(); // 6. build the .hex file sketch.setCompilingProgress(80); - compileHex(includePaths); + compileHex(); sketch.setCompilingProgress(90); return true; @@ -217,8 +217,8 @@ private PreferencesMap createBuildPreferences(String _buildPath, return p; } - private List compileFiles(String outputPath, File sourcePath, - boolean recurse, List includePaths) + private List compileFiles(File outputPath, File sourcePath, + boolean recurse, List includeFolders) throws RunnerException { List sSources = findFilesInFolder(sourcePath, "S", recurse); List cSources = findFilesInFolder(sourcePath, "c", recurse); @@ -226,36 +226,29 @@ private List compileFiles(String outputPath, File sourcePath, List objectPaths = new ArrayList(); for (File file : sSources) { - String objectPath = outputPath + File.separator + file.getName() + ".o"; - objectPaths.add(new File(objectPath)); - String[] cmd = getCommandCompilerS(includePaths, file.getAbsolutePath(), - objectPath); + File objectFile = new File(outputPath, file.getName() + ".o"); + objectPaths.add(objectFile); + String[] cmd = getCommandCompilerS(includeFolders, file, objectFile); execAsynchronously(cmd); } for (File file : cSources) { - String objectPath = outputPath + File.separator + file.getName() + ".o"; - String dependPath = outputPath + File.separator + file.getName() + ".d"; - File objectFile = new File(objectPath); - File dependFile = new File(dependPath); + File objectFile = new File(outputPath, file.getName() + ".o"); + File dependFile = new File(outputPath, file.getName() + ".d"); objectPaths.add(objectFile); if (isAlreadyCompiled(file, objectFile, dependFile, prefs)) continue; - String[] cmd = getCommandCompilerC(includePaths, file.getAbsolutePath(), - objectPath); + String[] cmd = getCommandCompilerC(includeFolders, file, objectFile); execAsynchronously(cmd); } for (File file : cppSources) { - String objectPath = outputPath + File.separator + file.getName() + ".o"; - String dependPath = outputPath + File.separator + file.getName() + ".d"; - File objectFile = new File(objectPath); - File dependFile = new File(dependPath); + File objectFile = new File(outputPath, file.getName() + ".o"); + File dependFile = new File(outputPath, file.getName() + ".d"); objectPaths.add(objectFile); if (isAlreadyCompiled(file, objectFile, dependFile, prefs)) continue; - String[] cmd = getCommandCompilerCPP(includePaths, - file.getAbsolutePath(), objectPath); + String[] cmd = getCommandCompilerCPP(includeFolders, file, objectFile); execAsynchronously(cmd); } @@ -510,15 +503,15 @@ public void message(String s) { System.err.print(s); } - private String[] getCommandCompilerS(List includePaths, - String sourceName, String objectName) + private String[] getCommandCompilerS(List includeFolders, + File sourceFile, File objectFile) throws RunnerException { - String includes = preparePaths(includePaths); + String includes = prepareIncludes(includeFolders); PreferencesMap dict = new PreferencesMap(prefs); dict.put("ide_version", "" + Base.REVISION); dict.put("includes", includes); - dict.put("source_file", sourceName); - dict.put("object_file", objectName); + dict.put("source_file", sourceFile.getAbsolutePath()); + dict.put("object_file", objectFile.getAbsolutePath()); try { String cmd = prefs.get("recipe.S.o.pattern"); @@ -528,16 +521,16 @@ private String[] getCommandCompilerS(List includePaths, } } - private String[] getCommandCompilerC(List includePaths, - String sourceName, String objectName) + private String[] getCommandCompilerC(List includeFolders, + File sourceFile, File objectFile) throws RunnerException { - String includes = preparePaths(includePaths); + String includes = prepareIncludes(includeFolders); PreferencesMap dict = new PreferencesMap(prefs); dict.put("ide_version", "" + Base.REVISION); dict.put("includes", includes); - dict.put("source_file", sourceName); - dict.put("object_file", objectName); + dict.put("source_file", sourceFile.getAbsolutePath()); + dict.put("object_file", objectFile.getAbsolutePath()); String cmd = prefs.get("recipe.c.o.pattern"); try { @@ -547,16 +540,16 @@ private String[] getCommandCompilerC(List includePaths, } } - private String[] getCommandCompilerCPP(List includePaths, - String sourceName, String objectName) + private String[] getCommandCompilerCPP(List includeFolders, + File sourceFile, File objectFile) throws RunnerException { - String includes = preparePaths(includePaths); + String includes = prepareIncludes(includeFolders); PreferencesMap dict = new PreferencesMap(prefs); dict.put("ide_version", "" + Base.REVISION); dict.put("includes", includes); - dict.put("source_file", sourceName); - dict.put("object_file", objectName); + dict.put("source_file", sourceFile.getAbsolutePath()); + dict.put("object_file", objectFile.getAbsolutePath()); String cmd = prefs.get("recipe.cpp.o.pattern"); try { @@ -605,29 +598,28 @@ static public List findFilesInFolder(File folder, String extension, } // 1. compile the sketch (already in the buildPath) - void compileSketch(List includePaths) throws RunnerException { - String buildPath = prefs.get("build.path"); - objectFiles.addAll(compileFiles(buildPath, new File(buildPath), false, - includePaths)); + void compileSketch(List includeFolders) throws RunnerException { + File buildPath = prefs.getFile("build.path"); + objectFiles.addAll(compileFiles(buildPath, buildPath, false, includeFolders)); } // 2. compile the libraries, outputting .o files to: // // - void compileLibraries(List includePaths) throws RunnerException { + void compileLibraries(List includeFolders) throws RunnerException { for (Library lib : sketch.getImportedLibraries()) { - compileLibrary(lib, includePaths); + compileLibrary(lib, includeFolders); } } - private void compileLibrary(Library lib, List includePaths) + private void compileLibrary(Library lib, List includeFolders) throws RunnerException { File libFolder = lib.getSrcFolder(); - File libBuildFolder = new File(prefs.get("build.path"), lib.getName()); + File libBuildFolder = prefs.getFile(("build.path"), lib.getName()); if (lib.useRecursion()) { // libBuildFolder == {build.path}/LibName // libFolder == {lib.path}/src - recursiveCompileFilesInFolder(libBuildFolder, libFolder, includePaths); + recursiveCompileFilesInFolder(libBuildFolder, libFolder, includeFolders); } else { // libFolder == {lib.path}/ @@ -637,26 +629,26 @@ private void compileLibrary(Library lib, List includePaths) File utilityFolder = new File(libFolder, "utility"); File utilityBuildFolder = new File(libBuildFolder, "utility"); - includePaths.add(utilityFolder.getAbsolutePath()); - compileFilesInFolder(libBuildFolder, libFolder, includePaths); - compileFilesInFolder(utilityBuildFolder, utilityFolder, includePaths); + includeFolders.add(utilityFolder); + compileFilesInFolder(libBuildFolder, libFolder, includeFolders); + compileFilesInFolder(utilityBuildFolder, utilityFolder, includeFolders); // other libraries should not see this library's utility/ folder - includePaths.remove(utilityFolder.getAbsolutePath()); + includeFolders.remove(utilityFolder); } } - private void recursiveCompileFilesInFolder(File srcBuildFolder, File srcFolder, List includePaths) throws RunnerException { - compileFilesInFolder(srcBuildFolder, srcFolder, includePaths); + private void recursiveCompileFilesInFolder(File srcBuildFolder, File srcFolder, List includeFolders) throws RunnerException { + compileFilesInFolder(srcBuildFolder, srcFolder, includeFolders); for (File subFolder : srcFolder.listFiles(new OnlyDirs())) { File subBuildFolder = new File(srcBuildFolder, subFolder.getName()); - recursiveCompileFilesInFolder(subBuildFolder, subFolder, includePaths); + recursiveCompileFilesInFolder(subBuildFolder, subFolder, includeFolders); } } - private void compileFilesInFolder(File buildFolder, File srcFolder, List includePaths) throws RunnerException { + private void compileFilesInFolder(File buildFolder, File srcFolder, List includeFolders) throws RunnerException { createFolder(buildFolder); - List objects = compileFiles(buildFolder.getAbsolutePath(), srcFolder, false, includePaths); + List objects = compileFiles(buildFolder, srcFolder, false, includeFolders); objectFiles.addAll(objects); } @@ -665,22 +657,22 @@ private void compileFilesInFolder(File buildFolder, File srcFolder, List void compileCore() throws RunnerException { - String corePath = prefs.get("build.core.path"); - String variantPath = prefs.get("build.variant.path"); - String buildPath = prefs.get("build.path"); + File coreFolder = prefs.getFile("build.core.path"); + File variantFolder = prefs.getFile("build.variant.path"); + File buildFolder = prefs.getFile("build.path"); - List includePaths = new ArrayList(); - includePaths.add(corePath); // include core path only - if (variantPath.length() != 0) - includePaths.add(variantPath); + List includeFolders = new ArrayList(); + includeFolders.add(coreFolder); // include core path only + if (variantFolder != null) + includeFolders.add(variantFolder); - List coreObjectFiles = compileFiles(buildPath, new File(corePath), - true, includePaths); - if (variantPath.length() != 0) - coreObjectFiles.addAll(compileFiles(buildPath, new File(variantPath), - true, includePaths)); + List objectFiles = compileFiles(buildFolder, coreFolder, true, + includeFolders); + if (variantFolder != null) + objectFiles.addAll(compileFiles(buildFolder, variantFolder, true, + includeFolders)); - for (File file : coreObjectFiles) { + for (File file : objectFiles) { PreferencesMap dict = new PreferencesMap(prefs); dict.put("ide_version", "" + Base.REVISION); @@ -699,7 +691,7 @@ void compileCore() } // 4. link it all together into the .elf file - void compileLink(List includePaths) + void compileLink() throws RunnerException { // TODO: Make the --relax thing in configuration files. @@ -733,7 +725,7 @@ void compileLink(List includePaths) } // 5. extract EEPROM data (from EEMEM directive) to .eep file. - void compileEep(List includePaths) throws RunnerException { + void compileEep() throws RunnerException { PreferencesMap dict = new PreferencesMap(prefs); dict.put("ide_version", "" + Base.REVISION); @@ -748,7 +740,7 @@ void compileEep(List includePaths) throws RunnerException { } // 6. build the .hex file - void compileHex(List includePaths) throws RunnerException { + void compileHex() throws RunnerException { PreferencesMap dict = new PreferencesMap(prefs); dict.put("ide_version", "" + Base.REVISION); @@ -762,10 +754,10 @@ void compileHex(List includePaths) throws RunnerException { execAsynchronously(cmdArray); } - private static String preparePaths(List includePaths) { + private static String prepareIncludes(List includeFolders) { String res = ""; - for (String p : includePaths) - res += " \"-I" + p + '"'; + for (File p : includeFolders) + res += " \"-I" + p.getAbsolutePath() + '"'; // Remove first space return res.substring(1); diff --git a/app/src/processing/app/helpers/PreferencesMap.java b/app/src/processing/app/helpers/PreferencesMap.java index cd3bb7dd2f7..bac942a7729 100644 --- a/app/src/processing/app/helpers/PreferencesMap.java +++ b/app/src/processing/app/helpers/PreferencesMap.java @@ -265,4 +265,37 @@ public String getOrExcept(String k) throws PreferencesMapException { public String toString() { return toString(""); } + + /** + * Creates a new File instance by converting the value of the key into an + * abstract pathname. If the the given key doesn't exists or his value is the + * empty string, the result is null. + * + * @param key + * @return + */ + public File getFile(String key) { + if (!containsKey(key)) + return null; + String path = get(key).trim(); + if (path.length() == 0) + return null; + return new File(path); + } + + /** + * Creates a new File instance by converting the value of the key into an + * abstract pathname with the specified sub folder. If the the given key + * doesn't exists or his value is the empty string, the result is null. + * + * @param key + * @param subFolder + * @return + */ + public File getFile(String key, String subFolder) { + File file = getFile(key); + if (file == null) + return null; + return new File(file, subFolder); + } } From 4932831f8b2d8b93e1e11ab670b5bce18e518c16 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 25 Dec 2013 16:16:31 +0100 Subject: [PATCH 4/9] IDE do not hide libraries with incompatible architectures --- app/src/processing/app/Base.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 5f351f76477..fd5ab7df68a 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -1323,8 +1323,6 @@ public void onBoardOrPortChange() { } catch (IOException e) { showWarning(_("Error"), _("Error loading libraries"), e); } - String currentArch = Base.getTargetPlatform().getId(); - libraries = libraries.filterByArchitecture(currentArch); // Populate importToLibraryTable importToLibraryTable = new HashMap(); From ce5ff8c2991fd945c880e80251d073aed43ec620 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 25 Dec 2013 19:20:29 +0100 Subject: [PATCH 5/9] Added "category" field in libraries. --- app/src/processing/app/packages/Library.java | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/src/processing/app/packages/Library.java b/app/src/processing/app/packages/Library.java index 1e95205c6a0..e94ab36808b 100644 --- a/app/src/processing/app/packages/Library.java +++ b/app/src/processing/app/packages/Library.java @@ -21,6 +21,7 @@ public class Library { private String sentence; private String paragraph; private String url; + private String category; private List architectures; private File folder; private File srcFolder; @@ -31,6 +32,11 @@ public class Library { .asList(new String[] { "name", "version", "author", "maintainer", "sentence", "paragraph", "url" }); + private static final List CATEGORIES = Arrays.asList(new String[] { + "Display", "Communication", "Signal Input/Output", "Sensors", + "Device Control", "Timing", "Data Storage", "Data Processing", "Other", + "Uncategorized" }); + /** * Scans inside a folder and create a Library object out of it. Automatically * detects legacy libraries. Automatically fills metadata from @@ -113,6 +119,12 @@ private static Library createLibrary(File libFolder) throws IOException { for (String arch : architectures.split(",")) archs.add(arch.trim()); + String category = properties.get("category"); + if (category == null) + category = "Uncategorized"; + if (!CATEGORIES.contains(category)) + category = "Uncategorized"; + Library res = new Library(); res.folder = libFolder; res.srcFolder = srcFolder; @@ -123,6 +135,7 @@ private static Library createLibrary(File libFolder) throws IOException { res.sentence = properties.get("sentence").trim(); res.paragraph = properties.get("paragraph").trim(); res.url = properties.get("url").trim(); + res.category = category.trim(); res.architectures = archs; res.useRecursion = useRecursion; res.isLegacy = false; @@ -183,6 +196,14 @@ public String getUrl() { return url; } + public String getCategory() { + return category; + } + + public static List getCategories() { + return CATEGORIES; + } + public String getVersion() { return version; } From 164da522b6f7e47a39bda5475ee0fcb0fa6b5bfb Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 25 Dec 2013 19:27:09 +0100 Subject: [PATCH 6/9] Added "license" field in libraries. --- app/src/processing/app/packages/Library.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/processing/app/packages/Library.java b/app/src/processing/app/packages/Library.java index e94ab36808b..67b8865a3d1 100644 --- a/app/src/processing/app/packages/Library.java +++ b/app/src/processing/app/packages/Library.java @@ -22,6 +22,7 @@ public class Library { private String paragraph; private String url; private String category; + private String license; private List architectures; private File folder; private File srcFolder; @@ -125,6 +126,10 @@ private static Library createLibrary(File libFolder) throws IOException { if (!CATEGORIES.contains(category)) category = "Uncategorized"; + String license = properties.get("license"); + if (license == null) + license = "Unspecified"; + Library res = new Library(); res.folder = libFolder; res.srcFolder = srcFolder; @@ -136,6 +141,7 @@ private static Library createLibrary(File libFolder) throws IOException { res.paragraph = properties.get("paragraph").trim(); res.url = properties.get("url").trim(); res.category = category.trim(); + res.license = license.trim(); res.architectures = archs; res.useRecursion = useRecursion; res.isLegacy = false; @@ -200,6 +206,10 @@ public String getCategory() { return category; } + public String getLicense() { + return license; + } + public static List getCategories() { return CATEGORIES; } From 512925a8128dd9f261d0ee48d7f78043d11268d8 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 25 Dec 2013 20:16:14 +0100 Subject: [PATCH 7/9] IDE warns if a library is compiled with an unsupported architecture --- app/src/processing/app/debug/Compiler.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 8abb1ee04b3..12641e709fa 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -101,6 +101,18 @@ public boolean compile(boolean _verbose) throws RunnerException { } if (verbose) System.out.println(); + + String arch = Base.getTargetPlatform().getId(); + for (Library lib : sketch.getImportedLibraries()) { + if (!lib.supportsArchitecture(arch)) { + System.err.println(I18n + .format(_("WARNING: library {0} claims to run on {1} " + + "architecture(s) and may be incompatible with your" + + " current board which runs on [{2}] architecture."), lib + .getName(), lib.getArchitectures(), arch)); + System.err.println(); + } + } // 1. compile the sketch (already in the buildPath) sketch.setCompilingProgress(30); From 2b53d6988a6fa093e032a803605aa247fb580a63 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 26 Dec 2013 01:32:30 +0100 Subject: [PATCH 8/9] Added the possibility to override library compatibility check --- app/src/processing/app/debug/Compiler.java | 14 +++++++--- app/src/processing/app/packages/Library.java | 27 +++++++++++++++++--- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 12641e709fa..ae3f7e763cc 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -30,6 +30,7 @@ import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -102,14 +103,19 @@ public boolean compile(boolean _verbose) throws RunnerException { if (verbose) System.out.println(); - String arch = Base.getTargetPlatform().getId(); + List archs = new ArrayList(); + archs.add(Base.getTargetPlatform().getId()); + if (prefs.containsKey("architecture.override_check")) { + String[] overrides = prefs.get("architecture.override_check").split(","); + archs.addAll(Arrays.asList(overrides)); + } for (Library lib : sketch.getImportedLibraries()) { - if (!lib.supportsArchitecture(arch)) { + if (!lib.supportsArchitecture(archs)) { System.err.println(I18n .format(_("WARNING: library {0} claims to run on {1} " + "architecture(s) and may be incompatible with your" - + " current board which runs on [{2}] architecture."), lib - .getName(), lib.getArchitectures(), arch)); + + " current board which runs on {2} architecture(s)."), lib + .getName(), lib.getArchitectures(), archs)); System.err.println(); } } diff --git a/app/src/processing/app/packages/Library.java b/app/src/processing/app/packages/Library.java index 67b8865a3d1..2ac8e5a4379 100644 --- a/app/src/processing/app/packages/Library.java +++ b/app/src/processing/app/packages/Library.java @@ -1,7 +1,5 @@ package processing.app.packages; -import static processing.app.helpers.StringUtils.wildcardMatch; - import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -160,9 +158,30 @@ private static Library createLegacyLibrary(File libFolder) { return res; } + /** + * Returns true if the library declares to support the specified + * architecture (through the "architectures" property field). + * + * @param reqArch + * @return + */ public boolean supportsArchitecture(String reqArch) { - for (String arch : architectures) - if (wildcardMatch(reqArch, arch)) + return architectures.contains(reqArch) || architectures.contains("*"); + } + + /** + * Returns true if the library declares to support at least one of the + * specified architectures. + * + * @param reqArchs + * A List of architectures to check + * @return + */ + public boolean supportsArchitecture(List reqArchs) { + if (reqArchs.contains("*")) + return true; + for (String reqArch : reqArchs) + if (supportsArchitecture(reqArch)) return true; return false; } From 6923cc9c3919d67b38c6e1ce893391b9bd184c5d Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 26 Dec 2013 15:11:16 +0100 Subject: [PATCH 9/9] Removed unused import --- app/src/processing/app/Sketch.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index c8a2967ec0f..5d66e18a89e 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -38,7 +38,6 @@ import processing.core.*; import static processing.app.I18n._; -import java.awt.*; import java.io.*; import java.util.*; import java.util.List;