Use Files instead of String to handle paths in Compiler class.

This commit is contained in:
Cristian Maglie 2013-12-24 20:08:22 +01:00
parent e045cd26cc
commit 5e7663574b
2 changed files with 105 additions and 80 deletions

View File

@ -88,29 +88,29 @@ public class Compiler implements MessageConsumer {
// 0. include paths for core + all libraries // 0. include paths for core + all libraries
sketch.setCompilingProgress(20); sketch.setCompilingProgress(20);
List<String> includePaths = new ArrayList<String>(); List<File> includeFolders = new ArrayList<File>();
includePaths.add(prefs.get("build.core.path")); includeFolders.add(prefs.getFile("build.core.path"));
if (prefs.get("build.variant.path").length() != 0) if (prefs.getFile("build.variant.path") != null)
includePaths.add(prefs.get("build.variant.path")); includeFolders.add(prefs.getFile("build.variant.path"));
for (Library lib : sketch.getImportedLibraries()) { for (Library lib : sketch.getImportedLibraries()) {
if (verbose) if (verbose)
System.out.println(I18n System.out.println(I18n
.format(_("Using library {0} in folder: {1} {2}"), lib.getName(), .format(_("Using library {0} in folder: {1} {2}"), lib.getName(),
lib.getFolder(), lib.isLegacy() ? "(legacy)" : "")); lib.getFolder(), lib.isLegacy() ? "(legacy)" : ""));
includePaths.add(lib.getSrcFolder().getPath()); includeFolders.add(lib.getSrcFolder());
} }
if (verbose) if (verbose)
System.out.println(); System.out.println();
// 1. compile the sketch (already in the buildPath) // 1. compile the sketch (already in the buildPath)
sketch.setCompilingProgress(30); sketch.setCompilingProgress(30);
compileSketch(includePaths); compileSketch(includeFolders);
sketchIsCompiled = true; sketchIsCompiled = true;
// 2. compile the libraries, outputting .o files to: <buildPath>/<library>/ // 2. compile the libraries, outputting .o files to: <buildPath>/<library>/
// Doesn't really use configPreferences // Doesn't really use configPreferences
sketch.setCompilingProgress(40); sketch.setCompilingProgress(40);
compileLibraries(includePaths); compileLibraries(includeFolders);
// 3. compile the core, outputting .o files to <buildPath> and then // 3. compile the core, outputting .o files to <buildPath> and then
// collecting them into the core.a library file. // collecting them into the core.a library file.
@ -119,15 +119,15 @@ public class Compiler implements MessageConsumer {
// 4. link it all together into the .elf file // 4. link it all together into the .elf file
sketch.setCompilingProgress(60); sketch.setCompilingProgress(60);
compileLink(includePaths); compileLink();
// 5. extract EEPROM data (from EEMEM directive) to .eep file. // 5. extract EEPROM data (from EEMEM directive) to .eep file.
sketch.setCompilingProgress(70); sketch.setCompilingProgress(70);
compileEep(includePaths); compileEep();
// 6. build the .hex file // 6. build the .hex file
sketch.setCompilingProgress(80); sketch.setCompilingProgress(80);
compileHex(includePaths); compileHex();
sketch.setCompilingProgress(90); sketch.setCompilingProgress(90);
return true; return true;
@ -217,8 +217,8 @@ public class Compiler implements MessageConsumer {
return p; return p;
} }
private List<File> compileFiles(String outputPath, File sourcePath, private List<File> compileFiles(File outputPath, File sourcePath,
boolean recurse, List<String> includePaths) boolean recurse, List<File> includeFolders)
throws RunnerException { throws RunnerException {
List<File> sSources = findFilesInFolder(sourcePath, "S", recurse); List<File> sSources = findFilesInFolder(sourcePath, "S", recurse);
List<File> cSources = findFilesInFolder(sourcePath, "c", recurse); List<File> cSources = findFilesInFolder(sourcePath, "c", recurse);
@ -226,36 +226,29 @@ public class Compiler implements MessageConsumer {
List<File> objectPaths = new ArrayList<File>(); List<File> objectPaths = new ArrayList<File>();
for (File file : sSources) { for (File file : sSources) {
String objectPath = outputPath + File.separator + file.getName() + ".o"; File objectFile = new File(outputPath, file.getName() + ".o");
objectPaths.add(new File(objectPath)); objectPaths.add(objectFile);
String[] cmd = getCommandCompilerS(includePaths, file.getAbsolutePath(), String[] cmd = getCommandCompilerS(includeFolders, file, objectFile);
objectPath);
execAsynchronously(cmd); execAsynchronously(cmd);
} }
for (File file : cSources) { for (File file : cSources) {
String objectPath = outputPath + File.separator + file.getName() + ".o"; File objectFile = new File(outputPath, file.getName() + ".o");
String dependPath = outputPath + File.separator + file.getName() + ".d"; File dependFile = new File(outputPath, file.getName() + ".d");
File objectFile = new File(objectPath);
File dependFile = new File(dependPath);
objectPaths.add(objectFile); objectPaths.add(objectFile);
if (isAlreadyCompiled(file, objectFile, dependFile, prefs)) if (isAlreadyCompiled(file, objectFile, dependFile, prefs))
continue; continue;
String[] cmd = getCommandCompilerC(includePaths, file.getAbsolutePath(), String[] cmd = getCommandCompilerC(includeFolders, file, objectFile);
objectPath);
execAsynchronously(cmd); execAsynchronously(cmd);
} }
for (File file : cppSources) { for (File file : cppSources) {
String objectPath = outputPath + File.separator + file.getName() + ".o"; File objectFile = new File(outputPath, file.getName() + ".o");
String dependPath = outputPath + File.separator + file.getName() + ".d"; File dependFile = new File(outputPath, file.getName() + ".d");
File objectFile = new File(objectPath);
File dependFile = new File(dependPath);
objectPaths.add(objectFile); objectPaths.add(objectFile);
if (isAlreadyCompiled(file, objectFile, dependFile, prefs)) if (isAlreadyCompiled(file, objectFile, dependFile, prefs))
continue; continue;
String[] cmd = getCommandCompilerCPP(includePaths, String[] cmd = getCommandCompilerCPP(includeFolders, file, objectFile);
file.getAbsolutePath(), objectPath);
execAsynchronously(cmd); execAsynchronously(cmd);
} }
@ -510,15 +503,15 @@ public class Compiler implements MessageConsumer {
System.err.print(s); System.err.print(s);
} }
private String[] getCommandCompilerS(List<String> includePaths, private String[] getCommandCompilerS(List<File> includeFolders,
String sourceName, String objectName) File sourceFile, File objectFile)
throws RunnerException { throws RunnerException {
String includes = preparePaths(includePaths); String includes = prepareIncludes(includeFolders);
PreferencesMap dict = new PreferencesMap(prefs); PreferencesMap dict = new PreferencesMap(prefs);
dict.put("ide_version", "" + Base.REVISION); dict.put("ide_version", "" + Base.REVISION);
dict.put("includes", includes); dict.put("includes", includes);
dict.put("source_file", sourceName); dict.put("source_file", sourceFile.getAbsolutePath());
dict.put("object_file", objectName); dict.put("object_file", objectFile.getAbsolutePath());
try { try {
String cmd = prefs.get("recipe.S.o.pattern"); String cmd = prefs.get("recipe.S.o.pattern");
@ -528,16 +521,16 @@ public class Compiler implements MessageConsumer {
} }
} }
private String[] getCommandCompilerC(List<String> includePaths, private String[] getCommandCompilerC(List<File> includeFolders,
String sourceName, String objectName) File sourceFile, File objectFile)
throws RunnerException { throws RunnerException {
String includes = preparePaths(includePaths); String includes = prepareIncludes(includeFolders);
PreferencesMap dict = new PreferencesMap(prefs); PreferencesMap dict = new PreferencesMap(prefs);
dict.put("ide_version", "" + Base.REVISION); dict.put("ide_version", "" + Base.REVISION);
dict.put("includes", includes); dict.put("includes", includes);
dict.put("source_file", sourceName); dict.put("source_file", sourceFile.getAbsolutePath());
dict.put("object_file", objectName); dict.put("object_file", objectFile.getAbsolutePath());
String cmd = prefs.get("recipe.c.o.pattern"); String cmd = prefs.get("recipe.c.o.pattern");
try { try {
@ -547,16 +540,16 @@ public class Compiler implements MessageConsumer {
} }
} }
private String[] getCommandCompilerCPP(List<String> includePaths, private String[] getCommandCompilerCPP(List<File> includeFolders,
String sourceName, String objectName) File sourceFile, File objectFile)
throws RunnerException { throws RunnerException {
String includes = preparePaths(includePaths); String includes = prepareIncludes(includeFolders);
PreferencesMap dict = new PreferencesMap(prefs); PreferencesMap dict = new PreferencesMap(prefs);
dict.put("ide_version", "" + Base.REVISION); dict.put("ide_version", "" + Base.REVISION);
dict.put("includes", includes); dict.put("includes", includes);
dict.put("source_file", sourceName); dict.put("source_file", sourceFile.getAbsolutePath());
dict.put("object_file", objectName); dict.put("object_file", objectFile.getAbsolutePath());
String cmd = prefs.get("recipe.cpp.o.pattern"); String cmd = prefs.get("recipe.cpp.o.pattern");
try { try {
@ -605,29 +598,28 @@ public class Compiler implements MessageConsumer {
} }
// 1. compile the sketch (already in the buildPath) // 1. compile the sketch (already in the buildPath)
void compileSketch(List<String> includePaths) throws RunnerException { void compileSketch(List<File> includeFolders) throws RunnerException {
String buildPath = prefs.get("build.path"); File buildPath = prefs.getFile("build.path");
objectFiles.addAll(compileFiles(buildPath, new File(buildPath), false, objectFiles.addAll(compileFiles(buildPath, buildPath, false, includeFolders));
includePaths));
} }
// 2. compile the libraries, outputting .o files to: // 2. compile the libraries, outputting .o files to:
// <buildPath>/<library>/ // <buildPath>/<library>/
void compileLibraries(List<String> includePaths) throws RunnerException { void compileLibraries(List<File> includeFolders) throws RunnerException {
for (Library lib : sketch.getImportedLibraries()) { for (Library lib : sketch.getImportedLibraries()) {
compileLibrary(lib, includePaths); compileLibrary(lib, includeFolders);
} }
} }
private void compileLibrary(Library lib, List<String> includePaths) private void compileLibrary(Library lib, List<File> includeFolders)
throws RunnerException { throws RunnerException {
File libFolder = lib.getSrcFolder(); 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()) { if (lib.useRecursion()) {
// libBuildFolder == {build.path}/LibName // libBuildFolder == {build.path}/LibName
// libFolder == {lib.path}/src // libFolder == {lib.path}/src
recursiveCompileFilesInFolder(libBuildFolder, libFolder, includePaths); recursiveCompileFilesInFolder(libBuildFolder, libFolder, includeFolders);
} else { } else {
// libFolder == {lib.path}/ // libFolder == {lib.path}/
@ -637,26 +629,26 @@ public class Compiler implements MessageConsumer {
File utilityFolder = new File(libFolder, "utility"); File utilityFolder = new File(libFolder, "utility");
File utilityBuildFolder = new File(libBuildFolder, "utility"); File utilityBuildFolder = new File(libBuildFolder, "utility");
includePaths.add(utilityFolder.getAbsolutePath()); includeFolders.add(utilityFolder);
compileFilesInFolder(libBuildFolder, libFolder, includePaths); compileFilesInFolder(libBuildFolder, libFolder, includeFolders);
compileFilesInFolder(utilityBuildFolder, utilityFolder, includePaths); compileFilesInFolder(utilityBuildFolder, utilityFolder, includeFolders);
// other libraries should not see this library's utility/ folder // 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<String> includePaths) throws RunnerException { private void recursiveCompileFilesInFolder(File srcBuildFolder, File srcFolder, List<File> includeFolders) throws RunnerException {
compileFilesInFolder(srcBuildFolder, srcFolder, includePaths); compileFilesInFolder(srcBuildFolder, srcFolder, includeFolders);
for (File subFolder : srcFolder.listFiles(new OnlyDirs())) { for (File subFolder : srcFolder.listFiles(new OnlyDirs())) {
File subBuildFolder = new File(srcBuildFolder, subFolder.getName()); File subBuildFolder = new File(srcBuildFolder, subFolder.getName());
recursiveCompileFilesInFolder(subBuildFolder, subFolder, includePaths); recursiveCompileFilesInFolder(subBuildFolder, subFolder, includeFolders);
} }
} }
private void compileFilesInFolder(File buildFolder, File srcFolder, List<String> includePaths) throws RunnerException { private void compileFilesInFolder(File buildFolder, File srcFolder, List<File> includeFolders) throws RunnerException {
createFolder(buildFolder); createFolder(buildFolder);
List<File> objects = compileFiles(buildFolder.getAbsolutePath(), srcFolder, false, includePaths); List<File> objects = compileFiles(buildFolder, srcFolder, false, includeFolders);
objectFiles.addAll(objects); objectFiles.addAll(objects);
} }
@ -665,22 +657,22 @@ public class Compiler implements MessageConsumer {
void compileCore() void compileCore()
throws RunnerException { throws RunnerException {
String corePath = prefs.get("build.core.path"); File coreFolder = prefs.getFile("build.core.path");
String variantPath = prefs.get("build.variant.path"); File variantFolder = prefs.getFile("build.variant.path");
String buildPath = prefs.get("build.path"); File buildFolder = prefs.getFile("build.path");
List<String> includePaths = new ArrayList<String>(); List<File> includeFolders = new ArrayList<File>();
includePaths.add(corePath); // include core path only includeFolders.add(coreFolder); // include core path only
if (variantPath.length() != 0) if (variantFolder != null)
includePaths.add(variantPath); includeFolders.add(variantFolder);
List<File> coreObjectFiles = compileFiles(buildPath, new File(corePath), List<File> objectFiles = compileFiles(buildFolder, coreFolder, true,
true, includePaths); includeFolders);
if (variantPath.length() != 0) if (variantFolder != null)
coreObjectFiles.addAll(compileFiles(buildPath, new File(variantPath), objectFiles.addAll(compileFiles(buildFolder, variantFolder, true,
true, includePaths)); includeFolders));
for (File file : coreObjectFiles) { for (File file : objectFiles) {
PreferencesMap dict = new PreferencesMap(prefs); PreferencesMap dict = new PreferencesMap(prefs);
dict.put("ide_version", "" + Base.REVISION); dict.put("ide_version", "" + Base.REVISION);
@ -699,7 +691,7 @@ public class Compiler implements MessageConsumer {
} }
// 4. link it all together into the .elf file // 4. link it all together into the .elf file
void compileLink(List<String> includePaths) void compileLink()
throws RunnerException { throws RunnerException {
// TODO: Make the --relax thing in configuration files. // TODO: Make the --relax thing in configuration files.
@ -733,7 +725,7 @@ public class Compiler implements MessageConsumer {
} }
// 5. extract EEPROM data (from EEMEM directive) to .eep file. // 5. extract EEPROM data (from EEMEM directive) to .eep file.
void compileEep(List<String> includePaths) throws RunnerException { void compileEep() throws RunnerException {
PreferencesMap dict = new PreferencesMap(prefs); PreferencesMap dict = new PreferencesMap(prefs);
dict.put("ide_version", "" + Base.REVISION); dict.put("ide_version", "" + Base.REVISION);
@ -748,7 +740,7 @@ public class Compiler implements MessageConsumer {
} }
// 6. build the .hex file // 6. build the .hex file
void compileHex(List<String> includePaths) throws RunnerException { void compileHex() throws RunnerException {
PreferencesMap dict = new PreferencesMap(prefs); PreferencesMap dict = new PreferencesMap(prefs);
dict.put("ide_version", "" + Base.REVISION); dict.put("ide_version", "" + Base.REVISION);
@ -762,10 +754,10 @@ public class Compiler implements MessageConsumer {
execAsynchronously(cmdArray); execAsynchronously(cmdArray);
} }
private static String preparePaths(List<String> includePaths) { private static String prepareIncludes(List<File> includeFolders) {
String res = ""; String res = "";
for (String p : includePaths) for (File p : includeFolders)
res += " \"-I" + p + '"'; res += " \"-I" + p.getAbsolutePath() + '"';
// Remove first space // Remove first space
return res.substring(1); return res.substring(1);

View File

@ -265,4 +265,37 @@ public class PreferencesMap extends LinkedHashMap<String, String> {
public String toString() { public String toString() {
return 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 <b>null</b>.
*
* @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 <b>null</b>.
*
* @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);
}
} }