@@ -401,31 +401,21 @@ public final class ManifestLoader: ManifestLoaderProtocol {
401401
402402 // Compute the path to runtime we need to load.
403403 let runtimePath = self . runtimePath ( for: manifestVersion) . pathString
404- let interpreterFlags = self . interpreterFlags ( for: manifestVersion)
404+ let compilerFlags = self . interpreterFlags ( for: manifestVersion)
405405
406406 // FIXME: Workaround for the module cache bug that's been haunting Swift CI
407407 // <rdar://problem/48443680>
408408 let moduleCachePath = Process . env [ " SWIFTPM_MODULECACHE_OVERRIDE " ] ?? Process . env [ " SWIFTPM_TESTS_MODULECACHE " ]
409409
410+ let bootstrapArgs = self . bootstrapArgs ( )
411+
410412 var cmd = [ String] ( )
411- #if os(macOS)
412- // If enabled, use sandbox-exec on macOS. This provides some safety against
413- // arbitrary code execution when parsing manifest files. We only allow
414- // the permissions which are absolutely necessary for manifest parsing.
415- if isManifestSandboxEnabled {
416- let cacheDirs = [
417- cacheDir,
418- moduleCachePath. map { AbsolutePath ( $0) }
419- ] . compactMap { $0}
420- cmd += [ " sandbox-exec " , " -p " , sandboxProfile ( cacheDirs) ]
421- }
422- #endif
423413 cmd += [ resources. swiftCompiler. pathString]
424- cmd += [ " --driver-mode=swift " ]
425- cmd += bootstrapArgs ( )
414+ cmd += bootstrapArgs. compileFlags
426415 cmd += verbosity. ccArgs
427416 cmd += [ " -L " , runtimePath, " -lPackageDescription " ]
428- cmd += interpreterFlags
417+ cmd += [ " -Xlinker " , " -rpath " , " -Xlinker " , runtimePath]
418+ cmd += compilerFlags
429419 if let moduleCachePath = moduleCachePath {
430420 cmd += [ " -module-cache-path " , moduleCachePath]
431421 }
@@ -441,25 +431,55 @@ public final class ManifestLoader: ManifestLoaderProtocol {
441431
442432 cmd += [ manifestPath. pathString]
443433
444- // Create and open a temporary file to write json to.
445- let file = try TemporaryFile ( )
434+ let tmpDir = try TemporaryDirectory ( removeTreeOnDeinit: true )
435+ let compiledManifest = tmpDir. path. appending ( component: " manifest " )
436+ // Set path to compiled manifest executable.
437+ cmd += [ " -o " , compiledManifest. pathString]
438+
439+ // Compile the manifest.
440+ let compilerResult = try Process . popen ( arguments: cmd)
441+ let compilerOutput = try ( compilerResult. utf8Output ( ) + compilerResult. utf8stderrOutput ( ) ) . spm_chuzzle ( )
442+ manifestParseResult. compilerOutput = compilerOutput
443+
444+ // Return now if there was an error.
445+ if compilerResult. exitStatus != . terminated( code: 0 ) {
446+ return
447+ }
448+
446449 // Pass the fd in arguments.
447- cmd += [ " -fileno " , " \( file. fileHandle. fileDescriptor) " ]
450+ cmd = [ compiledManifest. pathString, " -fileno " , " 1 " ]
451+
452+ #if os(macOS)
453+ // If enabled, use sandbox-exec on macOS. This provides some safety against
454+ // arbitrary code execution when parsing manifest files. We only allow
455+ // the permissions which are absolutely necessary for manifest parsing.
456+ if isManifestSandboxEnabled {
457+ let cacheDirectories = [
458+ cacheDir,
459+ moduleCachePath. map ( { AbsolutePath ( $0) } )
460+ ] . compactMap ( { $0 } )
461+ let profile = sandboxProfile ( cacheDirectories)
462+ cmd += [ " sandbox-exec " , " -p " , profile]
463+ }
464+ #endif
465+
466+ // Setup the runtime environment for bootstrapping.
467+ var env = Process . env
468+ if !bootstrapArgs. runtimeFlags. isEmpty {
469+ env [ " LD_LIBRARY_PATH " ] = bootstrapArgs. runtimeFlags. joined ( separator: " : " )
470+ }
448471
449472 // Run the command.
450- let result = try Process . popen ( arguments: cmd)
451- let output = try ( result. utf8Output ( ) + result. utf8stderrOutput ( ) ) . spm_chuzzle ( )
452- manifestParseResult. compilerOutput = output
473+ let runResult = try Process . popen ( arguments: cmd, environment: env)
474+ let runOutput = try ( runResult. utf8Output ( ) + runResult. utf8stderrOutput ( ) ) . spm_chuzzle ( )
453475
454476 // Return now if there was an error.
455- if result. exitStatus != . terminated( code: 0 ) {
477+ if runResult. exitStatus != . terminated( code: 0 ) {
478+ manifestParseResult. errorOutput = runOutput
456479 return
457480 }
458481
459- guard let json = try localFileSystem. readFileContents ( file. path) . validDescription else {
460- throw StringError ( " the manifest has invalid encoding " )
461- }
462- manifestParseResult. parsedManifest = json
482+ manifestParseResult. parsedManifest = runOutput
463483 }
464484
465485 var manifestParseResult = ManifestParseResult ( )
@@ -478,32 +498,34 @@ public final class ManifestLoader: ManifestLoaderProtocol {
478498 }
479499
480500 /// Returns the extra manifest args required during SwiftPM's own bootstrap.
481- private func bootstrapArgs( ) -> [ String ] {
501+ private func bootstrapArgs( ) -> ( compileFlags : [ String ] , runtimeFlags : [ String ] ) {
482502 #if !os(Linux)
483- return [ ]
503+ return ( [ ] , [ ] )
484504 #else
485505 // The Linux bots require extra arguments in order to locate the corelibs.
486506 // We can potentially drop this by installing some stable linux toolchain
487507 // after Swift gets ABI and module stability.
488508 //
489509 // Compute if SwiftPM is bootstrapping.
490510 let env = ProcessInfo . processInfo. environment
491- guard env. keys. contains ( " SWIFTPM_BOOTSTRAP " ) else { return [ ] }
511+ guard env. keys. contains ( " SWIFTPM_BOOTSTRAP " ) else { return ( [ ] , [ ] ) }
492512 guard let buildPathStr = env [ " SWIFTPM_BUILD_DIR " ] , let buildPath = try ? AbsolutePath ( validating: buildPathStr) else {
493- return [ ]
513+ return ( [ ] , [ ] )
494514 }
495515
496516 // Construct the required search paths relative to the build directory.
497517 let libdir = buildPath. appending ( RelativePath ( " .bootstrap/lib/swift/linux " ) )
498518 let incdir = libdir. appending ( component: " x86_64 " )
499519 let dispatchIncdir = incdir. appending ( component: " dispatch " )
500520
501- return [
521+ let compileFlags = [
502522 " -I \( incdir) " ,
503523 " -I \( dispatchIncdir) " ,
504524 " -L \( libdir) " ,
505525 " -Xcc " , " -F \( incdir) " ,
506526 ]
527+
528+ return ( compileFlags, [ libdir. pathString] )
507529 #endif
508530 }
509531
0 commit comments