@@ -401,31 +401,21 @@ public final class ManifestLoader: ManifestLoaderProtocol {
401
401
402
402
// Compute the path to runtime we need to load.
403
403
let runtimePath = self . runtimePath ( for: manifestVersion) . pathString
404
- let interpreterFlags = self . interpreterFlags ( for: manifestVersion)
404
+ let compilerFlags = self . interpreterFlags ( for: manifestVersion)
405
405
406
406
// FIXME: Workaround for the module cache bug that's been haunting Swift CI
407
407
// <rdar://problem/48443680>
408
408
let moduleCachePath = Process . env [ " SWIFTPM_MODULECACHE_OVERRIDE " ] ?? Process . env [ " SWIFTPM_TESTS_MODULECACHE " ]
409
409
410
+ let bootstrapArgs = self . bootstrapArgs ( )
411
+
410
412
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
423
413
cmd += [ resources. swiftCompiler. pathString]
424
- cmd += [ " --driver-mode=swift " ]
425
- cmd += bootstrapArgs ( )
414
+ cmd += bootstrapArgs. compileFlags
426
415
cmd += verbosity. ccArgs
427
416
cmd += [ " -L " , runtimePath, " -lPackageDescription " ]
428
- cmd += interpreterFlags
417
+ cmd += [ " -Xlinker " , " -rpath " , " -Xlinker " , runtimePath]
418
+ cmd += compilerFlags
429
419
if let moduleCachePath = moduleCachePath {
430
420
cmd += [ " -module-cache-path " , moduleCachePath]
431
421
}
@@ -441,25 +431,55 @@ public final class ManifestLoader: ManifestLoaderProtocol {
441
431
442
432
cmd += [ manifestPath. pathString]
443
433
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
+
446
449
// 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
+ }
448
471
449
472
// 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 ( )
453
475
454
476
// 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
456
479
return
457
480
}
458
481
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
463
483
}
464
484
465
485
var manifestParseResult = ManifestParseResult ( )
@@ -478,32 +498,34 @@ public final class ManifestLoader: ManifestLoaderProtocol {
478
498
}
479
499
480
500
/// Returns the extra manifest args required during SwiftPM's own bootstrap.
481
- private func bootstrapArgs( ) -> [ String ] {
501
+ private func bootstrapArgs( ) -> ( compileFlags : [ String ] , runtimeFlags : [ String ] ) {
482
502
#if !os(Linux)
483
- return [ ]
503
+ return ( [ ] , [ ] )
484
504
#else
485
505
// The Linux bots require extra arguments in order to locate the corelibs.
486
506
// We can potentially drop this by installing some stable linux toolchain
487
507
// after Swift gets ABI and module stability.
488
508
//
489
509
// Compute if SwiftPM is bootstrapping.
490
510
let env = ProcessInfo . processInfo. environment
491
- guard env. keys. contains ( " SWIFTPM_BOOTSTRAP " ) else { return [ ] }
511
+ guard env. keys. contains ( " SWIFTPM_BOOTSTRAP " ) else { return ( [ ] , [ ] ) }
492
512
guard let buildPathStr = env [ " SWIFTPM_BUILD_DIR " ] , let buildPath = try ? AbsolutePath ( validating: buildPathStr) else {
493
- return [ ]
513
+ return ( [ ] , [ ] )
494
514
}
495
515
496
516
// Construct the required search paths relative to the build directory.
497
517
let libdir = buildPath. appending ( RelativePath ( " .bootstrap/lib/swift/linux " ) )
498
518
let incdir = libdir. appending ( component: " x86_64 " )
499
519
let dispatchIncdir = incdir. appending ( component: " dispatch " )
500
520
501
- return [
521
+ let compileFlags = [
502
522
" -I \( incdir) " ,
503
523
" -I \( dispatchIncdir) " ,
504
524
" -L \( libdir) " ,
505
525
" -Xcc " , " -F \( incdir) " ,
506
526
]
527
+
528
+ return ( compileFlags, [ libdir. pathString] )
507
529
#endif
508
530
}
509
531
0 commit comments