summaryrefslogtreecommitdiff
path: root/chapter28b/src/main/java/com
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-25 14:24:09 -0700
committerCliff Click <cliffc@acm.org>2026-10-25 14:24:09 -0700
commit0e7c50b22d7f900b9c3c8db3765f3b7af41e5dd1 (patch)
tree6bfc8e100d1e1a727fdeabbc8dcf0710d04ff29b /chapter28b/src/main/java/com
parent2d80a348bad4b1e3165bd955ceaff3e18a96e516 (diff)
downloadSimple-main.tar.gz
Simple-main.zip
Update incremental build checkmain
Diffstat (limited to 'chapter28b/src/main/java/com')
-rw-r--r--chapter28b/src/main/java/com/seaofnodes/simple/codegen/CompUnit.java42
-rw-r--r--chapter28b/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java10
2 files changed, 38 insertions, 14 deletions
diff --git a/chapter28b/src/main/java/com/seaofnodes/simple/codegen/CompUnit.java b/chapter28b/src/main/java/com/seaofnodes/simple/codegen/CompUnit.java
index 71126795..8b303008 100644
--- a/chapter28b/src/main/java/com/seaofnodes/simple/codegen/CompUnit.java
+++ b/chapter28b/src/main/java/com/seaofnodes/simple/codegen/CompUnit.java
@@ -60,7 +60,7 @@ public class CompUnit {
( fname.equals(CODE._srcName) || // Explicit input is a compilation request
!_obj.exists() || // No object file
_smp.lastModified() > _obj.lastModified() || // Out-of-date with source?
- checkDependentObjs() ); // Out-of-date with other objs?
+ !current(_obj,new HashSet<>()) ); // Out-of-date anywhere in its inputs?
_src = mustCompile ? new String(Files.readAllBytes(_smp.toPath())) : null;
}
@@ -101,16 +101,42 @@ public class CompUnit {
_src = null;
}
- // Return true if _obj is out-of-date relative to dependents.
- private boolean checkDependentObjs() {
- ElfReader elf = CODE.getElf(_obj);
+ // Check source-backed inputs before importing any saved types or IR.
+ // A dependency's source can be newer while its object is unchanged.
+ // Use a fresh visited set for each root: encountering a cycle is safe, but
+ // caching a provisional "current" answer from inside it would not be.
+ private static boolean current(File obj, HashSet<File> visit) {
+ if( obj==null || !obj.isFile() ) return false;
+ if( !visit.add(obj.getAbsoluteFile()) ) return true;
+ ElfReader elf = CODE.getElf(obj);
+ if( elf==null ) return false;
elf.loadPublicSymbols();
+ if( elf._units==null ) return false;
+ long time = obj.lastModified();
+ for( String unit : elf._units ) {
+ // Never import another copy of a unit explicitly being compiled.
+ CompUnit cu = CODE._compunits.get(unit);
+ if( unit.equals(CODE._srcName) || (cu!=null && cu._src!=null) ) return false;
+ File src = new File(CODE._modDir+"/"+unit+".smp");
+ if( !src.isFile() || src.lastModified()>time ) return false;
+ }
for( String dep : elf._deps ) {
- File obj = new File(CODE._buildDir+"/"+dep+".o");
- if( obj.lastModified() > _obj.lastModified() ) // Out-of-date with deps?
- return true;
+ if( Arrays.asList(elf._units).contains(dep) ) continue; // Owned by this object.
+ File file = dependencyObj(dep,true);
+ if( file==null || !file.isFile() || file.lastModified()>time ) return false;
+ // Object-only libraries are supplied as a coherent build. Their
+ // input versions cannot be inferred from installation timestamps.
+ if( file.equals(new File(CODE._buildDir+"/"+dep+".o")) && !current(file,visit) ) return false;
}
- return false;
+ return true;
+ }
+
+ // Resolve dependencies the same way for freshness checks and actual loads.
+ static File dependencyObj(String fname, boolean local) {
+ File obj = new File(CODE._buildDir+"/"+fname+".o");
+ if( local && (obj.isFile() || new File(CODE._modDir+"/"+fname+".smp").isFile()) ) return obj;
+ ElfReader elf = CODE.findExternalSimple(Parser.addClzPrefix(fname.replace('/','.')));
+ return elf==null ? null : elf._file;
}
// Add a discovered dependency, for later writing out in an ELF file, ".simple" section
diff --git a/chapter28b/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java b/chapter28b/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java
index c55f9a90..d7c0f7e2 100644
--- a/chapter28b/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java
+++ b/chapter28b/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java
@@ -258,12 +258,10 @@ public abstract class ParseAll {
}
private static File depObj(CodeGen code, CompUnit cunit, String fname) {
- if( cunit._smp != null )
- return null;
- ElfReader elf = code.findExternalSimple(Parser.addClzPrefix(fname.replace('/','.')));
- if( elf == null )
- throw new RuntimeException("Cannot find external Simple dependency '"+fname+"'");
- return elf._file;
+ File obj = CompUnit.dependencyObj(fname,cunit._smp!=null);
+ if( obj == null )
+ throw new RuntimeException("Cannot find Simple dependency '"+fname+"'");
+ return cunit._smp!=null && obj.equals(new File(code._buildDir+"/"+fname+".o")) ? null : obj;
}
private static File externalObj(CodeGen code, CompUnit par, String name) {