@@ -408,13 +408,17 @@ class swift::ParseableInterfaceBuilder {
408
408
StringRef DepName = Scratch.str ();
409
409
410
410
assert (moduleCachePath.empty () || !DepName.startswith (moduleCachePath));
411
- assert (prebuiltCachePath.empty () || !DepName.startswith (prebuiltCachePath));
412
411
413
412
// Serialize the paths of dependencies in the SDK relative to it.
414
413
Optional<StringRef> SDKRelativePath = getRelativeDepPath (DepName, SDKPath);
415
414
StringRef DepNameToStore = SDKRelativePath.getValueOr (DepName);
416
415
bool IsSDKRelative = SDKRelativePath.hasValue ();
417
416
417
+ // Forwarding modules add the underlying prebuilt module to their
418
+ // dependency list -- don't serialize that.
419
+ if (!prebuiltCachePath.empty () && DepName.startswith (prebuiltCachePath))
420
+ continue ;
421
+
418
422
if (AllDepNames.insert (DepName).second && dependencyTracker) {
419
423
dependencyTracker->addDependency (DepName, /* isSystem*/ IsSDKRelative);
420
424
}
@@ -828,6 +832,10 @@ class ParseableInterfaceModuleLoaderImpl {
828
832
}
829
833
path::append (scratch, path::filename (modulePath));
830
834
835
+ // If there isn't a file at this location, skip returning a path.
836
+ if (!fs.exists (scratch))
837
+ return None;
838
+
831
839
return scratch.str ();
832
840
}
833
841
@@ -914,7 +922,7 @@ class ParseableInterfaceModuleLoaderImpl {
914
922
return DiscoveredModule::prebuilt (*path, std::move (moduleBuffer));
915
923
} else {
916
924
LLVM_DEBUG (llvm::dbgs () << " Found out-of-date prebuilt module at "
917
- << modulePath << " \n " );
925
+ << path-> str () << " \n " );
918
926
}
919
927
}
920
928
}
@@ -951,40 +959,62 @@ class ParseableInterfaceModuleLoaderImpl {
951
959
952
960
// / Writes the "forwarding module" that will forward to a module in the
953
961
// / prebuilt cache.
962
+ // /
954
963
// / Since forwarding modules track dependencies separately from the module
955
964
// / they point to, we'll need to grab the up-to-date file status while doing
956
- // / this.
957
- bool writeForwardingModule (const DiscoveredModule &mod,
958
- StringRef outputPath,
959
- ArrayRef<FileDependency> deps) {
965
+ // / this. If the write was successful, it also updates the
966
+ // / list of dependencies to match what was written to the forwarding file.
967
+ bool writeForwardingModuleAndUpdateDeps (
968
+ const DiscoveredModule &mod, StringRef outputPath,
969
+ SmallVectorImpl<FileDependency> &deps) {
960
970
assert (mod.isPrebuilt () &&
961
971
" cannot write forwarding file for non-prebuilt module" );
962
972
ForwardingModule fwd (mod.path );
963
973
974
+ SmallVector<FileDependency, 16 > depsAdjustedToMTime;
975
+
964
976
// FIXME: We need to avoid re-statting all these dependencies, otherwise
965
977
// we may record out-of-date information.
966
- auto addDependency = [&](StringRef path) {
978
+ auto addDependency = [&](StringRef path) -> FileDependency {
967
979
auto status = fs.status (path);
968
980
uint64_t mtime =
969
981
status->getLastModificationTime ().time_since_epoch ().count ();
970
982
fwd.addDependency (path, status->getSize (), mtime);
983
+
984
+ // Construct new FileDependency matching what we've added to the
985
+ // forwarding module. This is no longer SDK-relative because the absolute
986
+ // path has already been resolved.
987
+ return FileDependency::modTimeBased (path, /* isSDKRelative*/ false ,
988
+ status->getSize (), mtime);
971
989
};
972
990
973
- // Add the prebuilt module as a dependency of the forwarding module.
974
- addDependency (fwd.underlyingModulePath );
991
+ // Add the prebuilt module as a dependency of the forwarding module, but
992
+ // don't add it to the outer dependency list.
993
+ (void )addDependency (fwd.underlyingModulePath );
975
994
976
- // Add all the dependencies from the prebuilt module.
995
+ // Add all the dependencies from the prebuilt module, and update our list
996
+ // of dependencies to reflect what's recorded in the forwarding module.
977
997
SmallString<128 > SDKRelativeBuffer;
978
998
for (auto dep : deps) {
979
- addDependency (getFullDependencyPath (dep, SDKRelativeBuffer));
999
+ auto adjustedDep =
1000
+ addDependency (getFullDependencyPath (dep, SDKRelativeBuffer));
1001
+ depsAdjustedToMTime.push_back (adjustedDep);
980
1002
}
981
1003
982
- return withOutputFile (diags, outputPath,
1004
+ auto hadError = withOutputFile (diags, outputPath,
983
1005
[&](llvm::raw_pwrite_stream &out) {
984
1006
llvm::yaml::Output yamlWriter (out);
985
1007
yamlWriter << fwd;
986
1008
return false ;
987
1009
});
1010
+
1011
+ if (hadError)
1012
+ return true ;
1013
+
1014
+ // If and only if we succeeded writing the forwarding file, update the
1015
+ // provided list of dependencies.
1016
+ deps = depsAdjustedToMTime;
1017
+ return false ;
988
1018
}
989
1019
990
1020
// / Looks up the best module to load for a given interface, and returns a
@@ -1033,9 +1063,11 @@ class ParseableInterfaceModuleLoaderImpl {
1033
1063
if (moduleOrErr) {
1034
1064
auto module = std::move (moduleOrErr.get ());
1035
1065
1036
- // If it's prebuilt, use this time to generate a forwarding module.
1066
+ // If it's prebuilt, use this time to generate a forwarding module and
1067
+ // update the dependencies to use modification times.
1037
1068
if (module.isPrebuilt ())
1038
- if (writeForwardingModule (module, cachedOutputPath, allDeps))
1069
+ if (writeForwardingModuleAndUpdateDeps (module, cachedOutputPath,
1070
+ allDeps))
1039
1071
return std::make_error_code (std::errc::not_supported);
1040
1072
1041
1073
// Report the module's dependencies to the dependencyTracker
0 commit comments