mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[autolink-extract] Support (and ignore) LLVM IR files. (#71142)
In Linux, the current implementation of swift-autolink-extract does not support LLVM IR files resulting from using LTO. If one tries to build LLVM using LTO and then try to link one of the targets that use `swiftc` to link, but link against LLVM object files (like `swift-plugin-server`), `swift-autolink-extract` will fail saying that some object files are not valid. To deal with LLVM IR files correctly, create and pass a `llvm::LLVMContext` around, which allows the APIs in `llvm::object` to read LLVM IR files. Additionally, handle the case of `IRObjectFile` when extracting, but perform no action.
This commit is contained in:
committed by
GitHub
parent
c527b0ff39
commit
b43d01ff7f
@@ -32,7 +32,9 @@
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/Object/IRObjectFile.h"
|
||||
#include "llvm/Object/Wasm.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/BinaryFormat/Wasm.h"
|
||||
|
||||
using namespace swift;
|
||||
@@ -161,7 +163,8 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
|
||||
CompilerInstance &Instance,
|
||||
StringRef BinaryFileName,
|
||||
std::vector<std::string> &LinkerFlags,
|
||||
std::unordered_map<std::string, bool> &SwiftRuntimeLibraries) {
|
||||
std::unordered_map<std::string, bool> &SwiftRuntimeLibraries,
|
||||
llvm::LLVMContext *LLVMCtx) {
|
||||
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
|
||||
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, SwiftRuntimeLibraries, Instance);
|
||||
} else if (auto *ObjectFile =
|
||||
@@ -170,7 +173,7 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
|
||||
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
|
||||
llvm::Error Error = llvm::Error::success();
|
||||
for (const auto &Child : Archive->children(Error)) {
|
||||
auto ChildBinary = Child.getAsBinary();
|
||||
auto ChildBinary = Child.getAsBinary(LLVMCtx);
|
||||
// FIXME: BinaryFileName below should instead be ld-style names for
|
||||
// object files in archives, e.g. "foo.a(bar.o)".
|
||||
if (!ChildBinary) {
|
||||
@@ -180,12 +183,15 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
|
||||
return true;
|
||||
}
|
||||
if (extractLinkerFlags(ChildBinary->get(), Instance, BinaryFileName,
|
||||
LinkerFlags, SwiftRuntimeLibraries)) {
|
||||
LinkerFlags, SwiftRuntimeLibraries, LLVMCtx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return bool(Error);
|
||||
} else {
|
||||
} else if (auto *IRObjectFile = llvm::dyn_cast<llvm::object::IRObjectFile>(Bin)) {
|
||||
// Ignore the LLVM IR files (LTO)
|
||||
return false;
|
||||
} else {
|
||||
Instance.getDiags().diagnose(SourceLoc(), diag::error_open_input_file,
|
||||
BinaryFileName,
|
||||
"Don't know how to extract from object file"
|
||||
@@ -259,8 +265,9 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
|
||||
}
|
||||
|
||||
// Extract the linker flags from the objects.
|
||||
llvm::LLVMContext LLVMCtx;
|
||||
for (const auto &BinaryFileName : Invocation.getInputFilenames()) {
|
||||
auto BinaryOwner = llvm::object::createBinary(BinaryFileName);
|
||||
auto BinaryOwner = llvm::object::createBinary(BinaryFileName, &LLVMCtx);
|
||||
if (!BinaryOwner) {
|
||||
std::string message;
|
||||
{
|
||||
@@ -274,7 +281,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
|
||||
}
|
||||
|
||||
if (extractLinkerFlags(BinaryOwner->getBinary(), Instance, BinaryFileName,
|
||||
LinkerFlags, SwiftRuntimeLibraries)) {
|
||||
LinkerFlags, SwiftRuntimeLibraries, &LLVMCtx)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
7
test/AutolinkExtract/llvm-ir.cpp
Normal file
7
test/AutolinkExtract/llvm-ir.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
// REQUIRES: autolink-extract
|
||||
// RUN: %clang -flto=thin -c -o - %s | %target-swift-autolink-extract -o - - 2>&1 | %FileCheck --allow-empty %s
|
||||
// CHECK-NOT: The file was not recognized as a valid object file
|
||||
|
||||
int test() {
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user