Skip to content

Commit 7d8375b

Browse files
Xazax-hunGabor Horvath
andauthored
[clang][driver] Fix -print-libgcc-file-name on Darwin platforms (#98325)
On Darwin, -print-libgcc-file-name was returning a nonsensical result. It would return the name of the library that would be used by the default toolchain implementation, but that was something that didn't exist on Darwin. Fixing this requires initializing the Darwin toolchain before processing `-print-libgcc-file-name`. Previously, the Darwin toolchain would only be initialized when building the jobs for this compilation, which is too late since `-print-libgcc-file-name` requires the toolchain to be initialized in order to provide the right results. rdar://90633749 Co-authored-by: Gabor Horvath <[email protected]>
1 parent 7122b70 commit 7d8375b

File tree

5 files changed

+160
-24
lines changed

5 files changed

+160
-24
lines changed

clang/include/clang/Driver/Driver.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,8 +628,9 @@ class Driver {
628628
/// treated before building actions or binding tools.
629629
///
630630
/// \return Whether any compilation should be built for this
631-
/// invocation.
632-
bool HandleImmediateArgs(const Compilation &C);
631+
/// invocation. The compilation can only be modified when
632+
/// this function returns false.
633+
bool HandleImmediateArgs(Compilation &C);
633634

634635
/// ConstructAction - Construct the appropriate action to do for
635636
/// \p Phase on the \p Input, taking in to account arguments

clang/lib/Driver/Driver.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2128,7 +2128,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const {
21282128
llvm::outs() << llvm::join(SuggestedCompletions, "\n") << '\n';
21292129
}
21302130

2131-
bool Driver::HandleImmediateArgs(const Compilation &C) {
2131+
bool Driver::HandleImmediateArgs(Compilation &C) {
21322132
// The order these options are handled in gcc is all over the place, but we
21332133
// don't expect inconsistencies w.r.t. that to matter in practice.
21342134

@@ -2271,6 +2271,14 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
22712271
if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
22722272
ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(C.getArgs());
22732273
const llvm::Triple Triple(TC.ComputeEffectiveClangTriple(C.getArgs()));
2274+
// The 'Darwin' toolchain is initialized only when its arguments are
2275+
// computed. Get the default arguments for OFK_None to ensure that
2276+
// initialization is performed before trying to access properties of
2277+
// the toolchain in the functions below.
2278+
// FIXME: Remove when darwin's toolchain is initialized during construction.
2279+
// FIXME: For some more esoteric targets the default toolchain is not the
2280+
// correct one.
2281+
C.getArgsForToolChain(&TC, Triple.getArchName(), Action::OFK_None);
22742282
RegisterEffectiveTriple TripleRAII(TC, Triple);
22752283
switch (RLT) {
22762284
case ToolChain::RLT_CompilerRT:

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,23 +1272,8 @@ unsigned DarwinClang::GetDefaultDwarfVersion() const {
12721272
void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
12731273
StringRef Component, RuntimeLinkOptions Opts,
12741274
bool IsShared) const {
1275-
SmallString<64> DarwinLibName = StringRef("libclang_rt.");
1276-
// On Darwin the builtins component is not in the library name.
1277-
if (Component != "builtins") {
1278-
DarwinLibName += Component;
1279-
if (!(Opts & RLO_IsEmbedded))
1280-
DarwinLibName += "_";
1281-
}
1282-
1283-
DarwinLibName += getOSLibraryNameSuffix();
1284-
DarwinLibName += IsShared ? "_dynamic.dylib" : ".a";
1285-
SmallString<128> Dir(getDriver().ResourceDir);
1286-
llvm::sys::path::append(Dir, "lib", "darwin");
1287-
if (Opts & RLO_IsEmbedded)
1288-
llvm::sys::path::append(Dir, "macho_embedded");
1289-
1290-
SmallString<128> P(Dir);
1291-
llvm::sys::path::append(P, DarwinLibName);
1275+
std::string P = getCompilerRT(
1276+
Args, Component, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static);
12921277

12931278
// For now, allow missing resource libraries to support developers who may
12941279
// not have compiler-rt checked out or integrated into their build (unless
@@ -1303,18 +1288,56 @@ void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
13031288
// rpaths. This is currently true from this place, but we need to be
13041289
// careful if this function is ever called before user's rpaths are emitted.
13051290
if (Opts & RLO_AddRPath) {
1306-
assert(DarwinLibName.ends_with(".dylib") && "must be a dynamic library");
1291+
assert(StringRef(P).ends_with(".dylib") && "must be a dynamic library");
13071292

13081293
// Add @executable_path to rpath to support having the dylib copied with
13091294
// the executable.
13101295
CmdArgs.push_back("-rpath");
13111296
CmdArgs.push_back("@executable_path");
13121297

1313-
// Add the path to the resource dir to rpath to support using the dylib
1314-
// from the default location without copying.
1298+
// Add the compiler-rt library's directory to rpath to support using the
1299+
// dylib from the default location without copying.
13151300
CmdArgs.push_back("-rpath");
1316-
CmdArgs.push_back(Args.MakeArgString(Dir));
1301+
CmdArgs.push_back(Args.MakeArgString(llvm::sys::path::parent_path(P)));
1302+
}
1303+
}
1304+
1305+
std::string MachO::getCompilerRT(const ArgList &, StringRef Component,
1306+
FileType Type) const {
1307+
assert(Type != ToolChain::FT_Object &&
1308+
"it doesn't make sense to ask for the compiler-rt library name as an "
1309+
"object file");
1310+
SmallString<64> MachOLibName = StringRef("libclang_rt");
1311+
// On MachO, the builtins component is not in the library name
1312+
if (Component != "builtins") {
1313+
MachOLibName += '.';
1314+
MachOLibName += Component;
1315+
}
1316+
MachOLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a";
1317+
1318+
SmallString<128> FullPath(getDriver().ResourceDir);
1319+
llvm::sys::path::append(FullPath, "lib", "darwin", "macho_embedded",
1320+
MachOLibName);
1321+
return std::string(FullPath);
1322+
}
1323+
1324+
std::string Darwin::getCompilerRT(const ArgList &, StringRef Component,
1325+
FileType Type) const {
1326+
assert(Type != ToolChain::FT_Object &&
1327+
"it doesn't make sense to ask for the compiler-rt library name as an "
1328+
"object file");
1329+
SmallString<64> DarwinLibName = StringRef("libclang_rt.");
1330+
// On Darwin, the builtins component is not in the library name
1331+
if (Component != "builtins") {
1332+
DarwinLibName += Component;
1333+
DarwinLibName += '_';
13171334
}
1335+
DarwinLibName += getOSLibraryNameSuffix();
1336+
DarwinLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a";
1337+
1338+
SmallString<128> FullPath(getDriver().ResourceDir);
1339+
llvm::sys::path::append(FullPath, "lib", "darwin", DarwinLibName);
1340+
return std::string(FullPath);
13181341
}
13191342

13201343
StringRef Darwin::getPlatformFamily() const {

clang/lib/Driver/ToolChains/Darwin.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,13 @@ class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
223223
// There aren't any profiling libs for embedded targets currently.
224224
}
225225

226+
// Return the full path of the compiler-rt library on a non-Darwin MachO
227+
// system. Those are under
228+
// <resourcedir>/lib/darwin/macho_embedded/<...>(.dylib|.a).
229+
std::string
230+
getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
231+
FileType Type = ToolChain::FT_Static) const override;
232+
226233
/// }
227234
/// @name ToolChain Implementation
228235
/// {
@@ -356,6 +363,12 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
356363
void addProfileRTLibs(const llvm::opt::ArgList &Args,
357364
llvm::opt::ArgStringList &CmdArgs) const override;
358365

366+
// Return the full path of the compiler-rt library on a Darwin MachO system.
367+
// Those are under <resourcedir>/lib/darwin/<...>(.dylib|.a).
368+
std::string
369+
getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
370+
FileType Type = ToolChain::FT_Static) const override;
371+
359372
protected:
360373
/// }
361374
/// @name Darwin specific Toolchain functions
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Test the output of -print-libgcc-file-name on Darwin.
2+
3+
//
4+
// All platforms
5+
//
6+
7+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
8+
// RUN: --target=x86_64-apple-macos \
9+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
10+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-MACOS %s
11+
// CHECK-CLANGRT-MACOS: libclang_rt.osx.a
12+
13+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
14+
// RUN: --target=arm64-apple-ios \
15+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
16+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-IOS %s
17+
// CHECK-CLANGRT-IOS: libclang_rt.ios.a
18+
19+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
20+
// RUN: --target=arm64-apple-watchos \
21+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
22+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-WATCHOS %s
23+
// CHECK-CLANGRT-WATCHOS: libclang_rt.watchos.a
24+
25+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
26+
// RUN: --target=arm64-apple-tvos \
27+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
28+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-TVOS %s
29+
// CHECK-CLANGRT-TVOS: libclang_rt.tvos.a
30+
31+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
32+
// RUN: --target=arm64-apple-driverkit \
33+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
34+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-DRIVERKIT %s
35+
// CHECK-CLANGRT-DRIVERKIT: libclang_rt.driverkit.a
36+
37+
//
38+
// Simulators
39+
//
40+
41+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
42+
// RUN: --target=arm64-apple-ios-simulator \
43+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
44+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-IOS-SIMULATOR %s
45+
// CHECK-CLANGRT-IOS-SIMULATOR: libclang_rt.iossim.a
46+
47+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
48+
// RUN: --target=arm64-apple-watchos-simulator \
49+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
50+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-WATCHOS-SIMULATOR %s
51+
// CHECK-CLANGRT-WATCHOS-SIMULATOR: libclang_rt.watchossim.a
52+
53+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
54+
// RUN: --target=arm64-apple-tvos-simulator \
55+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
56+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-TVOS-SIMULATOR %s
57+
// CHECK-CLANGRT-TVOS-SIMULATOR: libclang_rt.tvossim.a
58+
59+
// Check the sanitizer and profile variants
60+
// While the driver also links in sanitizer-specific dylibs, the result of
61+
// -print-libgcc-file-name is the path of the basic compiler-rt library.
62+
63+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
64+
// RUN: -fsanitize=address --target=x86_64-apple-macos \
65+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
66+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-MACOS-SAN %s
67+
// CHECK-CLANGRT-MACOS-SAN: libclang_rt.osx.a
68+
69+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
70+
// RUN: -fsanitize=address --target=arm64-apple-ios \
71+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
72+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-IOS-SAN %s
73+
// CHECK-CLANGRT-IOS-SAN: libclang_rt.ios.a
74+
75+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
76+
// RUN: -fsanitize=address --target=arm64-apple-watchos \
77+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
78+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-WATCHOS-SAN %s
79+
// CHECK-CLANGRT-WATCHOS-SAN: libclang_rt.watchos.a
80+
81+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
82+
// RUN: -fsanitize=address --target=arm64-apple-tvos \
83+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
84+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-TVOS-SAN %s
85+
// CHECK-CLANGRT-TVOS-SAN: libclang_rt.tvos.a
86+
87+
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
88+
// RUN: -fsanitize=address --target=arm64-apple-driverkit \
89+
// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
90+
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-DRIVERKIT-SAN %s
91+
// CHECK-CLANGRT-DRIVERKIT-SAN: libclang_rt.driverkit.a

0 commit comments

Comments
 (0)