@@ -789,6 +789,92 @@ final class ExplicitModuleBuildTests: XCTestCase {
789
789
}
790
790
}
791
791
792
+ func testBinaryFrameworkDependencyScan( ) throws {
793
+ try withTemporaryDirectory { path in
794
+ let ( stdLibPath, shimsPath, toolchain, hostTriple) = try getDriverArtifactsForScanning ( )
795
+ let moduleCachePath = path. appending ( component: " ModuleCache " )
796
+
797
+ // Setup module to be used as dependency
798
+ try localFileSystem. createDirectory ( moduleCachePath)
799
+ let frameworksPath = path. appending ( component: " Frameworks " )
800
+ let frameworkModuleDir = frameworksPath. appending ( component: " Foo.framework " )
801
+ . appending ( component: " Modules " )
802
+ . appending ( component: " Foo.swiftmodule " )
803
+ let frameworkModulePath =
804
+ frameworkModuleDir. appending ( component: hostTriple. archName + " .swiftmodule " )
805
+ try localFileSystem. createDirectory ( frameworkModuleDir, recursive: true )
806
+ let fooSourcePath = path. appending ( component: " Foo.swift " )
807
+ try localFileSystem. writeFileContents ( fooSourcePath) {
808
+ $0 <<< " public func foo() {} "
809
+ }
810
+
811
+ // Setup our main test module
812
+ let mainSourcePath = path. appending ( component: " Foo.swift " )
813
+ try localFileSystem. writeFileContents ( mainSourcePath) {
814
+ $0 <<< " import Foo "
815
+ }
816
+
817
+ // 1. Build Foo module
818
+ let sdkArgumentsForTesting = ( try ? Driver . sdkArgumentsForTesting ( ) ) ?? [ ]
819
+ var driverFoo = try Driver ( args: [ " swiftc " ,
820
+ " -module-cache-path " , moduleCachePath. nativePathString ( escaped: true ) ,
821
+ " -module-name " , " Foo " ,
822
+ " -emit-module " ,
823
+ " -emit-module-path " ,
824
+ frameworkModulePath. nativePathString ( escaped: true ) ,
825
+ " -working-directory " ,
826
+ path. nativePathString ( escaped: true ) ,
827
+ fooSourcePath. nativePathString ( escaped: true ) ] + sdkArgumentsForTesting,
828
+ env: ProcessEnv . vars)
829
+ let jobs = try driverFoo. planBuild ( )
830
+ try driverFoo. run ( jobs: jobs)
831
+ XCTAssertFalse ( driverFoo. diagnosticEngine. hasErrors)
832
+
833
+ // 2. Run a dependency scan to find the just-built module
834
+ let dependencyOracle = InterModuleDependencyOracle ( )
835
+ let scanLibPath = try Driver . getScanLibPath ( of: toolchain,
836
+ hostTriple: hostTriple,
837
+ env: ProcessEnv . vars)
838
+ guard try dependencyOracle
839
+ . verifyOrCreateScannerInstance ( fileSystem: localFileSystem,
840
+ swiftScanLibPath: scanLibPath) else {
841
+ XCTFail ( " Dependency scanner library not found " )
842
+ return
843
+ }
844
+ guard try dependencyOracle. supportsBinaryFrameworkDependencies ( ) else {
845
+ throw XCTSkip ( " libSwiftScan does not support framework binary dependency reporting. " )
846
+ }
847
+
848
+ var driver = try Driver ( args: [ " swiftc " ,
849
+ " -I " , stdLibPath. nativePathString ( escaped: true ) ,
850
+ " -I " , shimsPath. nativePathString ( escaped: true ) ,
851
+ " -F " , frameworksPath. nativePathString ( escaped: true ) ,
852
+ " -import-objc-header " ,
853
+ " -explicit-module-build " ,
854
+ " -module-name " , " main " ,
855
+ " -working-directory " , path. nativePathString ( escaped: true ) ,
856
+ mainSourcePath. nativePathString ( escaped: true ) ] + sdkArgumentsForTesting,
857
+ env: ProcessEnv . vars)
858
+ let resolver = try ArgsResolver ( fileSystem: localFileSystem)
859
+ var scannerCommand = try driver. dependencyScannerInvocationCommand ( ) . 1 . map { try resolver. resolve ( $0) }
860
+ if scannerCommand. first == " -frontend " {
861
+ scannerCommand. removeFirst ( )
862
+ }
863
+ let dependencyGraph =
864
+ try ! dependencyOracle. getDependencies ( workingDirectory: path,
865
+ commandLine: scannerCommand)
866
+
867
+ let fooDependencyInfo = try XCTUnwrap ( dependencyGraph. modules [ . swiftPrebuiltExternal( " Foo " ) ] )
868
+ guard case . swiftPrebuiltExternal( let fooDetails) = fooDependencyInfo. details else {
869
+ XCTFail ( " Foo dependency module does not have Swift details field " )
870
+ return
871
+ }
872
+
873
+ // Ensure the dependency has been reported as a framework
874
+ XCTAssertTrue ( fooDetails. isFramework)
875
+ }
876
+ }
877
+
792
878
func getStdlibShimsPaths( _ driver: Driver ) throws -> ( AbsolutePath , AbsolutePath ) {
793
879
let toolchainRootPath : AbsolutePath = try driver. toolchain. getToolPath ( . swiftCompiler)
794
880
. parentDirectory // bin
0 commit comments