mirror of
https://github.com/arduino/Arduino.git
synced 2025-03-14 11:29:26 +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:
parent
b8fbffeac4
commit
b0ae6e764d
@ -1010,6 +1010,7 @@ public class Base {
|
|||||||
Preferences.set("target", (String) getValue("target"));
|
Preferences.set("target", (String) getValue("target"));
|
||||||
Preferences.set("board", (String) getValue("board"));
|
Preferences.set("board", (String) getValue("board"));
|
||||||
onBoardOrPortChange();
|
onBoardOrPortChange();
|
||||||
|
Sketch.buildSettingChanged();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
action.putValue("target", target.getName());
|
action.putValue("target", target.getName());
|
||||||
|
@ -1246,6 +1246,12 @@ public class Sketch {
|
|||||||
*/
|
*/
|
||||||
//protected String compile() throws RunnerException {
|
//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
|
* When running from the editor, take care of preparations before running
|
||||||
@ -1620,9 +1626,29 @@ public class Sketch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
File appletFolder = new File(appletPath);
|
File appletFolder = new File(appletPath);
|
||||||
// Nuke the old applet folder because it can cause trouble
|
String use_dep = Base.getBoardPreferences().get("build.dependency");
|
||||||
if (Preferences.getBoolean("export.delete_target_folder")) {
|
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);
|
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)
|
// Create a fresh applet folder (needed before preproc is run below)
|
||||||
appletFolder.mkdirs();
|
appletFolder.mkdirs();
|
||||||
|
@ -269,7 +269,11 @@ public class Compiler implements MessageConsumer {
|
|||||||
|
|
||||||
for (File file : cSources) {
|
for (File file : cSources) {
|
||||||
String objectPath = buildPath + File.separator + file.getName() + ".o";
|
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,
|
execAsynchronously(getCommandCompilerC(avrBasePath, includePaths,
|
||||||
file.getAbsolutePath(),
|
file.getAbsolutePath(),
|
||||||
objectPath,
|
objectPath,
|
||||||
@ -278,7 +282,11 @@ public class Compiler implements MessageConsumer {
|
|||||||
|
|
||||||
for (File file : cppSources) {
|
for (File file : cppSources) {
|
||||||
String objectPath = buildPath + File.separator + file.getName() + ".o";
|
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,
|
execAsynchronously(getCommandCompilerCPP(avrBasePath, includePaths,
|
||||||
file.getAbsolutePath(),
|
file.getAbsolutePath(),
|
||||||
objectPath,
|
objectPath,
|
||||||
@ -288,6 +296,71 @@ public class Compiler implements MessageConsumer {
|
|||||||
return objectPaths;
|
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 firstErrorFound;
|
||||||
boolean secondErrorFound;
|
boolean secondErrorFound;
|
||||||
@ -490,6 +563,7 @@ public class Compiler implements MessageConsumer {
|
|||||||
"-fdata-sections",
|
"-fdata-sections",
|
||||||
"-mmcu=" + boardPreferences.get("build.mcu"),
|
"-mmcu=" + boardPreferences.get("build.mcu"),
|
||||||
"-DF_CPU=" + boardPreferences.get("build.f_cpu"),
|
"-DF_CPU=" + boardPreferences.get("build.f_cpu"),
|
||||||
|
"-MMD", // output dependancy info
|
||||||
"-DARDUINO=" + Base.REVISION,
|
"-DARDUINO=" + Base.REVISION,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -498,7 +572,8 @@ public class Compiler implements MessageConsumer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
baseCommandCompiler.add(sourceName);
|
baseCommandCompiler.add(sourceName);
|
||||||
baseCommandCompiler.add("-o"+ objectName);
|
baseCommandCompiler.add("-o");
|
||||||
|
baseCommandCompiler.add(objectName);
|
||||||
|
|
||||||
return baseCommandCompiler;
|
return baseCommandCompiler;
|
||||||
}
|
}
|
||||||
@ -519,6 +594,7 @@ public class Compiler implements MessageConsumer {
|
|||||||
"-fdata-sections",
|
"-fdata-sections",
|
||||||
"-mmcu=" + boardPreferences.get("build.mcu"),
|
"-mmcu=" + boardPreferences.get("build.mcu"),
|
||||||
"-DF_CPU=" + boardPreferences.get("build.f_cpu"),
|
"-DF_CPU=" + boardPreferences.get("build.f_cpu"),
|
||||||
|
"-MMD", // output dependancy info
|
||||||
"-DARDUINO=" + Base.REVISION,
|
"-DARDUINO=" + Base.REVISION,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -527,7 +603,8 @@ public class Compiler implements MessageConsumer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
baseCommandCompilerCPP.add(sourceName);
|
baseCommandCompilerCPP.add(sourceName);
|
||||||
baseCommandCompilerCPP.add("-o"+ objectName);
|
baseCommandCompilerCPP.add("-o");
|
||||||
|
baseCommandCompilerCPP.add(objectName);
|
||||||
|
|
||||||
return baseCommandCompilerCPP;
|
return baseCommandCompilerCPP;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user