18
18
19
19
#include < string>
20
20
#include < vector>
21
+ #include < unordered_set>
21
22
22
23
#include " swift/AST/DiagnosticsFrontend.h"
23
24
#include " swift/Frontend/Frontend.h"
@@ -112,6 +113,7 @@ class AutolinkExtractInvocation {
112
113
// / Return 'true' if there was an error, and 'false' otherwise.
113
114
static bool
114
115
extractLinkerFlagsFromObjectFile (const llvm::object::ObjectFile *ObjectFile,
116
+ std::unordered_set<std::string> &SeenLinkerLibraryFlags,
115
117
std::vector<std::string> &LinkerFlags,
116
118
CompilerInstance &Instance) {
117
119
// Search for the section we hold autolink entries in
@@ -140,8 +142,15 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
140
142
llvm::SmallVector<llvm::StringRef, 4 > SplitFlags;
141
143
SectionData->split (SplitFlags, llvm::StringRef (" \0 " , 1 ), -1 ,
142
144
/* KeepEmpty=*/ false );
143
- for (const auto &Flag : SplitFlags)
144
- LinkerFlags.push_back (Flag.str ());
145
+ for (const auto &Flag : SplitFlags) {
146
+ // If this is a library '-lxxx' flag, only add it if we have not seen it before
147
+ if (Flag.str ().rfind (" -l" , 0 ) == 0 ) {
148
+ auto SeenFlagsInsertResult = SeenLinkerLibraryFlags.insert (Flag.str ());
149
+ if (SeenFlagsInsertResult.second == true )
150
+ LinkerFlags.push_back (Flag.str ());
151
+ } else
152
+ LinkerFlags.push_back (Flag.str ());
153
+ }
145
154
}
146
155
}
147
156
return false ;
@@ -152,6 +161,7 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
152
161
// / 'true' if there was an error, and 'false' otherwise.
153
162
static bool
154
163
extractLinkerFlagsFromObjectFile (const llvm::object::WasmObjectFile *ObjectFile,
164
+ std::unordered_set<std::string> &SeenLinkerLibraryFlags,
155
165
std::vector<std::string> &LinkerFlags,
156
166
CompilerInstance &Instance) {
157
167
// Search for the data segment we hold autolink entries in
@@ -164,8 +174,15 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
164
174
llvm::SmallVector<llvm::StringRef, 4 > SplitFlags;
165
175
SegmentData.split (SplitFlags, llvm::StringRef (" \0 " , 1 ), -1 ,
166
176
/* KeepEmpty=*/ false );
167
- for (const auto &Flag : SplitFlags)
168
- LinkerFlags.push_back (Flag.str ());
177
+ for (const auto &Flag : SplitFlags) {
178
+ // If this is a library '-lxxx' flag, only add it if we have not seen it before
179
+ if (Flag.str ().rfind (" -l" , 0 ) == 0 ) {
180
+ auto SeenFlagsInsertResult = SeenLinkerLibraryFlags.insert (Flag.str ());
181
+ if (SeenFlagsInsertResult.second == true )
182
+ LinkerFlags.push_back (Flag.str ());
183
+ } else
184
+ LinkerFlags.push_back (Flag.str ());
185
+ }
169
186
}
170
187
}
171
188
return false ;
@@ -178,12 +195,13 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
178
195
static bool extractLinkerFlags (const llvm::object::Binary *Bin,
179
196
CompilerInstance &Instance,
180
197
StringRef BinaryFileName,
198
+ std::unordered_set<std::string> &SeenLinkerLibraryFlags,
181
199
std::vector<std::string> &LinkerFlags) {
182
200
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
183
- return extractLinkerFlagsFromObjectFile (ObjectFile, LinkerFlags, Instance);
201
+ return extractLinkerFlagsFromObjectFile (ObjectFile, SeenLinkerLibraryFlags, LinkerFlags, Instance);
184
202
} else if (auto *ObjectFile =
185
203
llvm::dyn_cast<llvm::object::WasmObjectFile>(Bin)) {
186
- return extractLinkerFlagsFromObjectFile (ObjectFile, LinkerFlags, Instance);
204
+ return extractLinkerFlagsFromObjectFile (ObjectFile, SeenLinkerLibraryFlags, LinkerFlags, Instance);
187
205
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
188
206
llvm::Error Error = llvm::Error::success ();
189
207
for (const auto &Child : Archive->children (Error)) {
@@ -197,7 +215,7 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
197
215
return true ;
198
216
}
199
217
if (extractLinkerFlags (ChildBinary->get (), Instance, BinaryFileName,
200
- LinkerFlags)) {
218
+ SeenLinkerLibraryFlags, LinkerFlags)) {
201
219
return true ;
202
220
}
203
221
}
@@ -228,6 +246,8 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
228
246
}
229
247
230
248
std::vector<std::string> LinkerFlags;
249
+ // Flags of the form '-lxxx' seen so far
250
+ std::unordered_set<std::string> SeenLinkerLibraryFlags;
231
251
232
252
// Extract the linker flags from the objects.
233
253
for (const auto &BinaryFileName : Invocation.getInputFilenames ()) {
@@ -245,7 +265,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
245
265
}
246
266
247
267
if (extractLinkerFlags (BinaryOwner->getBinary (), Instance, BinaryFileName,
248
- LinkerFlags)) {
268
+ SeenLinkerLibraryFlags, LinkerFlags)) {
249
269
return 1 ;
250
270
}
251
271
}
0 commit comments