Skip to content

Commit

Permalink
[Autolink Extract] Filter out common Swift libraries from being linke…
Browse files Browse the repository at this point in the history
…d more than once

A partial solution to swiftlang#58380
  • Loading branch information
artemcm committed May 24, 2022
1 parent 7cb0c28 commit 34c1abe
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 9 deletions.
48 changes: 39 additions & 9 deletions lib/DriverTool/autolink_extract_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class AutolinkExtractInvocation {
static bool
extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
std::vector<std::string> &LinkerFlags,
std::unordered_map<std::string, bool> &CommonAddedSwiftLibraries,
CompilerInstance &Instance) {
// Search for the section we hold autolink entries in
for (auto &Section : ObjectFile->sections()) {
Expand Down Expand Up @@ -140,8 +141,18 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
llvm::SmallVector<llvm::StringRef, 4> SplitFlags;
SectionData->split(SplitFlags, llvm::StringRef("\0", 1), -1,
/*KeepEmpty=*/false);
for (const auto &Flag : SplitFlags)
LinkerFlags.push_back(Flag.str());
for (const auto &Flag : SplitFlags) {
// If it is one of the common Swift library flags,
// only add if not seen before.
if (auto It = CommonAddedSwiftLibraries.find(Flag.str());
It != CommonAddedSwiftLibraries.end()) {
if (It->second == false) {
LinkerFlags.push_back(Flag.str());
It->second = true;
}
} else
LinkerFlags.push_back(Flag.str());
}
}
}
return false;
Expand All @@ -153,6 +164,7 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
static bool
extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
std::vector<std::string> &LinkerFlags,
std::unordered_map<std::string, bool> &CommonAddedSwiftLibraries,
CompilerInstance &Instance) {
// Search for the data segment we hold autolink entries in
for (const llvm::object::WasmSegment &Segment : ObjectFile->dataSegments()) {
Expand All @@ -164,8 +176,18 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
llvm::SmallVector<llvm::StringRef, 4> SplitFlags;
SegmentData.split(SplitFlags, llvm::StringRef("\0", 1), -1,
/*KeepEmpty=*/false);
for (const auto &Flag : SplitFlags)
LinkerFlags.push_back(Flag.str());
for (const auto &Flag : SplitFlags) {
// If it is one of the common Swift library flags,
// only add if not seen before.
if (auto It = CommonAddedSwiftLibraries.find(Flag.str());
It != CommonAddedSwiftLibraries.end()) {
if (It->second == false) {
LinkerFlags.push_back(Flag.str());
It->second = true;
}
} else
LinkerFlags.push_back(Flag.str());
}
}
}
return false;
Expand All @@ -178,12 +200,13 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
static bool extractLinkerFlags(const llvm::object::Binary *Bin,
CompilerInstance &Instance,
StringRef BinaryFileName,
std::vector<std::string> &LinkerFlags) {
std::vector<std::string> &LinkerFlags,
std::unordered_map<std::string, bool> &CommonAddedSwiftLibraries) {
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance);
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, CommonAddedSwiftLibraries, Instance);
} else if (auto *ObjectFile =
llvm::dyn_cast<llvm::object::WasmObjectFile>(Bin)) {
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance);
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, CommonAddedSwiftLibraries, Instance);
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
llvm::Error Error = llvm::Error::success();
for (const auto &Child : Archive->children(Error)) {
Expand All @@ -197,7 +220,7 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
return true;
}
if (extractLinkerFlags(ChildBinary->get(), Instance, BinaryFileName,
LinkerFlags)) {
LinkerFlags, CommonAddedSwiftLibraries)) {
return true;
}
}
Expand Down Expand Up @@ -229,6 +252,13 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,

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

// Keep track of whether we've already added the common
// Swift libraries that ususally have autolink directives
// in most object fiels
std::unordered_map<std::string, bool> CommonAddedSwiftLibraries = {{"-lswiftSwiftOnoneSupport", false},
{"-lswiftCore", false},
{"-lswift_Concurrency", false}};

// Extract the linker flags from the objects.
for (const auto &BinaryFileName : Invocation.getInputFilenames()) {
auto BinaryOwner = llvm::object::createBinary(BinaryFileName);
Expand All @@ -245,7 +275,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
}

if (extractLinkerFlags(BinaryOwner->getBinary(), Instance, BinaryFileName,
LinkerFlags)) {
LinkerFlags, CommonAddedSwiftLibraries)) {
return 1;
}
}
Expand Down
5 changes: 5 additions & 0 deletions test/AutolinkExtract/import.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
// RUN: %target-swiftc_driver -emit-module -emit-module-path %t/empty.swiftmodule -module-name empty -module-link-name empty %S/empty.swift
// RUN: %target-swiftc_driver -c %s -I %t -o %t/import_experimental.o
// RUN: %target-swift-autolink-extract %t/import_experimental.o -o - | %FileCheck --check-prefix CHECK-%target-object-format %s
// RUN: %target-swiftc_driver -c %s -I %t -o %t/import_experimental_again.o
// RUN: %target-swift-autolink-extract %t/import_experimental.o %t/import_experimental_again.o -o - | %FileCheck --check-prefix CHECK-%target-object-format %s
// RUN: %target-swift-autolink-extract %t/import_experimental.o %t/import_experimental_again.o -o - | %FileCheck --check-prefix UNIQUE %s

// REQUIRES: autolink-extract

// UNIQUE-COUNT-1: -lswiftCore

// CHECK-elf-DAG: -lswiftCore
// CHECK-elf-DAG: -lempty

Expand Down

0 comments on commit 34c1abe

Please sign in to comment.