Skip to content

Commit 6750873

Browse files
committed
Propagate driver-specified clang-target flags even when no SDK is specified
1 parent 07413ed commit 6750873

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
@@ -2591,6 +2591,142 @@ final class ExplicitModuleBuildTests: XCTestCase {
25912591
}
25922592
}
25932593

2594+
func testClangTargetOptionsExplicit() throws {
2595+
let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning()
2596+
let cHeadersPath: AbsolutePath =
2597+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
2598+
.appending(component: "CHeaders")
2599+
let swiftModuleInterfacesPath: AbsolutePath =
2600+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
2601+
.appending(component: "Swift")
2602+
let mockSDKPath: AbsolutePath =
2603+
try testInputsPath.appending(component: "mock-sdk.sdk")
2604+
2605+
// Only '-target' is specified, the driver infers '-clang-target' from SDK deployment target
2606+
do {
2607+
try withTemporaryDirectory { path in
2608+
let main = path.appending(component: "testDependencyScanning.swift")
2609+
try localFileSystem.writeFileContents(main, bytes:
2610+
"""
2611+
import A;
2612+
"""
2613+
)
2614+
var driver = try Driver(args: ["swiftc",
2615+
"-target", "x86_64-apple-macosx10.10",
2616+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2617+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2618+
"-emit-module",
2619+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2620+
"-I", cHeadersPath.nativePathString(escaped: true),
2621+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2622+
"-I", stdlibPath.nativePathString(escaped: true),
2623+
"-I", shimsPath.nativePathString(escaped: true),
2624+
"-explicit-module-build",
2625+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2626+
main.pathString])
2627+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2628+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2629+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2630+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.15")]))
2631+
}
2632+
}
2633+
2634+
// User-specified '-clang-target'
2635+
do {
2636+
try withTemporaryDirectory { path in
2637+
let main = path.appending(component: "testDependencyScanning.swift")
2638+
try localFileSystem.writeFileContents(main, bytes:
2639+
"""
2640+
import A;
2641+
"""
2642+
)
2643+
var driver = try Driver(args: ["swiftc",
2644+
"-target", "x86_64-apple-macosx10.10",
2645+
"-clang-target", "x86_64-apple-macosx10.12",
2646+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2647+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2648+
"-emit-module",
2649+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2650+
"-I", cHeadersPath.nativePathString(escaped: true),
2651+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2652+
"-I", stdlibPath.nativePathString(escaped: true),
2653+
"-I", shimsPath.nativePathString(escaped: true),
2654+
"-explicit-module-build",
2655+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2656+
main.pathString])
2657+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2658+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2659+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2660+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.12")]))
2661+
}
2662+
}
2663+
2664+
// Only '-target' and '-target-variant' is specified, the driver infers '-clang-target' from SDK deployment target
2665+
// and '-clang-target-variant' form the
2666+
do {
2667+
try withTemporaryDirectory { path in
2668+
let main = path.appending(component: "testDependencyScanning.swift")
2669+
try localFileSystem.writeFileContents(main, bytes:
2670+
"""
2671+
import A;
2672+
"""
2673+
)
2674+
var driver = try Driver(args: ["swiftc",
2675+
"-target", "x86_64-apple-macosx10.10",
2676+
"-target-variant", "x86_64-apple-ios13.0-macabi",
2677+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2678+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2679+
"-emit-module",
2680+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2681+
"-I", cHeadersPath.nativePathString(escaped: true),
2682+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2683+
"-I", stdlibPath.nativePathString(escaped: true),
2684+
"-I", shimsPath.nativePathString(escaped: true),
2685+
"-explicit-module-build",
2686+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2687+
main.pathString])
2688+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2689+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2690+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2691+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.15")]))
2692+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target-variant"), .flag("x86_64-apple-ios13.1-macabi")]))
2693+
}
2694+
}
2695+
2696+
// User-specified '-clang-target' and '-clang-target-variant'
2697+
do {
2698+
try withTemporaryDirectory { path in
2699+
let main = path.appending(component: "testDependencyScanning.swift")
2700+
try localFileSystem.writeFileContents(main, bytes:
2701+
"""
2702+
import A;
2703+
"""
2704+
)
2705+
var driver = try Driver(args: ["swiftc",
2706+
"-target", "x86_64-apple-macosx10.10",
2707+
"-target-variant", "x86_64-apple-ios13.0-macabi",
2708+
"-clang-target", "x86_64-apple-macosx10.12",
2709+
"-clang-target-variant", "x86_64-apple-ios14.0-macabi",
2710+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2711+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2712+
"-emit-module",
2713+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2714+
"-I", cHeadersPath.nativePathString(escaped: true),
2715+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2716+
"-I", stdlibPath.nativePathString(escaped: true),
2717+
"-I", shimsPath.nativePathString(escaped: true),
2718+
"-explicit-module-build",
2719+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2720+
main.pathString])
2721+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2722+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2723+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2724+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.12")]))
2725+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target-variant"), .flag("x86_64-apple-ios14.0-macabi")]))
2726+
}
2727+
}
2728+
}
2729+
25942730
func testTargetVariantEmitModuleExplicit() throws {
25952731
let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning()
25962732
let cHeadersPath: AbsolutePath =
@@ -2623,8 +2759,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
26232759
"-emit-variant-module-path", "foo.swiftmodule/variant.swiftmodule",
26242760
"-emit-module-interface-path", "foo.swiftmodule/target.swiftinterface",
26252761
"-emit-variant-module-interface-path", "foo.swiftmodule/variant.swiftinterface",
2626-
"-disable-implicit-concurrency-module-import",
2627-
"-disable-implicit-string-processing-module-import",
2762+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2763+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
26282764
"-I", cHeadersPath.nativePathString(escaped: true),
26292765
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
26302766
"-I", stdlibPath.nativePathString(escaped: true),
@@ -2725,8 +2861,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
27252861
"-emit-module",
27262862
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
27272863
"-emit-variant-module-path", "foo.swiftmodule/variant.swiftmodule",
2728-
"-disable-implicit-concurrency-module-import",
2729-
"-disable-implicit-string-processing-module-import",
2864+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2865+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
27302866
"-I", cHeadersPath.nativePathString(escaped: true),
27312867
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
27322868
"-I", stdlibPath.nativePathString(escaped: true),

0 commit comments

Comments
 (0)