mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Autolink] Autolinking on COFF for Cygwin/MinGW
Cygwin and MinGW should use the autolink feature in the sameway of Linux due to the linker's limit. Now swift-autolink-extract recognizes the COFF format file for Cygwin/MinGW.
This commit is contained in:
@@ -273,7 +273,7 @@ code for the target that is not the build machine:
|
||||
``armv7``, ``armv7k``, ``arm64``).
|
||||
|
||||
* ``%target-os``: the target operating system (``macosx``, ``darwin``,
|
||||
``linux``, ``freebsd``).
|
||||
``linux``, ``freebsd``, ``windows-cygnus``, ``windows-gnu``).
|
||||
|
||||
* ``%target-object-format``: the platform's object format (``elf``, ``macho``,
|
||||
``coff``).
|
||||
|
||||
@@ -1316,7 +1316,8 @@ void Driver::buildActions(const ToolChain &TC,
|
||||
if (OI.shouldLink() && !AllLinkerInputs.empty()) {
|
||||
auto *LinkAction = new LinkJobAction(AllLinkerInputs, OI.LinkAction);
|
||||
|
||||
if (TC.getTriple().getObjectFormat() == llvm::Triple::ELF) {
|
||||
if (TC.getTriple().getObjectFormat() == llvm::Triple::ELF ||
|
||||
TC.getTriple().isOSCygMing()) {
|
||||
// On ELF platforms there's no built in autolinking mechanism, so we
|
||||
// pull the info we need from the .o files directly and pass them as an
|
||||
// argument input file to the linker.
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
// REQUIRES: autolink-extract
|
||||
|
||||
// CHECK-elf: -lswiftCore
|
||||
// CHECK-coff: -lswiftCore
|
||||
|
||||
@@ -6,3 +6,4 @@
|
||||
// REQUIRES: autolink-extract
|
||||
|
||||
// CHECK-elf: -lswiftCore
|
||||
// CHECK-coff: -lswiftCore
|
||||
|
||||
@@ -9,4 +9,7 @@
|
||||
// CHECK-elf-DAG: -lswiftCore
|
||||
// CHECK-elf-DAG: -lempty
|
||||
|
||||
// CHECK-coff-DAG: -lswiftCore
|
||||
// CHECK-coff-DAG: -lempty
|
||||
|
||||
import empty
|
||||
|
||||
@@ -10,4 +10,7 @@
|
||||
// CHECK-elf-DAG: -lswiftCore
|
||||
// CHECK-elf-DAG: -lempty
|
||||
|
||||
// CHECK-coff-DAG: -lswiftCore
|
||||
// CHECK-coff-DAG: -lempty
|
||||
|
||||
import empty
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
; RUN: llc -mtriple armv7--linux-gnueabihf -filetype obj -o - %s | %target-swift-autolink-extract -o - - | FileCheck %s
|
||||
; RUN: llc -mtriple x86_64--windows-gnu -filetype obj -o - %s | %target-swift-autolink-extract -o - - | FileCheck %s
|
||||
; RUN: llc -mtriple x86_64--windows-cygnus -filetype obj -o - %s | %target-swift-autolink-extract -o - - | FileCheck %s
|
||||
; REQUIRES: autolink-extract
|
||||
|
||||
; Ensure that the options in the object file preserve ordering. The linker
|
||||
|
||||
25
test/lit.cfg
25
test/lit.cfg
@@ -691,17 +691,30 @@ if run_vendor == 'apple':
|
||||
"%s clang++ %s" %
|
||||
(xcrun_prefix, config.target_cc_options))
|
||||
|
||||
elif run_os == 'linux-gnu' or run_os == 'linux-gnueabihf' or run_os == 'freebsd':
|
||||
# Linux/FreeBSD
|
||||
if run_os == 'freebsd':
|
||||
elif run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'windows-cygnus', 'windows-gnu']:
|
||||
# Linux/FreeBSD/Cygwin
|
||||
if run_os == 'windows-cygnus':
|
||||
lit_config.note("Testing Cygwin " + config.variant_triple)
|
||||
config.target_object_format = "coff"
|
||||
config.target_dylib_extension = "dll"
|
||||
config.target_sdk_name = "cygwin"
|
||||
elif run_os == 'windows-gnu':
|
||||
lit_config.note("Testing MinGW " + config.variant_triple)
|
||||
config.target_object_format = "coff"
|
||||
config.target_dylib_extension = "dll"
|
||||
config.target_sdk_name = "mingw"
|
||||
elif run_os == 'freebsd':
|
||||
lit_config.note("Testing FreeBSD " + config.variant_triple)
|
||||
config.target_object_format = "elf"
|
||||
config.target_dylib_extension = "so"
|
||||
config.target_sdk_name = "freebsd"
|
||||
else:
|
||||
lit_config.note("Testing Linux " + config.variant_triple)
|
||||
config.target_object_format = "elf"
|
||||
config.target_dylib_extension = "so"
|
||||
config.target_object_format = "elf"
|
||||
config.target_dylib_extension = "so"
|
||||
config.target_sdk_name = "linux"
|
||||
config.target_runtime = "native"
|
||||
config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
|
||||
config.target_sdk_name = "freebsd" if run_os == "freebsd" else "linux"
|
||||
config.target_build_swift = (
|
||||
'%s -target %s %s %s %s %s'
|
||||
% (config.swiftc, config.variant_triple, resource_dir_opt, mcp_opt,
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "llvm/Option/Option.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Object/COFF.h"
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
|
||||
using namespace swift;
|
||||
@@ -106,32 +107,44 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Look inside the binary 'Bin' and append any linker flags found in its
|
||||
// ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive,
|
||||
// recursively look inside all children within the archive. Return 'true' if
|
||||
// there was an error, and 'false' otherwise.
|
||||
/// Look inside the object file 'ObjectFile' and append any linker flags found in
|
||||
/// its ".swift1_autolink_entries" section to 'LinkerFlags'.
|
||||
static void
|
||||
extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
|
||||
std::vector<std::string> &LinkerFlags) {
|
||||
// Search for the section we hold autolink entries in
|
||||
for (auto &Section : ObjectFile->sections()) {
|
||||
llvm::StringRef SectionName;
|
||||
Section.getName(SectionName);
|
||||
if (SectionName == ".swift1_autolink_entries") {
|
||||
llvm::StringRef SectionData;
|
||||
Section.getContents(SectionData);
|
||||
|
||||
// entries are null-terminated, so extract them and push them into
|
||||
// the set.
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Look inside the binary 'Bin' and append any linker flags found in its
|
||||
/// ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive,
|
||||
/// recursively look inside all children within the archive. Return 'true' if
|
||||
/// there was an error, and 'false' otherwise.
|
||||
static bool extractLinkerFlags(const llvm::object::Binary *Bin,
|
||||
CompilerInstance &Instance,
|
||||
StringRef BinaryFileName,
|
||||
std::vector<std::string> &LinkerFlags) {
|
||||
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
|
||||
// Search for the section we hold autolink entries in
|
||||
for (auto &Section : ObjectFile->sections()) {
|
||||
llvm::StringRef SectionName;
|
||||
Section.getName(SectionName);
|
||||
if (SectionName == ".swift1_autolink_entries") {
|
||||
llvm::StringRef SectionData;
|
||||
Section.getContents(SectionData);
|
||||
|
||||
// entries are null-terminated, so extract them and push them into
|
||||
// the set.
|
||||
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);
|
||||
}
|
||||
}
|
||||
extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags);
|
||||
return false;
|
||||
} else if (auto *ObjectFile =
|
||||
llvm::dyn_cast<llvm::object::COFFObjectFile>(Bin)) {
|
||||
extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags);
|
||||
return false;
|
||||
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
|
||||
for (const auto &Child : Archive->children()) {
|
||||
|
||||
Reference in New Issue
Block a user