Skip to content

Commit 26be248

Browse files
authored
Merge pull request #654 from owenv/owenv/prelink-platform-version
Pass -platform_version to the linker when prelinking a target on Darwin platforms
2 parents 558048b + 58ce7eb commit 26be248

File tree

4 files changed

+81
-6
lines changed

4 files changed

+81
-6
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
}

Tests/SWBTaskConstructionTests/PrelinkedObjectFileTests.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fileprivate struct PrelinkedObjectFileTests: CoreBasedTests {
7373
results.checkTarget("AllLibraries") { target in
7474
// There should be tasks to create the prelinked object file and then the static library.
7575
results.checkTask(.matchTarget(target), .matchRuleType("PrelinkedObjectLink")) { task in
76-
task.checkCommandLineMatches([.suffix("ld"), "-r", "-arch", "x86_64", "-syslibroot", .equal(core.loadSDK(.macOS).path.str), "-exported_symbols_list", "Exports.exp", "-lWarningLibrary", "-lSomeLibrary", "-lAnotherLibrary", "-o", .equal("\(SRCROOT)/build/aProject.build/Debug/AllLibraries.build/Objects-normal/libAllLibraries.a-x86_64-prelink.o")])
76+
task.checkCommandLineMatches([.suffix("ld"), "-r", "-arch", "x86_64", "-platform_version", "1", .any, .any, "-syslibroot", .equal(core.loadSDK(.macOS).path.str), "-exported_symbols_list", "Exports.exp", "-lWarningLibrary", "-lSomeLibrary", "-lAnotherLibrary", "-o", .equal("\(SRCROOT)/build/aProject.build/Debug/AllLibraries.build/Objects-normal/libAllLibraries.a-x86_64-prelink.o")])
7777
}
7878
results.checkTask(.matchTarget(target), .matchRuleType("Libtool")) { task in
7979
task.checkCommandLineMatches([.suffix("libtool"), "-static", "-arch_only", "x86_64", "-D", "-syslibroot", .equal(core.loadSDK(.macOS).path.str), .equal("-L\(SRCROOT)/build/Debug"), "-filelist", .equal("\(SRCROOT)/build/aProject.build/Debug/AllLibraries.build/Objects-normal/x86_64/AllLibraries.LinkFileList"), "-dependency_info", "\(SRCROOT)/build/aProject.build/Debug/AllLibraries.build/Objects-normal/x86_64/AllLibraries_libtool_dependency_info.dat", "-o", .equal("\(SRCROOT)/build/Debug/libAllLibraries.a")])
@@ -102,7 +102,7 @@ fileprivate struct PrelinkedObjectFileTests: CoreBasedTests {
102102
results.checkTarget("AllLibraries") { target in
103103
// There should be tasks to create the prelinked object file and then the static library.
104104
results.checkTask(.matchTarget(target), .matchRuleType("PrelinkedObjectLink")) { task in
105-
task.checkCommandLineMatches([.suffix("ld"), "-r", "-arch", "x86_64", "-syslibroot", .equal(core.loadSDK(.macOS).path.str), "-exported_symbols_list", "Exports.exp", "-lWarningLibrary", "-lSomeLibrary", "-lAnotherLibrary", "-o", .equal("\(SRCROOT)/build/aProject.build/Debug/AllLibraries.build/Objects-normal/libAllLibraries.a-x86_64-prelink.o")])
105+
task.checkCommandLineMatches([.suffix("ld"), "-r", "-arch", "x86_64", "-platform_version", "1", .any, .any, "-syslibroot", .equal(core.loadSDK(.macOS).path.str), "-exported_symbols_list", "Exports.exp", "-lWarningLibrary", "-lSomeLibrary", "-lAnotherLibrary", "-o", .equal("\(SRCROOT)/build/aProject.build/Debug/AllLibraries.build/Objects-normal/libAllLibraries.a-x86_64-prelink.o")])
106106
}
107107
results.checkTask(.matchTarget(target), .matchRuleType("Libtool")) { task in
108108
task.checkCommandLineMatches([.suffix("libtool"), "-static", "-arch_only", "x86_64", "-D", "-syslibroot", .equal(core.loadSDK(.macOS).path.str), .equal("-L\(SRCROOT)/build/Debug/BuiltProducts"), "-filelist", .equal("\(SRCROOT)/build/aProject.build/Debug/AllLibraries.build/Objects-normal/x86_64/AllLibraries.LinkFileList"), "-dependency_info", "\(SRCROOT)/build/aProject.build/Debug/AllLibraries.build/Objects-normal/x86_64/AllLibraries_libtool_dependency_info.dat", "-o", "/tmp/aProject.dst/usr/local/lib/libAllLibraries.a"])
@@ -203,7 +203,7 @@ fileprivate struct PrelinkedObjectFileTests: CoreBasedTests {
203203
results.checkTarget("AllLibraries") { target in
204204
// There should be tasks to create the prelinked object file and then the static library.
205205
results.checkTask(.matchTarget(target), .matchRuleType("PrelinkedObjectLink")) { task in
206-
task.checkCommandLineMatches([.suffix("ld"), "-r", "-arch", "x86_64", "-syslibroot", .equal(core.loadSDK(.macOS).path.str), "-o", .equal("\(SRCROOT)/build/aProject.build/Debug-maccatalyst/AllLibraries.build/Objects-normal/libAllLibraries.a-x86_64-prelink.o")])
206+
task.checkCommandLineMatches([.suffix("ld"), "-r", "-arch", "x86_64", "-platform_version", "6", .any, .any, "-syslibroot", .equal(core.loadSDK(.macOS).path.str), "-o", .equal("\(SRCROOT)/build/aProject.build/Debug-maccatalyst/AllLibraries.build/Objects-normal/libAllLibraries.a-x86_64-prelink.o")])
207207
}
208208
results.checkTask(.matchTarget(target), .matchRuleType("Libtool")) { task in
209209
task.checkCommandLineMatches([.suffix("libtool"), "-static", "-arch_only", "x86_64", "-D", "-syslibroot", .equal(core.loadSDK(.macOS).path.str), .equal("-L\(SRCROOT)/build/Debug-maccatalyst"), "-L\(core.loadSDK(.macOS).path.str)/System/iOSSupport/usr/lib", "-L\(core.developerPath.path.str)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/maccatalyst", "-L\(core.loadSDK(.macOS).path.str)/System/iOSSupport/usr/lib", "-L\(core.developerPath.path.str)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/maccatalyst", "-filelist", .equal("\(SRCROOT)/build/aProject.build/Debug-maccatalyst/AllLibraries.build/Objects-normal/x86_64/AllLibraries.LinkFileList"), "-dependency_info", "\(SRCROOT)/build/aProject.build/Debug-maccatalyst/AllLibraries.build/Objects-normal/x86_64/AllLibraries_libtool_dependency_info.dat", "-o", .equal("\(SRCROOT)/build/Debug-maccatalyst/libAllLibraries.a")])
@@ -272,7 +272,7 @@ fileprivate struct PrelinkedObjectFileTests: CoreBasedTests {
272272
results.checkTarget("AllLibraries") { target in
273273
// There should be tasks to create the prelinked object file and then the static library.
274274
results.checkTask(.matchTarget(target), .matchRuleType("PrelinkedObjectLink")) { task in
275-
task.checkCommandLineMatches([.suffix("ld"), "-r", "-arch", "arm64", "-syslibroot", .equal(results.runDestinationSDK.path.str), "-o", .equal("\(SRCROOT)/build/aProject.build/Debug-iphoneos/AllLibraries.build/Objects-normal/libAllLibraries.a-arm64-prelink.o")])
275+
task.checkCommandLineMatches([.suffix("ld"), "-r", "-arch", "arm64", "-platform_version", "2", .any, .any, "-syslibroot", .equal(results.runDestinationSDK.path.str), "-o", .equal("\(SRCROOT)/build/aProject.build/Debug-iphoneos/AllLibraries.build/Objects-normal/libAllLibraries.a-arm64-prelink.o")])
276276
}
277277
results.checkTask(.matchTarget(target), .matchRuleType("Libtool")) { task in
278278
task.checkCommandLineMatches([.suffix("libtool"), "-static", "-arch_only", "arm64", "-D", "-syslibroot", .equal(results.runDestinationSDK.path.str), .equal("-L\(SRCROOT)/build/Debug-iphoneos"), "-filelist", .equal("\(SRCROOT)/build/aProject.build/Debug-iphoneos/AllLibraries.build/Objects-normal/arm64/AllLibraries.LinkFileList"), "-dependency_info", "\(SRCROOT)/build/aProject.build/Debug-iphoneos/AllLibraries.build/Objects-normal/arm64/AllLibraries_libtool_dependency_info.dat", "-o", .equal("\(SRCROOT)/build/Debug-iphoneos/libAllLibraries.a")])
@@ -340,7 +340,7 @@ fileprivate struct PrelinkedObjectFileTests: CoreBasedTests {
340340
results.checkTarget("AllLibraries") { target in
341341
// There should be tasks to create the prelinked object file and then the static library.
342342
results.checkTask(.matchTarget(target), .matchRuleType("PrelinkedObjectLink")) { task in
343-
task.checkCommandLineMatches([.suffix("ld"), "-r", "-arch", "x86_64", "-syslibroot", .equal(results.runDestinationSDK.path.str), "-o", .equal("\(SRCROOT)/build/aProject.build/Debug-iphonesimulator/AllLibraries.build/Objects-normal/libAllLibraries.a-x86_64-prelink.o")])
343+
task.checkCommandLineMatches([.suffix("ld"), "-r", "-arch", "x86_64", "-platform_version", "7", .any, .any, "-syslibroot", .equal(results.runDestinationSDK.path.str), "-o", .equal("\(SRCROOT)/build/aProject.build/Debug-iphonesimulator/AllLibraries.build/Objects-normal/libAllLibraries.a-x86_64-prelink.o")])
344344
}
345345
results.checkTask(.matchTarget(target), .matchRuleType("Libtool")) { task in
346346
task.checkCommandLineMatches([.suffix("libtool"), "-static", "-arch_only", "x86_64", "-D", "-syslibroot", .equal(results.runDestinationSDK.path.str), .equal("-L\(SRCROOT)/build/Debug-iphonesimulator"), "-filelist", .equal("\(SRCROOT)/build/aProject.build/Debug-iphonesimulator/AllLibraries.build/Objects-normal/x86_64/AllLibraries.LinkFileList"), "-dependency_info", "\(SRCROOT)/build/aProject.build/Debug-iphonesimulator/AllLibraries.build/Objects-normal/x86_64/AllLibraries_libtool_dependency_info.dat", "-o", .equal("\(SRCROOT)/build/Debug-iphonesimulator/libAllLibraries.a")])

Tests/SWBTaskConstructionTests/TaskConstructionTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ fileprivate struct TaskConstructionTests: CoreBasedTests {
895895
}
896896

897897
#expect(nonUniqueObjs[0] != nonUniqueObjs[1])
898-
task.checkCommandLineMatches([StringPattern.suffix("ld"), "-r", "-arch", "x86_64", "-syslibroot", .equal(core.loadSDK(.macOS).path.str), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/SourceFile.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/SourceFile-Matched-Excluded.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/SourceFile-Matched-Included.o"), .equal(nonUniqueObjs[0]), .equal(nonUniqueObjs[1]), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/SourceFile_MRR.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/Lex.yy.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/y.tab.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/Script-Output-Custom-SourceFile.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/Script-Output-Standard-SourceFile.o"), "-o", .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/AppTarget-x86_64-prelink.o")])
898+
task.checkCommandLineMatches([StringPattern.suffix("ld"), "-r", "-arch", "x86_64", "-platform_version", "1", .any, .any, "-syslibroot", .equal(core.loadSDK(.macOS).path.str), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/SourceFile.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/SourceFile-Matched-Excluded.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/SourceFile-Matched-Included.o"), .equal(nonUniqueObjs[0]), .equal(nonUniqueObjs[1]), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/SourceFile_MRR.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/Lex.yy.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/y.tab.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/Script-Output-Custom-SourceFile.o"), .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/Script-Output-Standard-SourceFile.o"), "-o", .equal("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/AppTarget-x86_64-prelink.o")])
899899

900900
task.checkInputs([
901901
.path("\(SRCROOT)/build/aProject.build/Release/AppTarget.build/Objects-normal/x86_64/SourceFile.o"),

0 commit comments

Comments
 (0)