19
19
#include " swift/AST/Module.h"
20
20
#include " swift/AST/ProtocolConformance.h"
21
21
#include " swift/Basic/Lazy.h"
22
+ #include " swift/Basic/Platform.h"
22
23
#include " swift/Basic/STLExtras.h"
23
24
#include " swift/Frontend/Frontend.h"
24
25
#include " swift/Frontend/ParseableInterfaceSupport.h"
@@ -826,7 +827,7 @@ class ParseableInterfaceModuleLoaderImpl {
826
827
// Assemble the expected path: $PREBUILT_CACHE/Foo.swiftmodule or
827
828
// $PREBUILT_CACHE/Foo.swiftmodule/arch.swiftmodule. Note that there's no
828
829
// cache key here.
829
- scratch. append ( prebuiltCacheDir) ;
830
+ scratch = prebuiltCacheDir;
830
831
831
832
// FIXME: Would it be possible to only have architecture-specific names
832
833
// here? Then we could skip this check.
@@ -845,6 +846,48 @@ class ParseableInterfaceModuleLoaderImpl {
845
846
return scratch.str ();
846
847
}
847
848
849
+ // / Hack to deal with build systems (including the Swift standard library, at
850
+ // / the time of this comment) that aren't yet using target-specific names for
851
+ // / multi-target swiftmodules, in case the prebuilt cache is.
852
+ Optional<StringRef>
853
+ computeFallbackPrebuiltModulePath (llvm::SmallString<256 > &scratch) {
854
+ namespace path = llvm::sys::path;
855
+ StringRef sdkPath = ctx.SearchPathOpts .SDKPath ;
856
+
857
+ // Check if the interface file comes from the SDK
858
+ if (sdkPath.empty () || !hasPrefix (path::begin (interfacePath),
859
+ path::end (interfacePath),
860
+ path::begin (sdkPath),
861
+ path::end (sdkPath)))
862
+ return None;
863
+
864
+ // If the module isn't target-specific, there's no fallback path.
865
+ StringRef inParentDirName =
866
+ path::filename (path::parent_path (interfacePath));
867
+ if (path::extension (inParentDirName) != " .swiftmodule" )
868
+ return None;
869
+
870
+ // If the interface is already using the target-specific name, there's
871
+ // nothing else to try.
872
+ auto normalizedTarget = getTargetSpecificModuleTriple (ctx.LangOpts .Target );
873
+ if (path::stem (modulePath) == normalizedTarget.str ())
874
+ return None;
875
+
876
+ // Assemble the expected path:
877
+ // $PREBUILT_CACHE/Foo.swiftmodule/target.swiftmodule. Note that there's no
878
+ // cache key here.
879
+ scratch = prebuiltCacheDir;
880
+ path::append (scratch, inParentDirName);
881
+ path::append (scratch, normalizedTarget.str ());
882
+ scratch += " .swiftmodule" ;
883
+
884
+ // If there isn't a file at this location, skip returning a path.
885
+ if (!fs.exists (scratch))
886
+ return None;
887
+
888
+ return scratch.str ();
889
+ }
890
+
848
891
bool isInResourceDir (StringRef path) {
849
892
StringRef resourceDir = ctx.SearchPathOpts .RuntimeLibraryPath ;
850
893
if (resourceDir.empty ()) return false ;
@@ -926,7 +969,12 @@ class ParseableInterfaceModuleLoaderImpl {
926
969
if (!prebuiltCacheDir.empty ()) {
927
970
llvm::SmallString<256 > scratch;
928
971
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
929
- auto path = computePrebuiltModulePath (scratch);
972
+ Optional<StringRef> path = computePrebuiltModulePath (scratch);
973
+ if (!path) {
974
+ // Hack: deal with prebuilds of modules that still use the target-based
975
+ // names.
976
+ path = computeFallbackPrebuiltModulePath (scratch);
977
+ }
930
978
if (path) {
931
979
if (swiftModuleIsUpToDate (*path, deps, moduleBuffer)) {
932
980
LLVM_DEBUG (llvm::dbgs () << " Found up-to-date prebuilt module at "
0 commit comments