Skip to content

Commit abad917

Browse files
authored
Merge pull request #17843 from jrose-apple/batteries-included (#17896)
[Driver] Always link compiler_rt on Darwin (when available) rdar://problem/41911599 (cherry picked from commit b02d554)
1 parent 8297d75 commit abad917

File tree

8 files changed

+122
-13
lines changed

8 files changed

+122
-13
lines changed

include/swift/Basic/Platform.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ namespace swift {
5858
/// Returns the platform Kind for Darwin triples.
5959
DarwinPlatformKind getDarwinPlatformKind(const llvm::Triple &triple);
6060

61+
/// Maps an arbitrary platform to its non-simulator equivalent.
62+
///
63+
/// If \p platform is not a simulator platform, it will be returned as is.
64+
DarwinPlatformKind getNonSimulatorPlatform(DarwinPlatformKind platform);
65+
6166
/// Returns the architecture component of the path for a given target triple.
6267
///
6368
/// Typically this is used for mapping the architecture component of the

lib/Basic/Platform.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ DarwinPlatformKind swift::getDarwinPlatformKind(const llvm::Triple &triple) {
7676
llvm_unreachable("Unsupported Darwin platform");
7777
}
7878

79+
DarwinPlatformKind swift::getNonSimulatorPlatform(DarwinPlatformKind platform) {
80+
switch (platform) {
81+
case DarwinPlatformKind::MacOS:
82+
return DarwinPlatformKind::MacOS;
83+
case DarwinPlatformKind::IPhoneOS:
84+
case DarwinPlatformKind::IPhoneOSSimulator:
85+
return DarwinPlatformKind::IPhoneOS;
86+
case DarwinPlatformKind::TvOS:
87+
case DarwinPlatformKind::TvOSSimulator:
88+
return DarwinPlatformKind::TvOS;
89+
case DarwinPlatformKind::WatchOS:
90+
case DarwinPlatformKind::WatchOSSimulator:
91+
return DarwinPlatformKind::WatchOS;
92+
}
93+
}
94+
7995
static StringRef getPlatformNameForDarwin(const DarwinPlatformKind platform) {
8096
switch (platform) {
8197
case DarwinPlatformKind::MacOS:

lib/Driver/ToolChains.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,8 +1113,12 @@ toolchains::Darwin::constructInvocation(const InterpretJobAction &job,
11131113
}
11141114

11151115
static StringRef
1116-
getDarwinLibraryNameSuffixForTriple(const llvm::Triple &triple) {
1117-
switch (getDarwinPlatformKind(triple)) {
1116+
getDarwinLibraryNameSuffixForTriple(const llvm::Triple &triple,
1117+
bool distinguishSimulator = true) {
1118+
const DarwinPlatformKind kind = getDarwinPlatformKind(triple);
1119+
const DarwinPlatformKind effectiveKind =
1120+
distinguishSimulator ? kind : getNonSimulatorPlatform(kind);
1121+
switch (effectiveKind) {
11181122
case DarwinPlatformKind::MacOS:
11191123
return "osx";
11201124
case DarwinPlatformKind::IPhoneOS:
@@ -1357,7 +1361,22 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
13571361
assert(Triple.isOSDarwin());
13581362

13591363
// FIXME: If we used Clang as a linker instead of going straight to ld,
1360-
// we wouldn't have to replicate Clang's logic here.
1364+
// we wouldn't have to replicate a bunch of Clang's logic here.
1365+
1366+
// Always link the regular compiler_rt if it's present.
1367+
//
1368+
// Note: Normally we'd just add this unconditionally, but it's valid to build
1369+
// Swift and use it as a linker without building compiler_rt.
1370+
SmallString<128> CompilerRTPath;
1371+
getClangLibraryPath(*this, context.Args, CompilerRTPath);
1372+
llvm::sys::path::append(
1373+
CompilerRTPath,
1374+
Twine("libclang_rt.") +
1375+
getDarwinLibraryNameSuffixForTriple(Triple, /*simulator*/false) +
1376+
".a");
1377+
if (llvm::sys::fs::exists(CompilerRTPath))
1378+
Arguments.push_back(context.Args.MakeArgString(CompilerRTPath));
1379+
13611380
bool wantsObjCRuntime = false;
13621381
if (Triple.isiOS())
13631382
wantsObjCRuntime = Triple.isOSVersionLT(9);
@@ -1471,9 +1490,8 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
14711490
}
14721491

14731492
if (context.Args.hasArg(options::OPT_profile_generate)) {
1474-
SmallString<128> LibProfile(RuntimeLibPath);
1475-
llvm::sys::path::remove_filename(LibProfile); // remove platform name
1476-
llvm::sys::path::append(LibProfile, "clang", "lib", "darwin");
1493+
SmallString<128> LibProfile;
1494+
getClangLibraryPath(*this, context.Args, LibProfile);
14771495

14781496
StringRef RT;
14791497
if (Triple.isiOS()) {

test/Driver/linker-clang_rt.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Make sure that the platform-appropriate clang_rt library (found relative to
2+
// the compiler) is included when using Swift as a linker (with Apple targets).
3+
4+
// We use hard links to make sure the Swift driver really thinks it's been
5+
// moved.
6+
7+
// RUN: rm -rf %t
8+
// RUN: %empty-directory(%t/bin)
9+
// RUN: %hardlink-or-copy(from: %swift_driver_plain, to: %t/bin/swiftc)
10+
// RUN: %empty-directory(%t/lib/clang/darwin/)
11+
12+
// RUN: %t/bin/swiftc -driver-print-jobs -target x86_64-apple-macosx10.9 %S/../Inputs/empty.swift | %FileCheck -check-prefix CHECK -check-prefix CHECK-NO-RUNTIME %s
13+
14+
// RUN: touch %t/lib/clang/darwin/libclang_rt.osx.a %t/lib/clang/darwin/libclang_rt.ios.a %t/lib/clang/darwin/libclang_rt.tvos.a %t/lib/clang/darwin/libclang_rt.watchos.a
15+
16+
// RUN: %t/bin/swiftc -driver-print-jobs -target x86_64-apple-macosx10.9 %S/../Inputs/empty.swift | %FileCheck -check-prefix CHECK -check-prefix MACOS %s
17+
18+
// RUN: %t/bin/swiftc -driver-print-jobs -target i386-apple-ios7 %S/../Inputs/empty.swift | %FileCheck -check-prefix CHECK -check-prefix IOS %s
19+
// RUN: %t/bin/swiftc -driver-print-jobs -target x86_64-apple-ios7 %S/../Inputs/empty.swift | %FileCheck -check-prefix CHECK -check-prefix IOS %s
20+
// RUN: %t/bin/swiftc -driver-print-jobs -target armv7s-apple-ios7 %S/../Inputs/empty.swift | %FileCheck -check-prefix CHECK -check-prefix IOS %s
21+
// RUN: %t/bin/swiftc -driver-print-jobs -target arm64-apple-ios7 %S/../Inputs/empty.swift | %FileCheck -check-prefix CHECK -check-prefix IOS %s
22+
23+
// RUN: %t/bin/swiftc -driver-print-jobs -target x86_64-apple-ios9 %S/../Inputs/empty.swift | %FileCheck -check-prefix CHECK -check-prefix TVOS %s
24+
// RUN: %t/bin/swiftc -driver-print-jobs -target arm64-apple-tvos9 %S/../Inputs/empty.swift | %FileCheck -check-prefix CHECK -check-prefix TVOS %s
25+
26+
// RUN: %t/bin/swiftc -driver-print-jobs -target i386-apple-watchos2 %S/../Inputs/empty.swift | %FileCheck -check-prefix CHECK -check-prefix WATCHOS %s
27+
// RUN: %t/bin/swiftc -driver-print-jobs -target armv7k-apple-watchos2 %S/../Inputs/empty.swift | %FileCheck -check-prefix CHECK -check-prefix WATCHOS %s
28+
29+
// Clean up the test executable because hard links are expensive.
30+
// RUN: rm -f %t/bin/swiftc
31+
32+
// CHECK: bin/ld{{"? }}
33+
// CHECK-NO-RUNTIME-NOT: libclang_rt
34+
// CHECK-MACOS-SAME: {{[^ ]+/lib/clang/darwin/libclang_rt.osx.a}}
35+
// CHECK-IOS-SAME: {{[^ ]+/lib/clang/darwin/libclang_rt.ios.a}}
36+
// CHECK-TVOS-SAME: {{[^ ]+/lib/clang/darwin/libclang_rt.tvos.a}}
37+
// CHECK-WATCHOS-SAME: {{[^ ]+/lib/clang/darwin/libclang_rt.watchos.a}}
38+
// CHECK-SAME: -o {{[^ ]+}}

test/Driver/linker.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787

8888
// SIMPLE: bin/ld{{"? }}
8989
// SIMPLE-NOT: -syslibroot
90-
// SIMPLE-DAG: -macosx_version_min 10.{{[0-9]+}}.{{[0-9]+}}
90+
// SIMPLE: -macosx_version_min 10.{{[0-9]+}}.{{[0-9]+}}
9191
// SIMPLE-NOT: -syslibroot
9292
// SIMPLE: -o linker
9393

@@ -312,11 +312,11 @@
312312

313313

314314
// FILELIST: bin/ld{{"? }}
315-
// FILELIST-NOT: .o
315+
// FILELIST-NOT: .o{{"? }}
316316
// FILELIST: -filelist {{"?[^-]}}
317-
// FILELIST-NOT: .o
318-
// FILELIST: /a.o
319-
// FILELIST-NOT: .o
317+
// FILELIST-NOT: .o{{"? }}
318+
// FILELIST: /a.o{{"? }}
319+
// FILELIST-NOT: .o{{"? }}
320320
// FILELIST: -o linker
321321

322322

test/lit.cfg

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -957,8 +957,9 @@ def source_compiler_rt_libs(path):
957957
if lib.startswith('libclang_rt.')
958958
and config.compiler_rt_platform in lib])
959959

960-
source_compiler_rt_libs(os.path.join(test_resource_dir, 'clang', 'lib',
961-
platform.system().lower()))
960+
compiler_rt_dir = os.path.join(test_resource_dir, 'clang', 'lib',
961+
platform.system().lower())
962+
source_compiler_rt_libs(compiler_rt_dir)
962963

963964
def check_runtime_libs(features_to_check):
964965
for lib in config.compiler_rt_libs:
@@ -979,6 +980,17 @@ if run_ptrsize != "32":
979980

980981
check_runtime_libs(runtime_libs)
981982

983+
# From https://stackoverflow.com/a/2393022
984+
def strip_right(text, suffix):
985+
if not text.endswith(suffix):
986+
return text
987+
return text[:len(text)-len(suffix)]
988+
989+
base_runtime_lib_name = (
990+
'libclang_rt.' + strip_right(config.compiler_rt_platform, 'sim') + '.a')
991+
if os.path.exists(os.path.join(compiler_rt_dir, base_runtime_lib_name)):
992+
config.available_features.add('c_runtime')
993+
982994
if not getattr(config, 'target_run_simple_swift', None):
983995
config.target_run_simple_swift = (
984996
'rm -rf %%t && mkdir -p %%t && '
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <stdbool.h>
2+
3+
static inline bool isRunningOnFairlyRecentOS() {
4+
if (__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *)) {
5+
return true;
6+
} else {
7+
return false;
8+
}
9+
}

validation-test/Driver/clang_rt.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-build-swift -emit-executable %s -import-objc-header %S/Inputs/clang_rt-helper.h -o %t
2+
3+
// REQUIRES: c_runtime
4+
5+
// Just make sure we can build and link successfully.
6+
7+
if isRunningOnFairlyRecentOS() {
8+
print("new!")
9+
} else {
10+
print("old...")
11+
}

0 commit comments

Comments
 (0)