Skip to content

Commit 34c1abe

Browse files
committed
[Autolink Extract] Filter out common Swift libraries from being linked more than once
A partial solution to #58380
1 parent 7cb0c28 commit 34c1abe

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

lib/DriverTool/autolink_extract_main.cpp

Lines changed: 39 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> &CommonAddedSwiftLibraries,
116117
CompilerInstance &Instance) {
117118
// Search for the section we hold autolink entries in
118119
for (auto &Section : ObjectFile->sections()) {
@@ -140,8 +141,18 @@ 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+
// If it is one of the common Swift library flags,
146+
// only add if not seen before.
147+
if (auto It = CommonAddedSwiftLibraries.find(Flag.str());
148+
It != CommonAddedSwiftLibraries.end()) {
149+
if (It->second == false) {
150+
LinkerFlags.push_back(Flag.str());
151+
It->second = true;
152+
}
153+
} else
154+
LinkerFlags.push_back(Flag.str());
155+
}
145156
}
146157
}
147158
return false;
@@ -153,6 +164,7 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
153164
static bool
154165
extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
155166
std::vector<std::string> &LinkerFlags,
167+
std::unordered_map<std::string, bool> &CommonAddedSwiftLibraries,
156168
CompilerInstance &Instance) {
157169
// Search for the data segment we hold autolink entries in
158170
for (const llvm::object::WasmSegment &Segment : ObjectFile->dataSegments()) {
@@ -164,8 +176,18 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
164176
llvm::SmallVector<llvm::StringRef, 4> SplitFlags;
165177
SegmentData.split(SplitFlags, llvm::StringRef("\0", 1), -1,
166178
/*KeepEmpty=*/false);
167-
for (const auto &Flag : SplitFlags)
168-
LinkerFlags.push_back(Flag.str());
179+
for (const auto &Flag : SplitFlags) {
180+
// If it is one of the common Swift library flags,
181+
// only add if not seen before.
182+
if (auto It = CommonAddedSwiftLibraries.find(Flag.str());
183+
It != CommonAddedSwiftLibraries.end()) {
184+
if (It->second == false) {
185+
LinkerFlags.push_back(Flag.str());
186+
It->second = true;
187+
}
188+
} else
189+
LinkerFlags.push_back(Flag.str());
190+
}
169191
}
170192
}
171193
return false;
@@ -178,12 +200,13 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
178200
static bool extractLinkerFlags(const llvm::object::Binary *Bin,
179201
CompilerInstance &Instance,
180202
StringRef BinaryFileName,
181-
std::vector<std::string> &LinkerFlags) {
203+
std::vector<std::string> &LinkerFlags,
204+
std::unordered_map<std::string, bool> &CommonAddedSwiftLibraries) {
182205
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
183-
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance);
206+
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, CommonAddedSwiftLibraries, Instance);
184207
} else if (auto *ObjectFile =
185208
llvm::dyn_cast<llvm::object::WasmObjectFile>(Bin)) {
186-
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance);
209+
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, CommonAddedSwiftLibraries, Instance);
187210
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
188211
llvm::Error Error = llvm::Error::success();
189212
for (const auto &Child : Archive->children(Error)) {
@@ -197,7 +220,7 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
197220
return true;
198221
}
199222
if (extractLinkerFlags(ChildBinary->get(), Instance, BinaryFileName,
200-
LinkerFlags)) {
223+
LinkerFlags, CommonAddedSwiftLibraries)) {
201224
return true;
202225
}
203226
}
@@ -229,6 +252,13 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
229252

230253
std::vector<std::string> LinkerFlags;
231254

255+
// Keep track of whether we've already added the common
256+
// Swift libraries that ususally have autolink directives
257+
// in most object fiels
258+
std::unordered_map<std::string, bool> CommonAddedSwiftLibraries = {{"-lswiftSwiftOnoneSupport", false},
259+
{"-lswiftCore", false},
260+
{"-lswift_Concurrency", false}};
261+
232262
// Extract the linker flags from the objects.
233263
for (const auto &BinaryFileName : Invocation.getInputFilenames()) {
234264
auto BinaryOwner = llvm::object::createBinary(BinaryFileName);
@@ -245,7 +275,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
245275
}
246276

247277
if (extractLinkerFlags(BinaryOwner->getBinary(), Instance, BinaryFileName,
248-
LinkerFlags)) {
278+
LinkerFlags, CommonAddedSwiftLibraries)) {
249279
return 1;
250280
}
251281
}

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)