From 57bdacc93c99116dc6b21387e2e1a1ba43aeb76c Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 10 Apr 2014 14:47:36 +0200 Subject: [PATCH 1/3] Remove core.a before rebuilding it Before, the ar command was just ran for all .o files that should end up in core.a, which should replace any old code in core.a. However, it seems that in the unlikely event that functions or entire source files are deleted, they might linger in the core.a file. --- app/src/processing/app/debug/Compiler.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 8a38db7e9..29575b08f 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -703,13 +703,19 @@ public class Compiler implements MessageConsumer { if (variantFolder != null) includeFolders.add(variantFolder); + File afile = new File(buildFolder, "core.a"); + List coreObjectFiles = compileFiles(buildFolder, coreFolder, true, includeFolders); + + // Delete the .a file, to prevent any previous code from lingering + afile.delete(); + for (File file : coreObjectFiles) { PreferencesMap dict = new PreferencesMap(prefs); dict.put("ide_version", "" + Base.REVISION); - dict.put("archive_file", "core.a"); + dict.put("archive_file", afile.getName()); dict.put("object_file", file.getAbsolutePath()); String[] cmdArray; From 87c87c28971c4bf463697fe99f6130735f1cdcbe Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 10 Apr 2014 14:53:05 +0200 Subject: [PATCH 2/3] Delete core.a when building it fails This prevents a half-finished core.a file from lingering around. Currently, this should not make a difference since core.a is rebuilt every time, but this prepares for skipping this build step if possible. --- app/src/processing/app/debug/Compiler.java | 29 +++++++++++++--------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 29575b08f..ba144a7ba 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -711,21 +711,26 @@ public class Compiler implements MessageConsumer { // Delete the .a file, to prevent any previous code from lingering afile.delete(); - for (File file : coreObjectFiles) { + try { + for (File file : coreObjectFiles) { - PreferencesMap dict = new PreferencesMap(prefs); - dict.put("ide_version", "" + Base.REVISION); - dict.put("archive_file", afile.getName()); - dict.put("object_file", file.getAbsolutePath()); + PreferencesMap dict = new PreferencesMap(prefs); + dict.put("ide_version", "" + Base.REVISION); + dict.put("archive_file", afile.getName()); + dict.put("object_file", file.getAbsolutePath()); - String[] cmdArray; - try { - String cmd = prefs.get("recipe.ar.pattern"); - cmdArray = StringReplacer.formatAndSplit(cmd, dict, true); - } catch (Exception e) { - throw new RunnerException(e); + String[] cmdArray; + try { + String cmd = prefs.get("recipe.ar.pattern"); + cmdArray = StringReplacer.formatAndSplit(cmd, dict, true); + } catch (Exception e) { + throw new RunnerException(e); + } + execAsynchronously(cmdArray); } - execAsynchronously(cmdArray); + } catch (RunnerException e) { + afile.delete(); + throw e; } if (variantFolder != null) From b78339238d782971a0e40445171b08edad8f7194 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 10 Apr 2014 15:35:11 +0200 Subject: [PATCH 3/3] Don't recompile core.a if none of the .o files changed Before, core.a would be rebuilt on every build, even when none of the core .o files changed. Now, the timestamps are checked against the timestamp on core.a first, skipping the build if nothing changed. Because this uses the current list of .o files, there is a corner case when a source file is deleted, but no other source file is modified. In that case, core.a is not rebuilt, even though it should be. However, this is such a narrow and unrealistic case, that it should pose a real problem. This fixes part of #1991 --- app/src/processing/app/debug/Compiler.java | 32 +++++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index ba144a7ba..c16fef296 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -703,11 +703,39 @@ public class Compiler implements MessageConsumer { if (variantFolder != null) includeFolders.add(variantFolder); + + if (variantFolder != null) + objectFiles.addAll(compileFiles(buildFolder, variantFolder, true, + includeFolders)); + File afile = new File(buildFolder, "core.a"); List coreObjectFiles = compileFiles(buildFolder, coreFolder, true, includeFolders); + // See if the .a file is already uptodate + if (afile.exists()) { + boolean changed = false; + for (File file : coreObjectFiles) { + if (file.lastModified() > afile.lastModified()) { + changed = true; + break; + } + } + + // If none of the object files is newer than the .a file, don't + // bother rebuilding the .a file. There is a small corner case + // here: If a source file was removed, but no other source file + // was modified, this will not rebuild core.a even when it + // should. It's hard to fix and not a realistic case, so it + // shouldn't be a problem. + if (!changed) { + if (verbose) + System.out.println(I18n.format(_("Using previously compiled file: {0}"), afile.getPath())); + return; + } + } + // Delete the .a file, to prevent any previous code from lingering afile.delete(); @@ -732,10 +760,6 @@ public class Compiler implements MessageConsumer { afile.delete(); throw e; } - - if (variantFolder != null) - objectFiles.addAll(compileFiles(buildFolder, variantFolder, true, - includeFolders)); } // 4. link it all together into the .elf file