@@ -368,6 +368,8 @@ class swift::ParseableInterfaceBuilder {
368368 bool collectDepsForSerialization (CompilerInstance &SubInstance,
369369 SmallVectorImpl<FileDependency> &Deps,
370370 bool IsHashBased) {
371+ StringRef SDKPath = SubInstance.getASTContext ().SearchPathOpts .SDKPath ;
372+
371373 auto DTDeps = SubInstance.getDependencyTracker ()->getDependencies ();
372374 SmallVector<StringRef, 16 > InitialDepNames (DTDeps.begin (), DTDeps.end ());
373375 InitialDepNames.push_back (interfacePath);
@@ -396,17 +398,39 @@ class swift::ParseableInterfaceBuilder {
396398 if (!Status)
397399 return true ;
398400
401+ bool IsSDKRelative = false ;
402+ StringRef DepNameToStore = DepName;
403+ if (SDKPath.size () > 1 && DepName.startswith (SDKPath)) {
404+ assert (DepName.size () > SDKPath.size () &&
405+ " should never depend on a directory" );
406+ if (llvm::sys::path::is_separator (DepName[SDKPath.size ()])) {
407+ // Is the DepName something like ${SDKPath}/foo.h"?
408+ DepNameToStore = DepName.substr (SDKPath.size () + 1 );
409+ IsSDKRelative = true ;
410+ } else if (llvm::sys::path::is_separator (SDKPath.back ())) {
411+ // Is the DepName something like "${SDKPath}foo.h", where SDKPath
412+ // itself contains a trailing slash?
413+ DepNameToStore = DepName.substr (SDKPath.size ());
414+ IsSDKRelative = true ;
415+ } else {
416+ // We have something next to an SDK, like "Foo.sdk.h", that's somehow
417+ // become a dependency.
418+ }
419+ }
420+
399421 if (IsHashBased) {
400422 auto buf = getDepBuf ();
401423 if (!buf) return true ;
402424 uint64_t hash = xxHash64 (buf->getBuffer ());
403425 Deps.push_back (
404- FileDependency::hashBased (DepName, Status->getSize (), hash));
426+ FileDependency::hashBased (DepNameToStore, IsSDKRelative,
427+ Status->getSize (), hash));
405428 } else {
406429 uint64_t mtime =
407430 Status->getLastModificationTime ().time_since_epoch ().count ();
408431 Deps.push_back (
409- FileDependency::modTimeBased (DepName, Status->getSize (), mtime));
432+ FileDependency::modTimeBased (DepNameToStore, IsSDKRelative,
433+ Status->getSize (), mtime));
410434 }
411435
412436 if (moduleCachePath.empty ())
@@ -681,10 +705,23 @@ class ParseableInterfaceModuleLoaderImpl {
681705 OutPath.append (OutExt);
682706 }
683707
708+ // / Constructs the full path of the dependency \p dep by prepending the SDK
709+ // / path if necessary.
710+ StringRef getFullDependencyPath (const FileDependency &dep,
711+ SmallVectorImpl<char > &scratch) const {
712+ if (!dep.isSDKRelative ())
713+ return dep.getPath ();
714+
715+ StringRef SDKPath = ctx.SearchPathOpts .SDKPath ;
716+ scratch.assign (SDKPath.begin (), SDKPath.end ());
717+ llvm::sys::path::append (scratch, dep.getPath ());
718+ return StringRef (scratch.data (), scratch.size ());
719+ }
720+
684721 // Checks that a dependency read from the cached module is up to date compared
685722 // to the interface file it represents.
686- bool dependencyIsUpToDate (const FileDependency &dep) {
687- auto status = getStatusOfDependency (fs, dep. getPath () , interfacePath,
723+ bool dependencyIsUpToDate (const FileDependency &dep, StringRef fullPath ) {
724+ auto status = getStatusOfDependency (fs, fullPath , interfacePath,
688725 diags, diagnosticLoc);
689726 if (!status) return false ;
690727
@@ -701,7 +738,7 @@ class ParseableInterfaceModuleLoaderImpl {
701738
702739 // Slow path: if the dependency is verified by content hash, check it vs.
703740 // the hash of the file.
704- auto buf = getBufferOfDependency (fs, dep. getPath () , interfacePath,
741+ auto buf = getBufferOfDependency (fs, fullPath , interfacePath,
705742 diags, diagnosticLoc);
706743 if (!buf) return false ;
707744
@@ -711,10 +748,12 @@ class ParseableInterfaceModuleLoaderImpl {
711748 // Check if all the provided file dependencies are up-to-date compared to
712749 // what's currently on disk.
713750 bool dependenciesAreUpToDate (ArrayRef<FileDependency> deps) {
751+ SmallString<128 > SDKRelativeBuffer;
714752 for (auto &in : deps) {
753+ StringRef fullPath = getFullDependencyPath (in, SDKRelativeBuffer);
715754 if (dependencyTracker)
716- dependencyTracker->addDependency (in. getPath () , /* isSystem*/ false );
717- if (!dependencyIsUpToDate (in)) {
755+ dependencyTracker->addDependency (fullPath , /* isSystem*/ in. isSDKRelative () );
756+ if (!dependencyIsUpToDate (in, fullPath )) {
718757 LLVM_DEBUG (llvm::dbgs () << " Dep " << in.getPath ()
719758 << " is directly out of date\n " );
720759 return false ;
@@ -763,9 +802,12 @@ class ParseableInterfaceModuleLoaderImpl {
763802
764803 // Next, check the dependencies in the forwarding file.
765804 for (auto &dep : fwd.dependencies ) {
805+ // Forwarding modules expand SDKRelative paths when generated, so are
806+ // guaranteed to be absolute.
766807 deps.push_back (
767808 FileDependency::modTimeBased (
768- dep.path , dep.size , dep.lastModificationTime ));
809+ dep.path , /* isSDKRelative=*/ false , dep.size ,
810+ dep.lastModificationTime ));
769811 }
770812 if (!dependenciesAreUpToDate (deps))
771813 return false ;
@@ -919,8 +961,9 @@ class ParseableInterfaceModuleLoaderImpl {
919961 addDependency (fwd.underlyingModulePath );
920962
921963 // Add all the dependencies from the prebuilt module.
964+ SmallString<128 > SDKRelativeBuffer;
922965 for (auto dep : deps) {
923- addDependency (dep. getPath ( ));
966+ addDependency (getFullDependencyPath (dep, SDKRelativeBuffer ));
924967 }
925968
926969 return withOutputFile (diags, outputPath,
@@ -937,6 +980,7 @@ class ParseableInterfaceModuleLoaderImpl {
937980 // / loading strategy.
938981 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
939982 findOrBuildLoadableModule () {
983+
940984 // Track system dependencies if the parent tracker is set to do so.
941985 // FIXME: This means -track-system-dependencies isn't honored when the
942986 // top-level invocation isn't tracking dependencies
@@ -1057,11 +1101,10 @@ bool ParseableInterfaceModuleLoader::buildSwiftModuleFromSwiftInterface(
10571101 bool SerializeDependencyHashes, bool TrackSystemDependencies) {
10581102 ParseableInterfaceBuilder builder (Ctx, InPath, ModuleName,
10591103 CacheDir, PrebuiltCacheDir,
1060- SerializeDependencyHashes);
1061- // FIXME: We really only want to serialize 'important' dependencies here, and
1062- // make them relocatable (SDK-relative) if we want to ship the built
1063- // swiftmodules to another machine. Just track them as absolute paths
1064- // for now, so we can test the dependency tracking locally.
1104+ SerializeDependencyHashes,
1105+ TrackSystemDependencies);
1106+ // FIXME: We really only want to serialize 'important' dependencies here, if
1107+ // we want to ship the built swiftmodules to another machine.
10651108 return builder.buildSwiftModule (OutPath, /* shouldSerializeDeps*/ true ,
10661109 /* ModuleBuffer*/ nullptr );
10671110}
0 commit comments