Skip to content

Commit 4b8f064

Browse files
committed
Propagate driver-specified clang-target flags even when no SDK is specified
1 parent 7764366 commit 4b8f064

File tree

6 files changed

+203
-51
lines changed

6 files changed

+203
-51
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public struct Driver {
5959
case cannotSpecify_OForMultipleOutputs
6060
case conflictingOptions(Option, Option)
6161
case unableToLoadOutputFileMap(String, String)
62+
case malformedChainedBridgingHeader(String)
6263
case unableToDecodeFrontendTargetInfo(String?, [String], String)
6364
case failedToRetrieveFrontendTargetInfo
6465
case failedToRunFrontendToRetrieveTargetInfo(Int, String?)
@@ -111,6 +112,8 @@ public struct Driver {
111112
return "failed to retrieve frontend target info"
112113
case .unableToReadFrontendTargetInfo:
113114
return "could not read frontend target info"
115+
case .malformedChainedBridgingHeader(let content):
116+
return "could not convert bridging header content to utf-8: \(content)"
114117
case let .failedToRunFrontendToRetrieveTargetInfo(returnCode, stderr):
115118
return "frontend job retrieving target info failed with code \(returnCode)"
116119
+ (stderr.map {": \($0)"} ?? "")
@@ -3107,7 +3110,10 @@ extension Driver {
31073110
if !fileSystem.exists(path.parentDirectory) {
31083111
try fileSystem.createDirectory(path.parentDirectory, recursive: true)
31093112
}
3110-
return try VirtualPath.createBuildProductFileWithKnownContents(path, chainedHeader.content.data(using: .utf8)!).intern()
3113+
guard let headerData = chainedHeader.content.data(using: .utf8) else {
3114+
throw Driver.Error.malformedChainedBridgingHeader(chainedHeader.content)
3115+
}
3116+
return try VirtualPath.createBuildProductFileWithKnownContents(path, headerData).intern()
31113117
}
31123118
return originalObjCHeaderFile
31133119
}

Sources/SwiftDriver/Jobs/ReplJob.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ extension Driver {
1515
var commandLine: [Job.ArgTemplate] = swiftCompilerPrefixArgs.map { Job.ArgTemplate.flag($0) }
1616
var inputs: [TypedVirtualPath] = []
1717

18-
try addCommonFrontendOptions(commandLine: &commandLine, inputs: &inputs, kind: .repl,
19-
explicitModulePlanner: nil)
18+
try addCommonFrontendOptions(commandLine: &commandLine, inputs: &inputs, kind: .repl)
2019
try addRuntimeLibraryFlags(commandLine: &commandLine)
2120

2221
try commandLine.appendLast(.importObjcHeader, from: &parsedOptions)

Sources/SwiftDriver/Toolchains/DarwinToolchain.swift

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -409,8 +409,57 @@ public final class DarwinToolchain: Toolchain {
409409
driver: inout Driver,
410410
skipMacroOptions: Bool
411411
) throws {
412-
guard let sdkPath = frontendTargetInfo.sdkPath?.path,
413-
let sdkInfo = getTargetSDKInfo(sdkPath: sdkPath) else { return }
412+
let sdkPath = frontendTargetInfo.sdkPath?.path
413+
let sdkInfo: DarwinSDKInfo? = sdkPath != nil ? getTargetSDKInfo(sdkPath: sdkPath!) : nil
414+
415+
// Pass down -clang-target.
416+
// If not specified otherwise, we should use the same triple as -target
417+
if !driver.parsedOptions.hasArgument(.disableClangTarget) &&
418+
driver.isFrontendArgSupported(.clangTarget) &&
419+
driver.parsedOptions.contains(.driverExplicitModuleBuild) {
420+
// The common target triple for all Clang dependencies of this compilation,
421+
// both direct and transitive is computed as:
422+
// 1. An explicitly-specified `-clang-target` argument to this driver invocation
423+
// 2. (On Darwin) The target triple of the selected SDK
424+
var clangTargetTriple: String? = nil
425+
if let explicitClangTripleArg = driver.parsedOptions.getLastArgument(.clangTarget)?.asSingle {
426+
clangTargetTriple = explicitClangTripleArg
427+
} else if let sdkInfo = sdkInfo {
428+
let currentTriple = frontendTargetInfo.target.triple
429+
let sdkVersionedOSString = currentTriple.osNameUnversioned + sdkInfo.sdkVersion(for: currentTriple).sdkVersionString
430+
clangTargetTriple = currentTriple.triple.replacingOccurrences(of: currentTriple.osName, with: sdkVersionedOSString)
431+
}
432+
433+
if let clangTargetTriple {
434+
commandLine.appendFlag(.clangTarget)
435+
commandLine.appendFlag(clangTargetTriple)
436+
}
437+
438+
// Repeat the above for the '-target-variant' flag
439+
if driver.parsedOptions.contains(.targetVariant),
440+
driver.isFrontendArgSupported(.clangTargetVariant),
441+
let targetVariantTripleStr = frontendTargetInfo.targetVariant?.triple
442+
{
443+
var clangTargetVariantTriple: String? = nil
444+
if let explicitClangTargetVariantArg = driver.parsedOptions.getLastArgument(.clangTargetVariant)?.asSingle {
445+
clangTargetVariantTriple = explicitClangTargetVariantArg
446+
} else if let sdkInfo {
447+
let currentVariantTriple = targetVariantTripleStr
448+
let sdkVersionedOSSString =
449+
currentVariantTriple.osNameUnversioned
450+
+ sdkInfo.sdkVersion(for: currentVariantTriple).sdkVersionString
451+
clangTargetVariantTriple = currentVariantTriple.triple.replacingOccurrences(
452+
of: currentVariantTriple.osName, with: sdkVersionedOSSString)
453+
}
454+
455+
if let clangTargetVariantTriple {
456+
commandLine.appendFlag(.clangTargetVariant)
457+
commandLine.appendFlag(clangTargetVariantTriple)
458+
}
459+
}
460+
}
461+
462+
guard let sdkPath, let sdkInfo else { return }
414463

415464
commandLine.append(.flag("-target-sdk-version"))
416465
commandLine.append(.flag(sdkInfo.sdkVersion(for: frontendTargetInfo.target.triple).sdkVersionString))
@@ -453,45 +502,6 @@ public final class DarwinToolchain: Toolchain {
453502
commandLine.appendPath(prebuiltModulesPath)
454503
}
455504

456-
// Pass down -clang-target.
457-
// If not specified otherwise, we should use the same triple as -target
458-
if !driver.parsedOptions.hasArgument(.disableClangTarget) &&
459-
driver.isFrontendArgSupported(.clangTarget) &&
460-
driver.parsedOptions.contains(.driverExplicitModuleBuild) {
461-
// The common target triple for all Clang dependencies of this compilation,
462-
// both direct and transitive is computed as:
463-
// 1. An explicitly-specified `-clang-target` argument to this driver invocation
464-
// 2. (On Darwin) The target triple of the selected SDK
465-
let clangTargetTriple: String
466-
if let explicitClangTripleArg = driver.parsedOptions.getLastArgument(.clangTarget)?.asSingle {
467-
clangTargetTriple = explicitClangTripleArg
468-
} else {
469-
let currentTriple = frontendTargetInfo.target.triple
470-
let sdkVersionedOSString = currentTriple.osNameUnversioned + sdkInfo.sdkVersion(for: currentTriple).sdkVersionString
471-
clangTargetTriple = currentTriple.triple.replacingOccurrences(of: currentTriple.osName, with: sdkVersionedOSString)
472-
}
473-
474-
commandLine.appendFlag(.clangTarget)
475-
commandLine.appendFlag(clangTargetTriple)
476-
477-
// Repeat the above for the '-target-variant' flag
478-
if driver.parsedOptions.contains(.targetVariant),
479-
driver.isFrontendArgSupported(.clangTargetVariant),
480-
let targetVariantTripleStr = frontendTargetInfo.targetVariant?.triple {
481-
let clangTargetVariantTriple: String
482-
if let explicitClangTargetVariantArg = driver.parsedOptions.getLastArgument(.clangTargetVariant)?.asSingle {
483-
clangTargetVariantTriple = explicitClangTargetVariantArg
484-
} else {
485-
let currentVariantTriple = targetVariantTripleStr
486-
let sdkVersionedOSSString = currentVariantTriple.osNameUnversioned + sdkInfo.sdkVersion(for: currentVariantTriple).sdkVersionString
487-
clangTargetVariantTriple = currentVariantTriple.triple.replacingOccurrences(of: currentVariantTriple.osName, with: sdkVersionedOSSString)
488-
}
489-
490-
commandLine.appendFlag(.clangTargetVariant)
491-
commandLine.appendFlag(clangTargetVariantTriple)
492-
}
493-
}
494-
495505
if driver.isFrontendArgSupported(.externalPluginPath) && !skipMacroOptions {
496506
// If the PLATFORM_DIR environment variable is set, also add plugin
497507
// paths into it. Since this is a user override, it comes beore the

Sources/SwiftDriver/Utilities/VirtualPath.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ public enum VirtualPath: Hashable {
4747
/// Standard output
4848
case standardOutput
4949

50-
/// ACTODO: Comment
50+
/// A file with a known absolute path and contents computed by
51+
/// the driver, it gets written to the filesystem at resolution time
5152
case buildArtifactWithKnownContents(AbsolutePath, Data)
5253

5354
/// We would like to direct clients to use the temporary file creation utilities `createUniqueTemporaryFile`, etc.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"Version": "10.15",
33
"VersionMap": {
4-
"macOS_iOSMac": {},
5-
"iOSMac_macOS": {}
4+
"macOS_iOSMac": {"10.15":"13.1"},
5+
"iOSMac_macOS": {"13.1":"10.15"}
66
},
77
"CanonicalName": "macosx10.15"
88
}

Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift

Lines changed: 140 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2524,6 +2524,142 @@ final class ExplicitModuleBuildTests: XCTestCase {
25242524
}
25252525
}
25262526

2527+
func testClangTargetOptionsExplicit() throws {
2528+
let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning()
2529+
let cHeadersPath: AbsolutePath =
2530+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
2531+
.appending(component: "CHeaders")
2532+
let swiftModuleInterfacesPath: AbsolutePath =
2533+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
2534+
.appending(component: "Swift")
2535+
let mockSDKPath: AbsolutePath =
2536+
try testInputsPath.appending(component: "mock-sdk.sdk")
2537+
2538+
// Only '-target' is specified, the driver infers '-clang-target' from SDK deployment target
2539+
do {
2540+
try withTemporaryDirectory { path in
2541+
let main = path.appending(component: "testDependencyScanning.swift")
2542+
try localFileSystem.writeFileContents(main, bytes:
2543+
"""
2544+
import A;
2545+
"""
2546+
)
2547+
var driver = try Driver(args: ["swiftc",
2548+
"-target", "x86_64-apple-macosx10.10",
2549+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2550+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2551+
"-emit-module",
2552+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2553+
"-I", cHeadersPath.nativePathString(escaped: true),
2554+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2555+
"-I", stdlibPath.nativePathString(escaped: true),
2556+
"-I", shimsPath.nativePathString(escaped: true),
2557+
"-explicit-module-build",
2558+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2559+
main.pathString])
2560+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2561+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2562+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2563+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.15")]))
2564+
}
2565+
}
2566+
2567+
// User-specified '-clang-target'
2568+
do {
2569+
try withTemporaryDirectory { path in
2570+
let main = path.appending(component: "testDependencyScanning.swift")
2571+
try localFileSystem.writeFileContents(main, bytes:
2572+
"""
2573+
import A;
2574+
"""
2575+
)
2576+
var driver = try Driver(args: ["swiftc",
2577+
"-target", "x86_64-apple-macosx10.10",
2578+
"-clang-target", "x86_64-apple-macosx10.12",
2579+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2580+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2581+
"-emit-module",
2582+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2583+
"-I", cHeadersPath.nativePathString(escaped: true),
2584+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2585+
"-I", stdlibPath.nativePathString(escaped: true),
2586+
"-I", shimsPath.nativePathString(escaped: true),
2587+
"-explicit-module-build",
2588+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2589+
main.pathString])
2590+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2591+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2592+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2593+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.12")]))
2594+
}
2595+
}
2596+
2597+
// Only '-target' and '-target-variant' is specified, the driver infers '-clang-target' from SDK deployment target
2598+
// and '-clang-target-variant' form the
2599+
do {
2600+
try withTemporaryDirectory { path in
2601+
let main = path.appending(component: "testDependencyScanning.swift")
2602+
try localFileSystem.writeFileContents(main, bytes:
2603+
"""
2604+
import A;
2605+
"""
2606+
)
2607+
var driver = try Driver(args: ["swiftc",
2608+
"-target", "x86_64-apple-macosx10.10",
2609+
"-target-variant", "x86_64-apple-ios13.0-macabi",
2610+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2611+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2612+
"-emit-module",
2613+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2614+
"-I", cHeadersPath.nativePathString(escaped: true),
2615+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2616+
"-I", stdlibPath.nativePathString(escaped: true),
2617+
"-I", shimsPath.nativePathString(escaped: true),
2618+
"-explicit-module-build",
2619+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2620+
main.pathString])
2621+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2622+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2623+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2624+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.15")]))
2625+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target-variant"), .flag("x86_64-apple-ios13.1-macabi")]))
2626+
}
2627+
}
2628+
2629+
// User-specified '-clang-target' and '-clang-target-variant'
2630+
do {
2631+
try withTemporaryDirectory { path in
2632+
let main = path.appending(component: "testDependencyScanning.swift")
2633+
try localFileSystem.writeFileContents(main, bytes:
2634+
"""
2635+
import A;
2636+
"""
2637+
)
2638+
var driver = try Driver(args: ["swiftc",
2639+
"-target", "x86_64-apple-macosx10.10",
2640+
"-target-variant", "x86_64-apple-ios13.0-macabi",
2641+
"-clang-target", "x86_64-apple-macosx10.12",
2642+
"-clang-target-variant", "x86_64-apple-ios14.0-macabi",
2643+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2644+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2645+
"-emit-module",
2646+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2647+
"-I", cHeadersPath.nativePathString(escaped: true),
2648+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2649+
"-I", stdlibPath.nativePathString(escaped: true),
2650+
"-I", shimsPath.nativePathString(escaped: true),
2651+
"-explicit-module-build",
2652+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2653+
main.pathString])
2654+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2655+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2656+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2657+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.12")]))
2658+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target-variant"), .flag("x86_64-apple-ios14.0-macabi")]))
2659+
}
2660+
}
2661+
}
2662+
25272663
func testTargetVariantEmitModuleExplicit() throws {
25282664
let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning()
25292665
let cHeadersPath: AbsolutePath =
@@ -2556,8 +2692,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
25562692
"-emit-variant-module-path", "foo.swiftmodule/variant.swiftmodule",
25572693
"-emit-module-interface-path", "foo.swiftmodule/target.swiftinterface",
25582694
"-emit-variant-module-interface-path", "foo.swiftmodule/variant.swiftinterface",
2559-
"-disable-implicit-concurrency-module-import",
2560-
"-disable-implicit-string-processing-module-import",
2695+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2696+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
25612697
"-I", cHeadersPath.nativePathString(escaped: true),
25622698
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
25632699
"-I", stdlibPath.nativePathString(escaped: true),
@@ -2658,8 +2794,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
26582794
"-emit-module",
26592795
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
26602796
"-emit-variant-module-path", "foo.swiftmodule/variant.swiftmodule",
2661-
"-disable-implicit-concurrency-module-import",
2662-
"-disable-implicit-string-processing-module-import",
2797+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2798+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
26632799
"-I", cHeadersPath.nativePathString(escaped: true),
26642800
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
26652801
"-I", stdlibPath.nativePathString(escaped: true),

0 commit comments

Comments
 (0)