Skip to content

Commit 0bf6fc3

Browse files
authored
Merge pull request #59063 from artemcm/AutoLinkExtractFilterCommon
[Autolink Extract] Filter out common Swift libraries from being linked more than once
2 parents 84c547a + 3d30527 commit 0bf6fc3

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

lib/DriverTool/autolink_extract_main.cpp

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class AutolinkExtractInvocation {
113113
static bool
114114
extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
115115
std::vector<std::string> &LinkerFlags,
116+
std::unordered_map<std::string, bool> &SwiftRuntimeLibraries,
116117
CompilerInstance &Instance) {
117118
// Search for the section we hold autolink entries in
118119
for (auto &Section : ObjectFile->sections()) {
@@ -140,8 +141,13 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
140141
llvm::SmallVector<llvm::StringRef, 4> SplitFlags;
141142
SectionData->split(SplitFlags, llvm::StringRef("\0", 1), -1,
142143
/*KeepEmpty=*/false);
143-
for (const auto &Flag : SplitFlags)
144-
LinkerFlags.push_back(Flag.str());
144+
for (const auto &Flag : SplitFlags) {
145+
auto RuntimeLibEntry = SwiftRuntimeLibraries.find(Flag.str());
146+
if (RuntimeLibEntry == SwiftRuntimeLibraries.end())
147+
LinkerFlags.emplace_back(Flag.str());
148+
else
149+
RuntimeLibEntry->second = true;
150+
}
145151
}
146152
}
147153
return false;
@@ -153,6 +159,7 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
153159
static bool
154160
extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
155161
std::vector<std::string> &LinkerFlags,
162+
std::unordered_map<std::string, bool> &SwiftRuntimeLibraries,
156163
CompilerInstance &Instance) {
157164
// Search for the data segment we hold autolink entries in
158165
for (const llvm::object::WasmSegment &Segment : ObjectFile->dataSegments()) {
@@ -164,8 +171,13 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
164171
llvm::SmallVector<llvm::StringRef, 4> SplitFlags;
165172
SegmentData.split(SplitFlags, llvm::StringRef("\0", 1), -1,
166173
/*KeepEmpty=*/false);
167-
for (const auto &Flag : SplitFlags)
168-
LinkerFlags.push_back(Flag.str());
174+
for (const auto &Flag : SplitFlags) {
175+
auto RuntimeLibEntry = SwiftRuntimeLibraries.find(Flag.str());
176+
if (RuntimeLibEntry == SwiftRuntimeLibraries.end())
177+
LinkerFlags.emplace_back(Flag.str());
178+
else
179+
RuntimeLibEntry->second = true;
180+
}
169181
}
170182
}
171183
return false;
@@ -178,12 +190,13 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
178190
static bool extractLinkerFlags(const llvm::object::Binary *Bin,
179191
CompilerInstance &Instance,
180192
StringRef BinaryFileName,
181-
std::vector<std::string> &LinkerFlags) {
193+
std::vector<std::string> &LinkerFlags,
194+
std::unordered_map<std::string, bool> &SwiftRuntimeLibraries) {
182195
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
183-
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance);
196+
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, SwiftRuntimeLibraries, Instance);
184197
} else if (auto *ObjectFile =
185198
llvm::dyn_cast<llvm::object::WasmObjectFile>(Bin)) {
186-
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance);
199+
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, SwiftRuntimeLibraries, Instance);
187200
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
188201
llvm::Error Error = llvm::Error::success();
189202
for (const auto &Child : Archive->children(Error)) {
@@ -197,7 +210,7 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
197210
return true;
198211
}
199212
if (extractLinkerFlags(ChildBinary->get(), Instance, BinaryFileName,
200-
LinkerFlags)) {
213+
LinkerFlags, SwiftRuntimeLibraries)) {
201214
return true;
202215
}
203216
}
@@ -229,6 +242,15 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
229242

230243
std::vector<std::string> LinkerFlags;
231244

245+
// Keep track of whether we've already added the common
246+
// Swift libraries that ususally have autolink directives
247+
// in most object fiels
248+
std::unordered_map<std::string, bool> SwiftRuntimeLibraries = {
249+
{"-lswiftSwiftOnoneSupport", false},
250+
{"-lswiftCore", false},
251+
{"-lswift_Concurrency", false},
252+
};
253+
232254
// Extract the linker flags from the objects.
233255
for (const auto &BinaryFileName : Invocation.getInputFilenames()) {
234256
auto BinaryOwner = llvm::object::createBinary(BinaryFileName);
@@ -245,7 +267,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
245267
}
246268

247269
if (extractLinkerFlags(BinaryOwner->getBinary(), Instance, BinaryFileName,
248-
LinkerFlags)) {
270+
LinkerFlags, SwiftRuntimeLibraries)) {
249271
return 1;
250272
}
251273
}
@@ -264,5 +286,11 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
264286
OutOS << Flag << '\n';
265287
}
266288

289+
for (const auto &RuntimeLib : SwiftRuntimeLibraries) {
290+
if (RuntimeLib.second)
291+
OutOS << RuntimeLib.first << '\n';
292+
}
293+
294+
267295
return 0;
268296
}

test/AutolinkExtract/import.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
// RUN: %target-swiftc_driver -emit-module -emit-module-path %t/empty.swiftmodule -module-name empty -module-link-name empty %S/empty.swift
33
// RUN: %target-swiftc_driver -c %s -I %t -o %t/import_experimental.o
44
// RUN: %target-swift-autolink-extract %t/import_experimental.o -o - | %FileCheck --check-prefix CHECK-%target-object-format %s
5+
// RUN: %target-swiftc_driver -c %s -I %t -o %t/import_experimental_again.o
6+
// RUN: %target-swift-autolink-extract %t/import_experimental.o %t/import_experimental_again.o -o - | %FileCheck --check-prefix CHECK-%target-object-format %s
7+
// RUN: %target-swift-autolink-extract %t/import_experimental.o %t/import_experimental_again.o -o - | %FileCheck --check-prefix UNIQUE %s
58

69
// REQUIRES: autolink-extract
710

11+
// UNIQUE-COUNT-1: -lswiftCore
12+
813
// CHECK-elf-DAG: -lswiftCore
914
// CHECK-elf-DAG: -lempty
1015

0 commit comments

Comments
 (0)