Skip to content

Commit 91811bb

Browse files
committed
Propagate driver-specified clang-target flags even when no SDK is specified
1 parent ecefd23 commit 91811bb

File tree

6 files changed

+203
-51
lines changed

6 files changed

+203
-51
lines changed

Sources/SwiftDriver/Driver/Driver.swift

+7-1
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)"} ?? "")
@@ -3091,7 +3094,10 @@ extension Driver {
30913094
if !fileSystem.exists(path.parentDirectory) {
30923095
try fileSystem.createDirectory(path.parentDirectory, recursive: true)
30933096
}
3094-
return try VirtualPath.createBuildProductFileWithKnownContents(path, chainedHeader.content.data(using: .utf8)!).intern()
3097+
guard let headerData = chainedHeader.content.data(using: .utf8) else {
3098+
throw Driver.Error.malformedChainedBridgingHeader(chainedHeader.content)
3099+
}
3100+
return try VirtualPath.createBuildProductFileWithKnownContents(path, headerData).intern()
30953101
}
30963102
return originalObjCHeaderFile
30973103
}

Sources/SwiftDriver/Jobs/ReplJob.swift

+1-2
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

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

401450
commandLine.append(.flag("-target-sdk-version"))
402451
commandLine.append(.flag(sdkInfo.sdkVersion(for: frontendTargetInfo.target.triple).sdkVersionString))
@@ -439,45 +488,6 @@ public final class DarwinToolchain: Toolchain {
439488
commandLine.appendPath(prebuiltModulesPath)
440489
}
441490

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

Sources/SwiftDriver/Utilities/VirtualPath.swift

+2-1
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.
+2-2
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

+140-4
Original file line numberDiff line numberDiff line change
@@ -2457,6 +2457,142 @@ final class ExplicitModuleBuildTests: XCTestCase {
24572457
}
24582458
}
24592459

2460+
func testClangTargetOptionsExplicit() throws {
2461+
let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning()
2462+
let cHeadersPath: AbsolutePath =
2463+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
2464+
.appending(component: "CHeaders")
2465+
let swiftModuleInterfacesPath: AbsolutePath =
2466+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
2467+
.appending(component: "Swift")
2468+
let mockSDKPath: AbsolutePath =
2469+
try testInputsPath.appending(component: "mock-sdk.sdk")
2470+
2471+
// Only '-target' is specified, the driver infers '-clang-target' from SDK deployment target
2472+
do {
2473+
try withTemporaryDirectory { path in
2474+
let main = path.appending(component: "testDependencyScanning.swift")
2475+
try localFileSystem.writeFileContents(main, bytes:
2476+
"""
2477+
import A;
2478+
"""
2479+
)
2480+
var driver = try Driver(args: ["swiftc",
2481+
"-target", "x86_64-apple-macosx10.10",
2482+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2483+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2484+
"-emit-module",
2485+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2486+
"-I", cHeadersPath.nativePathString(escaped: true),
2487+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2488+
"-I", stdlibPath.nativePathString(escaped: true),
2489+
"-I", shimsPath.nativePathString(escaped: true),
2490+
"-explicit-module-build",
2491+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2492+
main.pathString])
2493+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2494+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2495+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2496+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.15")]))
2497+
}
2498+
}
2499+
2500+
// User-specified '-clang-target'
2501+
do {
2502+
try withTemporaryDirectory { path in
2503+
let main = path.appending(component: "testDependencyScanning.swift")
2504+
try localFileSystem.writeFileContents(main, bytes:
2505+
"""
2506+
import A;
2507+
"""
2508+
)
2509+
var driver = try Driver(args: ["swiftc",
2510+
"-target", "x86_64-apple-macosx10.10",
2511+
"-clang-target", "x86_64-apple-macosx10.12",
2512+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2513+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2514+
"-emit-module",
2515+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2516+
"-I", cHeadersPath.nativePathString(escaped: true),
2517+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2518+
"-I", stdlibPath.nativePathString(escaped: true),
2519+
"-I", shimsPath.nativePathString(escaped: true),
2520+
"-explicit-module-build",
2521+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2522+
main.pathString])
2523+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2524+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2525+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2526+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.12")]))
2527+
}
2528+
}
2529+
2530+
// Only '-target' and '-target-variant' is specified, the driver infers '-clang-target' from SDK deployment target
2531+
// and '-clang-target-variant' form the
2532+
do {
2533+
try withTemporaryDirectory { path in
2534+
let main = path.appending(component: "testDependencyScanning.swift")
2535+
try localFileSystem.writeFileContents(main, bytes:
2536+
"""
2537+
import A;
2538+
"""
2539+
)
2540+
var driver = try Driver(args: ["swiftc",
2541+
"-target", "x86_64-apple-macosx10.10",
2542+
"-target-variant", "x86_64-apple-ios13.0-macabi",
2543+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2544+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2545+
"-emit-module",
2546+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2547+
"-I", cHeadersPath.nativePathString(escaped: true),
2548+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2549+
"-I", stdlibPath.nativePathString(escaped: true),
2550+
"-I", shimsPath.nativePathString(escaped: true),
2551+
"-explicit-module-build",
2552+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2553+
main.pathString])
2554+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2555+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2556+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2557+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.15")]))
2558+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target-variant"), .flag("x86_64-apple-ios13.1-macabi")]))
2559+
}
2560+
}
2561+
2562+
// User-specified '-clang-target' and '-clang-target-variant'
2563+
do {
2564+
try withTemporaryDirectory { path in
2565+
let main = path.appending(component: "testDependencyScanning.swift")
2566+
try localFileSystem.writeFileContents(main, bytes:
2567+
"""
2568+
import A;
2569+
"""
2570+
)
2571+
var driver = try Driver(args: ["swiftc",
2572+
"-target", "x86_64-apple-macosx10.10",
2573+
"-target-variant", "x86_64-apple-ios13.0-macabi",
2574+
"-clang-target", "x86_64-apple-macosx10.12",
2575+
"-clang-target-variant", "x86_64-apple-ios14.0-macabi",
2576+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2577+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
2578+
"-emit-module",
2579+
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
2580+
"-I", cHeadersPath.nativePathString(escaped: true),
2581+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
2582+
"-I", stdlibPath.nativePathString(escaped: true),
2583+
"-I", shimsPath.nativePathString(escaped: true),
2584+
"-explicit-module-build",
2585+
"-sdk", mockSDKPath.nativePathString(escaped: true),
2586+
main.pathString])
2587+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2588+
let emitModuleJob = try XCTUnwrap(plannedJobs.findJobs(.emitModule).spm_only)
2589+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-sdk"), .path(.absolute(mockSDKPath))]))
2590+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target"), .flag("x86_64-apple-macosx10.12")]))
2591+
XCTAssertTrue(emitModuleJob.commandLine.contains(subsequence: [.flag("-clang-target-variant"), .flag("x86_64-apple-ios14.0-macabi")]))
2592+
}
2593+
}
2594+
}
2595+
24602596
func testTargetVariantEmitModuleExplicit() throws {
24612597
let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning()
24622598
let cHeadersPath: AbsolutePath =
@@ -2489,8 +2625,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
24892625
"-emit-variant-module-path", "foo.swiftmodule/variant.swiftmodule",
24902626
"-emit-module-interface-path", "foo.swiftmodule/target.swiftinterface",
24912627
"-emit-variant-module-interface-path", "foo.swiftmodule/variant.swiftinterface",
2492-
"-disable-implicit-concurrency-module-import",
2493-
"-disable-implicit-string-processing-module-import",
2628+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2629+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
24942630
"-I", cHeadersPath.nativePathString(escaped: true),
24952631
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
24962632
"-I", stdlibPath.nativePathString(escaped: true),
@@ -2591,8 +2727,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
25912727
"-emit-module",
25922728
"-emit-module-path", "foo.swiftmodule/target.swiftmodule",
25932729
"-emit-variant-module-path", "foo.swiftmodule/variant.swiftmodule",
2594-
"-disable-implicit-concurrency-module-import",
2595-
"-disable-implicit-string-processing-module-import",
2730+
"-Xfrontend", "-disable-implicit-concurrency-module-import",
2731+
"-Xfrontend", "-disable-implicit-string-processing-module-import",
25962732
"-I", cHeadersPath.nativePathString(escaped: true),
25972733
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
25982734
"-I", stdlibPath.nativePathString(escaped: true),

0 commit comments

Comments
 (0)