Skip to content

Commit 85fb228

Browse files
committed
Pass -platform_version to the linker when prelinking a target on Darwin platforms
rdar://154346861
1 parent 187d0ae commit 85fb228

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

Sources/SWBCore/SpecImplementations/Tools/PrelinkedObjectLink.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ public final class PrelinkedObjectLinkSpec: CommandLineToolSpec, SpecImplementat
3535
var commandLine = [toolSpecInfo.toolPath.str]
3636
commandLine += ["-r", "-arch", arch]
3737

38+
if let buildPlatform = cbc.producer.sdk?.targetBuildVersionPlatform(sdkVariant: cbc.producer.sdkVariant),
39+
let deploymentTargetMacro = cbc.producer.platform?.deploymentTargetMacro,
40+
let minDeploymentTarget = cbc.scope.evaluate(deploymentTargetMacro).nilIfEmpty,
41+
let sdkVersion = cbc.producer.sdk?.version {
42+
commandLine += ["-platform_version", "\(buildPlatform.rawValue)", minDeploymentTarget, sdkVersion.canonicalDeploymentTargetForm.description]
43+
}
44+
3845
// We do not pass the deployment target to the linker here. Instead the linker infers the platform and deployment target from the .o files being collected. We did briefly pass it to the linker to silence a linker warning - if we ever see issues here we should confer with the linker folks to make sure we do the right thing. See <rdar://problem/51800525> for more about the history here.
3946

4047
let sysroot = cbc.scope.evaluate(BuiltinMacros.SDK_DIR)

Tests/SWBBuildSystemTests/LinkerTests.swift

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,4 +360,72 @@ fileprivate struct LinkerTests: CoreBasedTests {
360360
}
361361
}
362362
}
363+
364+
@Test(.requireSDKs(.macOS))
365+
func prelinkingPropagatesPlatformVersion() async throws {
366+
func createProject(_ tmpDir: Path, enableInterop: Bool) -> TestProject {
367+
TestProject(
368+
"TestProject",
369+
sourceRoot: tmpDir,
370+
groupTree: TestGroup(
371+
"SomeFiles",
372+
children: [
373+
TestFile("main.c"),
374+
TestFile("lib.c"),
375+
]),
376+
targets: [
377+
TestStandardTarget(
378+
"cli", type: .commandLineTool,
379+
buildConfigurations: [
380+
TestBuildConfiguration(
381+
"Debug",
382+
buildSettings: [
383+
"PRODUCT_NAME": "$(TARGET_NAME)",
384+
"CODE_SIGNING_ALLOWED": "NO",
385+
"GENERATE_PRELINK_OBJECT_FILE": "YES",
386+
"GCC_SYMBOLS_PRIVATE_EXTERN": "NO",
387+
"MACOSX_DEPLOYMENT_TARGET": "13.0",
388+
])
389+
],
390+
buildPhases: [
391+
TestSourcesBuildPhase(["main.c"]),
392+
TestFrameworksBuildPhase([TestBuildFile(.target("lib"))])
393+
],
394+
dependencies: [TestTargetDependency("lib")]
395+
),
396+
TestStandardTarget(
397+
"lib", type: .staticLibrary,
398+
buildConfigurations: [
399+
TestBuildConfiguration(
400+
"Debug",
401+
buildSettings: [
402+
"PRODUCT_NAME": "$(TARGET_NAME)",
403+
"MACOSX_DEPLOYMENT_TARGET": "13.0",
404+
])
405+
],
406+
buildPhases: [
407+
TestSourcesBuildPhase(["lib.c"])
408+
]
409+
),
410+
])
411+
}
412+
413+
try await withTemporaryDirectory { tmpDir in
414+
let testProject = createProject(tmpDir, enableInterop: true)
415+
let tester = try await BuildOperationTester(getCore(), testProject, simulated: false)
416+
let projectDir = tester.workspace.projects[0].sourceRoot
417+
try await tester.fs.writeFileContents(projectDir.join("main.c")) { stream in
418+
stream <<< "int foo(void); int main(void) { foo(); }"
419+
}
420+
try await tester.fs.writeFileContents(projectDir.join("lib.c")) { stream in
421+
stream <<< "int foo(void) { return 42; }"
422+
}
423+
try await tester.checkBuild(runDestination: .macOS) { results in
424+
results.checkNoDiagnostics()
425+
results.checkTask(.matchRuleType("PrelinkedObjectLink")) { task in
426+
task.checkCommandLineContainsUninterrupted(["-platform_version", "1", "13.0"])
427+
}
428+
}
429+
}
430+
}
363431
}

0 commit comments

Comments
 (0)