1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-03-13 10:29:35 +01:00

Compilation speed-up patch (only compile modify files). (Paul Stoffregen)

http://code.google.com/p/arduino/issues/detail?id=638
This commit is contained in:
David A. Mellis 2011-12-16 18:20:22 -05:00
parent b8fbffeac4
commit b0ae6e764d
3 changed files with 110 additions and 6 deletions

View File

@ -1010,6 +1010,7 @@ public class Base {
Preferences.set("target", (String) getValue("target"));
Preferences.set("board", (String) getValue("board"));
onBoardOrPortChange();
Sketch.buildSettingChanged();
}
};
action.putValue("target", target.getName());

View File

@ -1246,6 +1246,12 @@ public class Sketch {
*/
//protected String compile() throws RunnerException {
// called when any setting changes that requires all files to be recompiled
public static void buildSettingChanged() {
deleteFilesOnNextBuild = true;
}
private static boolean deleteFilesOnNextBuild = true;
/**
* When running from the editor, take care of preparations before running
@ -1620,9 +1626,29 @@ public class Sketch {
}
File appletFolder = new File(appletPath);
// Nuke the old applet folder because it can cause trouble
if (Preferences.getBoolean("export.delete_target_folder")) {
String use_dep = Base.getBoardPreferences().get("build.dependency");
if (use_dep == null || use_dep.compareToIgnoreCase("true") != 0 || deleteFilesOnNextBuild) {
// delete the entire directory and all contents
// when we know something changed and all objects
// need to be recompiled, or if the board does not
// use setting build.dependency
Base.removeDir(appletFolder);
deleteFilesOnNextBuild = false;
} else {
// delete only stale source files, from the previously
// compiled sketch. This allows multiple windows to be
// used. Keep everything else, which might be reusable
if (appletFolder.exists()) {
String files[] = appletFolder.list();
for (String file : files) {
if (file.endsWith(".c") || file.endsWith(".cpp") || file.endsWith(".s")) {
File deleteMe = new File(appletFolder, file);
if (!deleteMe.delete()) {
System.err.println("Could not delete " + deleteMe);
}
}
}
}
}
// Create a fresh applet folder (needed before preproc is run below)
appletFolder.mkdirs();

View File

@ -269,7 +269,11 @@ public class Compiler implements MessageConsumer {
for (File file : cSources) {
String objectPath = buildPath + File.separator + file.getName() + ".o";
objectPaths.add(new File(objectPath));
String dependPath = buildPath + File.separator + file.getName() + ".d";
File objectFile = new File(objectPath);
File dependFile = new File(dependPath);
objectPaths.add(objectFile);
if (is_already_compiled(file, objectFile, dependFile, boardPreferences)) continue;
execAsynchronously(getCommandCompilerC(avrBasePath, includePaths,
file.getAbsolutePath(),
objectPath,
@ -278,7 +282,11 @@ public class Compiler implements MessageConsumer {
for (File file : cppSources) {
String objectPath = buildPath + File.separator + file.getName() + ".o";
objectPaths.add(new File(objectPath));
String dependPath = buildPath + File.separator + file.getName() + ".d";
File objectFile = new File(objectPath);
File dependFile = new File(dependPath);
objectPaths.add(objectFile);
if (is_already_compiled(file, objectFile, dependFile, boardPreferences)) continue;
execAsynchronously(getCommandCompilerCPP(avrBasePath, includePaths,
file.getAbsolutePath(),
objectPath,
@ -288,6 +296,71 @@ public class Compiler implements MessageConsumer {
return objectPaths;
}
private boolean is_already_compiled(File src, File obj, File dep, Map<String, String> prefs) {
String build_dep = prefs.get("build.dependency");
if (build_dep == null) return false;
if (build_dep.compareToIgnoreCase("true") != 0) return false;
boolean ret=true;
try {
//System.out.println("\n is_already_compiled: begin checks: " + obj.getPath());
if (!obj.exists()) return false; // object file (.o) does not exist
if (!dep.exists()) return false; // dep file (.d) does not exist
long src_modified = src.lastModified();
long obj_modified = obj.lastModified();
if (src_modified >= obj_modified) return false; // source modified since object compiled
if (src_modified >= dep.lastModified()) return false; // src modified since dep compiled
BufferedReader reader = new BufferedReader(new FileReader(dep.getPath()));
String line;
boolean need_obj_parse = true;
while ((line = reader.readLine()) != null) {
if (line.endsWith("\\")) {
line = line.substring(0, line.length() - 1);
}
line = line.trim();
if (line.length() == 0) continue; // ignore blank lines
if (need_obj_parse) {
// line is supposed to be the object file - make sure it really is!
if (line.endsWith(":")) {
line = line.substring(0, line.length() - 1);
String objpath = obj.getCanonicalPath();
File linefile = new File(line);
String linepath = linefile.getCanonicalPath();
//System.out.println(" is_already_compiled: obj = " + objpath);
//System.out.println(" is_already_compiled: line = " + linepath);
if (objpath.compareTo(linepath) == 0) {
need_obj_parse = false;
continue;
} else {
ret = false; // object named inside .d file is not the correct file!
break;
}
} else {
ret = false; // object file supposed to end with ':', but didn't
break;
}
} else {
// line is a prerequisite file
File prereq = new File(line);
if (!prereq.exists()) {
ret = false; // prerequisite file did not exist
break;
}
if (prereq.lastModified() >= obj_modified) {
ret = false; // prerequisite modified since object was compiled
break;
}
//System.out.println(" is_already_compiled: prerequisite ok");
}
}
reader.close();
} catch (Exception e) {
return false; // any error reading dep file = recompile it
}
if (ret && (verbose || Preferences.getBoolean("build.verbose"))) {
System.out.println(" Using previously compiled: " + obj.getPath());
}
return ret;
}
boolean firstErrorFound;
boolean secondErrorFound;
@ -490,6 +563,7 @@ public class Compiler implements MessageConsumer {
"-fdata-sections",
"-mmcu=" + boardPreferences.get("build.mcu"),
"-DF_CPU=" + boardPreferences.get("build.f_cpu"),
"-MMD", // output dependancy info
"-DARDUINO=" + Base.REVISION,
}));
@ -498,7 +572,8 @@ public class Compiler implements MessageConsumer {
}
baseCommandCompiler.add(sourceName);
baseCommandCompiler.add("-o"+ objectName);
baseCommandCompiler.add("-o");
baseCommandCompiler.add(objectName);
return baseCommandCompiler;
}
@ -519,6 +594,7 @@ public class Compiler implements MessageConsumer {
"-fdata-sections",
"-mmcu=" + boardPreferences.get("build.mcu"),
"-DF_CPU=" + boardPreferences.get("build.f_cpu"),
"-MMD", // output dependancy info
"-DARDUINO=" + Base.REVISION,
}));
@ -527,7 +603,8 @@ public class Compiler implements MessageConsumer {
}
baseCommandCompilerCPP.add(sourceName);
baseCommandCompilerCPP.add("-o"+ objectName);
baseCommandCompilerCPP.add("-o");
baseCommandCompilerCPP.add(objectName);
return baseCommandCompilerCPP;
}