Skip to content

Commit d134679

Browse files
committed
[ELF] Don't pass ELF shared objects to autolink-extract
This is a version of swiftlang/swift#30465 for the new driver. Since shared objects are classified as `.object`, they end up getting passed to the autolink-extract job. For ELF platforms, this is unnecessary, since the autolink entries are not in the final shared object, so the autolink-extract process will not find any entries. Additionally, in ELF platforms, `.so` files can actually be linker scripts (text files) with instructions for the actual linker, which the autolink-extract job will not understand and will fail. For those two reasons, modify the autolink-extract inputs to skip over objects in ELF platforms that have the `.so` extension.
1 parent 03f3539 commit d134679

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,13 @@ extension Driver {
599599
addJob: (Job) -> Void)
600600
throws
601601
{
602-
let autolinkInputs = linkerInputs.filter { $0.type == .object }
602+
let autolinkInputs = linkerInputs.filter { input in
603+
// Shared objects on ELF platforms don't have a swift1_autolink_entries
604+
// section in them because the section in the .o files is marked as
605+
// SHF_EXCLUDE. They can also be linker scripts which swift-autolink-extract
606+
// does not handle.
607+
return input.type == .object && !(targetTriple.objectFormat == .elf && input.file.`extension` == "so")
608+
}
603609
if let autolinkExtractJob = try autolinkExtractJob(inputs: autolinkInputs) {
604610
addJob(autolinkExtractJob)
605611
autolinkExtractJob.outputs.forEach(addLinkerInput)

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,6 +2038,34 @@ final class SwiftDriverTests: XCTestCase {
20382038
XCTAssertFalse(cmd.contains(.flag("-static")))
20392039
}
20402040

2041+
do {
2042+
// Linux shared objects (.so) are not offered to autolink-extract
2043+
try withTemporaryDirectory { path in
2044+
try localFileSystem.writeFileContents(
2045+
path.appending(components: "libEmpty.so")) { $0 <<< "/* empty */" }
2046+
2047+
var driver = try Driver(args: commonArgs + ["-emit-executable", "-target", "x86_64-unknown-linux", "libEmpty.so"], env: env)
2048+
let plannedJobs = try driver.planBuild()
2049+
2050+
XCTAssertEqual(plannedJobs.count, 4)
2051+
2052+
let autolinkExtractJob = plannedJobs[2]
2053+
XCTAssertEqual(autolinkExtractJob.kind,.autolinkExtract)
2054+
2055+
let autolinkCmd = autolinkExtractJob.commandLine
2056+
XCTAssertTrue(commandContainsTemporaryPath(autolinkCmd, "foo.o"))
2057+
XCTAssertTrue(commandContainsTemporaryPath(autolinkCmd, "bar.o"))
2058+
XCTAssertTrue(commandContainsTemporaryPath(autolinkCmd, "Test.autolink"))
2059+
XCTAssertFalse(
2060+
autolinkCmd.contains {
2061+
guard case .path(let path) = $0 else { return false }
2062+
if case .relative(let p) = path, p.basename == "libEmpty.so" { return true }
2063+
return false
2064+
}
2065+
)
2066+
}
2067+
}
2068+
20412069
do {
20422070
// static linux linking
20432071
var driver = try Driver(args: commonArgs + ["-emit-library", "-static", "-target", "x86_64-unknown-linux"], env: env)

0 commit comments

Comments
 (0)