Skip to content

Commit 0747503

Browse files
committed
[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.
1 parent 2ef0a8f commit 0747503

File tree

9 files changed

+66
-29
lines changed

9 files changed

+66
-29
lines changed

docs/Testing.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ code for the target that is not the build machine:
273273
``armv7``, ``armv7k``, ``arm64``).
274274

275275
* ``%target-os``: the target operating system (``macosx``, ``darwin``,
276-
``linux``, ``freebsd``).
276+
``linux``, ``freebsd``, ``windows-cygnus``, ``windows-gnu``).
277277

278278
* ``%target-object-format``: the platform's object format (``elf``, ``macho``,
279279
``coff``).

lib/Driver/Driver.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,8 @@ void Driver::buildActions(const ToolChain &TC,
13161316
if (OI.shouldLink() && !AllLinkerInputs.empty()) {
13171317
auto *LinkAction = new LinkJobAction(AllLinkerInputs, OI.LinkAction);
13181318

1319-
if (TC.getTriple().getObjectFormat() == llvm::Triple::ELF) {
1319+
if (TC.getTriple().getObjectFormat() == llvm::Triple::ELF ||
1320+
TC.getTriple().isOSCygMing()) {
13201321
// On ELF platforms there's no built in autolinking mechanism, so we
13211322
// pull the info we need from the .o files directly and pass them as an
13221323
// argument input file to the linker.

test/AutolinkExtract/empty.swift

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
// REQUIRES: autolink-extract
55

66
// CHECK-elf: -lswiftCore
7+
// CHECK-coff: -lswiftCore

test/AutolinkExtract/empty_archive.swift

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
// REQUIRES: autolink-extract
77

88
// CHECK-elf: -lswiftCore
9+
// CHECK-coff: -lswiftCore

test/AutolinkExtract/import.swift

+3
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@
99
// CHECK-elf-DAG: -lswiftCore
1010
// CHECK-elf-DAG: -lempty
1111

12+
// CHECK-coff-DAG: -lswiftCore
13+
// CHECK-coff-DAG: -lempty
14+
1215
import empty

test/AutolinkExtract/import_archive.swift

+3
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@
1010
// CHECK-elf-DAG: -lswiftCore
1111
// CHECK-elf-DAG: -lempty
1212

13+
// CHECK-coff-DAG: -lswiftCore
14+
// CHECK-coff-DAG: -lempty
15+
1316
import empty

test/AutolinkExtract/linker-order.ll

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
; RUN: llc -mtriple armv7--linux-gnueabihf -filetype obj -o - %s | %target-swift-autolink-extract -o - - | FileCheck %s
2+
; RUN: llc -mtriple x86_64--windows-gnu -filetype obj -o - %s | %target-swift-autolink-extract -o - - | FileCheck %s
3+
; RUN: llc -mtriple x86_64--windows-cygnus -filetype obj -o - %s | %target-swift-autolink-extract -o - - | FileCheck %s
24
; REQUIRES: autolink-extract
35

46
; Ensure that the options in the object file preserve ordering. The linker

test/lit.cfg

+19-6
Original file line numberDiff line numberDiff line change
@@ -691,17 +691,30 @@ if run_vendor == 'apple':
691691
"%s clang++ %s" %
692692
(xcrun_prefix, config.target_cc_options))
693693

694-
elif run_os == 'linux-gnu' or run_os == 'linux-gnueabihf' or run_os == 'freebsd':
695-
# Linux/FreeBSD
696-
if run_os == 'freebsd':
694+
elif run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'windows-cygnus', 'windows-gnu']:
695+
# Linux/FreeBSD/Cygwin
696+
if run_os == 'windows-cygnus':
697+
lit_config.note("Testing Cygwin " + config.variant_triple)
698+
config.target_object_format = "coff"
699+
config.target_dylib_extension = "dll"
700+
config.target_sdk_name = "cygwin"
701+
elif run_os == 'windows-gnu':
702+
lit_config.note("Testing MinGW " + config.variant_triple)
703+
config.target_object_format = "coff"
704+
config.target_dylib_extension = "dll"
705+
config.target_sdk_name = "mingw"
706+
elif run_os == 'freebsd':
697707
lit_config.note("Testing FreeBSD " + config.variant_triple)
708+
config.target_object_format = "elf"
709+
config.target_dylib_extension = "so"
710+
config.target_sdk_name = "freebsd"
698711
else:
699712
lit_config.note("Testing Linux " + config.variant_triple)
700-
config.target_object_format = "elf"
701-
config.target_dylib_extension = "so"
713+
config.target_object_format = "elf"
714+
config.target_dylib_extension = "so"
715+
config.target_sdk_name = "linux"
702716
config.target_runtime = "native"
703717
config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
704-
config.target_sdk_name = "freebsd" if run_os == "freebsd" else "linux"
705718
config.target_build_swift = (
706719
'%s -target %s %s %s %s %s'
707720
% (config.swiftc, config.variant_triple, resource_dir_opt, mcp_opt,

tools/driver/autolink_extract_main.cpp

+34-21
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "llvm/Option/Option.h"
3232
#include "llvm/Object/Archive.h"
3333
#include "llvm/Object/ObjectFile.h"
34+
#include "llvm/Object/COFF.h"
3435
#include "llvm/Object/ELFObjectFile.h"
3536

3637
using namespace swift;
@@ -106,32 +107,44 @@ class AutolinkExtractInvocation {
106107
}
107108
};
108109

109-
// Look inside the binary 'Bin' and append any linker flags found in its
110-
// ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive,
111-
// recursively look inside all children within the archive. Return 'true' if
112-
// there was an error, and 'false' otherwise.
110+
/// Look inside the object file 'ObjectFile' and append any linker flags found in
111+
/// its ".swift1_autolink_entries" section to 'LinkerFlags'.
112+
static void
113+
extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
114+
std::vector<std::string> &LinkerFlags) {
115+
// Search for the section we hold autolink entries in
116+
for (auto &Section : ObjectFile->sections()) {
117+
llvm::StringRef SectionName;
118+
Section.getName(SectionName);
119+
if (SectionName == ".swift1_autolink_entries") {
120+
llvm::StringRef SectionData;
121+
Section.getContents(SectionData);
122+
123+
// entries are null-terminated, so extract them and push them into
124+
// the set.
125+
llvm::SmallVector<llvm::StringRef, 4> SplitFlags;
126+
SectionData.split(SplitFlags, llvm::StringRef("\0", 1), -1,
127+
/*KeepEmpty=*/false);
128+
for (const auto &Flag : SplitFlags)
129+
LinkerFlags.push_back(Flag);
130+
}
131+
}
132+
}
133+
134+
/// Look inside the binary 'Bin' and append any linker flags found in its
135+
/// ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive,
136+
/// recursively look inside all children within the archive. Return 'true' if
137+
/// there was an error, and 'false' otherwise.
113138
static bool extractLinkerFlags(const llvm::object::Binary *Bin,
114139
CompilerInstance &Instance,
115140
StringRef BinaryFileName,
116141
std::vector<std::string> &LinkerFlags) {
117142
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
118-
// Search for the section we hold autolink entries in
119-
for (auto &Section : ObjectFile->sections()) {
120-
llvm::StringRef SectionName;
121-
Section.getName(SectionName);
122-
if (SectionName == ".swift1_autolink_entries") {
123-
llvm::StringRef SectionData;
124-
Section.getContents(SectionData);
125-
126-
// entries are null-terminated, so extract them and push them into
127-
// the set.
128-
llvm::SmallVector<llvm::StringRef, 4> SplitFlags;
129-
SectionData.split(SplitFlags, llvm::StringRef("\0", 1), -1,
130-
/*KeepEmpty=*/false);
131-
for (const auto &Flag : SplitFlags)
132-
LinkerFlags.push_back(Flag);
133-
}
134-
}
143+
extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags);
144+
return false;
145+
} else if (auto *ObjectFile =
146+
llvm::dyn_cast<llvm::object::COFFObjectFile>(Bin)) {
147+
extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags);
135148
return false;
136149
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
137150
for (const auto &Child : Archive->children()) {

0 commit comments

Comments
 (0)