1818
1919#include < string>
2020#include < vector>
21+ #include < unordered_set>
2122
2223#include " swift/AST/DiagnosticsFrontend.h"
2324#include " swift/Frontend/Frontend.h"
@@ -112,6 +113,7 @@ class AutolinkExtractInvocation {
112113// / Return 'true' if there was an error, and 'false' otherwise.
113114static bool
114115extractLinkerFlagsFromObjectFile (const llvm::object::ObjectFile *ObjectFile,
116+ std::unordered_set<std::string> &SeenLinkerLibraryFlags,
115117 std::vector<std::string> &LinkerFlags,
116118 CompilerInstance &Instance) {
117119 // Search for the section we hold autolink entries in
@@ -140,8 +142,15 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
140142 llvm::SmallVector<llvm::StringRef, 4 > SplitFlags;
141143 SectionData->split (SplitFlags, llvm::StringRef (" \0 " , 1 ), -1 ,
142144 /* 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+ }
145154 }
146155 }
147156 return false ;
@@ -152,6 +161,7 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
152161// / 'true' if there was an error, and 'false' otherwise.
153162static bool
154163extractLinkerFlagsFromObjectFile (const llvm::object::WasmObjectFile *ObjectFile,
164+ std::unordered_set<std::string> &SeenLinkerLibraryFlags,
155165 std::vector<std::string> &LinkerFlags,
156166 CompilerInstance &Instance) {
157167 // Search for the data segment we hold autolink entries in
@@ -164,8 +174,15 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
164174 llvm::SmallVector<llvm::StringRef, 4 > SplitFlags;
165175 SegmentData.split (SplitFlags, llvm::StringRef (" \0 " , 1 ), -1 ,
166176 /* 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+ }
169186 }
170187 }
171188 return false ;
@@ -178,12 +195,13 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
178195static bool extractLinkerFlags (const llvm::object::Binary *Bin,
179196 CompilerInstance &Instance,
180197 StringRef BinaryFileName,
198+ std::unordered_set<std::string> &SeenLinkerLibraryFlags,
181199 std::vector<std::string> &LinkerFlags) {
182200 if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
183- return extractLinkerFlagsFromObjectFile (ObjectFile, LinkerFlags, Instance);
201+ return extractLinkerFlagsFromObjectFile (ObjectFile, SeenLinkerLibraryFlags, LinkerFlags, Instance);
184202 } else if (auto *ObjectFile =
185203 llvm::dyn_cast<llvm::object::WasmObjectFile>(Bin)) {
186- return extractLinkerFlagsFromObjectFile (ObjectFile, LinkerFlags, Instance);
204+ return extractLinkerFlagsFromObjectFile (ObjectFile, SeenLinkerLibraryFlags, LinkerFlags, Instance);
187205 } else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
188206 llvm::Error Error = llvm::Error::success ();
189207 for (const auto &Child : Archive->children (Error)) {
@@ -197,7 +215,7 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
197215 return true ;
198216 }
199217 if (extractLinkerFlags (ChildBinary->get (), Instance, BinaryFileName,
200- LinkerFlags)) {
218+ SeenLinkerLibraryFlags, LinkerFlags)) {
201219 return true ;
202220 }
203221 }
@@ -228,6 +246,8 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
228246 }
229247
230248 std::vector<std::string> LinkerFlags;
249+ // Flags of the form '-lxxx' seen so far
250+ std::unordered_set<std::string> SeenLinkerLibraryFlags;
231251
232252 // Extract the linker flags from the objects.
233253 for (const auto &BinaryFileName : Invocation.getInputFilenames ()) {
@@ -245,7 +265,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
245265 }
246266
247267 if (extractLinkerFlags (BinaryOwner->getBinary (), Instance, BinaryFileName,
248- LinkerFlags)) {
268+ SeenLinkerLibraryFlags, LinkerFlags)) {
249269 return 1 ;
250270 }
251271 }
0 commit comments