@@ -368,6 +368,8 @@ class swift::ParseableInterfaceBuilder {
368
368
bool collectDepsForSerialization (CompilerInstance &SubInstance,
369
369
SmallVectorImpl<FileDependency> &Deps,
370
370
bool IsHashBased) {
371
+ StringRef SDKPath = SubInstance.getASTContext ().SearchPathOpts .SDKPath ;
372
+
371
373
auto DTDeps = SubInstance.getDependencyTracker ()->getDependencies ();
372
374
SmallVector<StringRef, 16 > InitialDepNames (DTDeps.begin (), DTDeps.end ());
373
375
InitialDepNames.push_back (interfacePath);
@@ -396,17 +398,39 @@ class swift::ParseableInterfaceBuilder {
396
398
if (!Status)
397
399
return true ;
398
400
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
+
399
421
if (IsHashBased) {
400
422
auto buf = getDepBuf ();
401
423
if (!buf) return true ;
402
424
uint64_t hash = xxHash64 (buf->getBuffer ());
403
425
Deps.push_back (
404
- FileDependency::hashBased (DepName, Status->getSize (), hash));
426
+ FileDependency::hashBased (DepNameToStore, IsSDKRelative,
427
+ Status->getSize (), hash));
405
428
} else {
406
429
uint64_t mtime =
407
430
Status->getLastModificationTime ().time_since_epoch ().count ();
408
431
Deps.push_back (
409
- FileDependency::modTimeBased (DepName, Status->getSize (), mtime));
432
+ FileDependency::modTimeBased (DepNameToStore, IsSDKRelative,
433
+ Status->getSize (), mtime));
410
434
}
411
435
412
436
if (moduleCachePath.empty ())
@@ -681,10 +705,23 @@ class ParseableInterfaceModuleLoaderImpl {
681
705
OutPath.append (OutExt);
682
706
}
683
707
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
+
684
721
// Checks that a dependency read from the cached module is up to date compared
685
722
// 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,
688
725
diags, diagnosticLoc);
689
726
if (!status) return false ;
690
727
@@ -701,7 +738,7 @@ class ParseableInterfaceModuleLoaderImpl {
701
738
702
739
// Slow path: if the dependency is verified by content hash, check it vs.
703
740
// the hash of the file.
704
- auto buf = getBufferOfDependency (fs, dep. getPath () , interfacePath,
741
+ auto buf = getBufferOfDependency (fs, fullPath , interfacePath,
705
742
diags, diagnosticLoc);
706
743
if (!buf) return false ;
707
744
@@ -711,10 +748,12 @@ class ParseableInterfaceModuleLoaderImpl {
711
748
// Check if all the provided file dependencies are up-to-date compared to
712
749
// what's currently on disk.
713
750
bool dependenciesAreUpToDate (ArrayRef<FileDependency> deps) {
751
+ SmallString<128 > SDKRelativeBuffer;
714
752
for (auto &in : deps) {
753
+ StringRef fullPath = getFullDependencyPath (in, SDKRelativeBuffer);
715
754
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 )) {
718
757
LLVM_DEBUG (llvm::dbgs () << " Dep " << in.getPath ()
719
758
<< " is directly out of date\n " );
720
759
return false ;
@@ -763,9 +802,12 @@ class ParseableInterfaceModuleLoaderImpl {
763
802
764
803
// Next, check the dependencies in the forwarding file.
765
804
for (auto &dep : fwd.dependencies ) {
805
+ // Forwarding modules expand SDKRelative paths when generated, so are
806
+ // guaranteed to be absolute.
766
807
deps.push_back (
767
808
FileDependency::modTimeBased (
768
- dep.path , dep.size , dep.lastModificationTime ));
809
+ dep.path , /* isSDKRelative=*/ false , dep.size ,
810
+ dep.lastModificationTime ));
769
811
}
770
812
if (!dependenciesAreUpToDate (deps))
771
813
return false ;
@@ -919,8 +961,9 @@ class ParseableInterfaceModuleLoaderImpl {
919
961
addDependency (fwd.underlyingModulePath );
920
962
921
963
// Add all the dependencies from the prebuilt module.
964
+ SmallString<128 > SDKRelativeBuffer;
922
965
for (auto dep : deps) {
923
- addDependency (dep. getPath ( ));
966
+ addDependency (getFullDependencyPath (dep, SDKRelativeBuffer ));
924
967
}
925
968
926
969
return withOutputFile (diags, outputPath,
@@ -937,6 +980,7 @@ class ParseableInterfaceModuleLoaderImpl {
937
980
// / loading strategy.
938
981
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
939
982
findOrBuildLoadableModule () {
983
+
940
984
// Track system dependencies if the parent tracker is set to do so.
941
985
// FIXME: This means -track-system-dependencies isn't honored when the
942
986
// top-level invocation isn't tracking dependencies
@@ -1057,11 +1101,10 @@ bool ParseableInterfaceModuleLoader::buildSwiftModuleFromSwiftInterface(
1057
1101
bool SerializeDependencyHashes, bool TrackSystemDependencies) {
1058
1102
ParseableInterfaceBuilder builder (Ctx, InPath, ModuleName,
1059
1103
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.
1065
1108
return builder.buildSwiftModule (OutPath, /* shouldSerializeDeps*/ true ,
1066
1109
/* ModuleBuffer*/ nullptr );
1067
1110
}
0 commit comments