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``).
|
``armv7``, ``armv7k``, ``arm64``).
|
||||||
|
|
||||||
* ``%target-os``: the target operating system (``macosx``, ``darwin``,
|
* ``%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``,
|
* ``%target-object-format``: the platform's object format (``elf``, ``macho``,
|
||||||
``coff``).
|
``coff``).
|
||||||
|
|||||||
@@ -1316,7 +1316,8 @@ void Driver::buildActions(const ToolChain &TC,
|
|||||||
if (OI.shouldLink() && !AllLinkerInputs.empty()) {
|
if (OI.shouldLink() && !AllLinkerInputs.empty()) {
|
||||||
auto *LinkAction = new LinkJobAction(AllLinkerInputs, OI.LinkAction);
|
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
|
// 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
|
// pull the info we need from the .o files directly and pass them as an
|
||||||
// argument input file to the linker.
|
// argument input file to the linker.
|
||||||
|
|||||||
@@ -4,3 +4,4 @@
|
|||||||
// REQUIRES: autolink-extract
|
// REQUIRES: autolink-extract
|
||||||
|
|
||||||
// CHECK-elf: -lswiftCore
|
// CHECK-elf: -lswiftCore
|
||||||
|
// CHECK-coff: -lswiftCore
|
||||||
|
|||||||
@@ -6,3 +6,4 @@
|
|||||||
// REQUIRES: autolink-extract
|
// REQUIRES: autolink-extract
|
||||||
|
|
||||||
// CHECK-elf: -lswiftCore
|
// CHECK-elf: -lswiftCore
|
||||||
|
// CHECK-coff: -lswiftCore
|
||||||
|
|||||||
@@ -9,4 +9,7 @@
|
|||||||
// CHECK-elf-DAG: -lswiftCore
|
// CHECK-elf-DAG: -lswiftCore
|
||||||
// CHECK-elf-DAG: -lempty
|
// CHECK-elf-DAG: -lempty
|
||||||
|
|
||||||
|
// CHECK-coff-DAG: -lswiftCore
|
||||||
|
// CHECK-coff-DAG: -lempty
|
||||||
|
|
||||||
import empty
|
import empty
|
||||||
|
|||||||
@@ -10,4 +10,7 @@
|
|||||||
// CHECK-elf-DAG: -lswiftCore
|
// CHECK-elf-DAG: -lswiftCore
|
||||||
// CHECK-elf-DAG: -lempty
|
// CHECK-elf-DAG: -lempty
|
||||||
|
|
||||||
|
// CHECK-coff-DAG: -lswiftCore
|
||||||
|
// CHECK-coff-DAG: -lempty
|
||||||
|
|
||||||
import empty
|
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 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
|
; REQUIRES: autolink-extract
|
||||||
|
|
||||||
; Ensure that the options in the object file preserve ordering. The linker
|
; 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" %
|
"%s clang++ %s" %
|
||||||
(xcrun_prefix, config.target_cc_options))
|
(xcrun_prefix, config.target_cc_options))
|
||||||
|
|
||||||
elif run_os == 'linux-gnu' or run_os == 'linux-gnueabihf' or run_os == 'freebsd':
|
elif run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'windows-cygnus', 'windows-gnu']:
|
||||||
# Linux/FreeBSD
|
# Linux/FreeBSD/Cygwin
|
||||||
if run_os == 'freebsd':
|
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)
|
lit_config.note("Testing FreeBSD " + config.variant_triple)
|
||||||
|
config.target_object_format = "elf"
|
||||||
|
config.target_dylib_extension = "so"
|
||||||
|
config.target_sdk_name = "freebsd"
|
||||||
else:
|
else:
|
||||||
lit_config.note("Testing Linux " + config.variant_triple)
|
lit_config.note("Testing Linux " + config.variant_triple)
|
||||||
config.target_object_format = "elf"
|
config.target_object_format = "elf"
|
||||||
config.target_dylib_extension = "so"
|
config.target_dylib_extension = "so"
|
||||||
|
config.target_sdk_name = "linux"
|
||||||
config.target_runtime = "native"
|
config.target_runtime = "native"
|
||||||
config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
|
config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
|
||||||
config.target_sdk_name = "freebsd" if run_os == "freebsd" else "linux"
|
|
||||||
config.target_build_swift = (
|
config.target_build_swift = (
|
||||||
'%s -target %s %s %s %s %s'
|
'%s -target %s %s %s %s %s'
|
||||||
% (config.swiftc, config.variant_triple, resource_dir_opt, mcp_opt,
|
% (config.swiftc, config.variant_triple, resource_dir_opt, mcp_opt,
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "llvm/Option/Option.h"
|
#include "llvm/Option/Option.h"
|
||||||
#include "llvm/Object/Archive.h"
|
#include "llvm/Object/Archive.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
|
#include "llvm/Object/COFF.h"
|
||||||
#include "llvm/Object/ELFObjectFile.h"
|
#include "llvm/Object/ELFObjectFile.h"
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
@@ -106,32 +107,44 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Look inside the binary 'Bin' and append any linker flags found in its
|
/// Look inside the object file 'ObjectFile' and append any linker flags found in
|
||||||
// ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive,
|
/// its ".swift1_autolink_entries" section to 'LinkerFlags'.
|
||||||
// recursively look inside all children within the archive. Return 'true' if
|
static void
|
||||||
// there was an error, and 'false' otherwise.
|
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,
|
static bool extractLinkerFlags(const llvm::object::Binary *Bin,
|
||||||
CompilerInstance &Instance,
|
CompilerInstance &Instance,
|
||||||
StringRef BinaryFileName,
|
StringRef BinaryFileName,
|
||||||
std::vector<std::string> &LinkerFlags) {
|
std::vector<std::string> &LinkerFlags) {
|
||||||
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
|
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
|
||||||
// Search for the section we hold autolink entries in
|
extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags);
|
||||||
for (auto &Section : ObjectFile->sections()) {
|
return false;
|
||||||
llvm::StringRef SectionName;
|
} else if (auto *ObjectFile =
|
||||||
Section.getName(SectionName);
|
llvm::dyn_cast<llvm::object::COFFObjectFile>(Bin)) {
|
||||||
if (SectionName == ".swift1_autolink_entries") {
|
extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
|
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
|
||||||
for (const auto &Child : Archive->children()) {
|
for (const auto &Child : Archive->children()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user