[clang] 7d8375b - [clang][driver] Fix -print-libgcc-file-name on Darwin platforms (#98325)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 19 05:24:41 PDT 2024
Author: Gábor Horváth
Date: 2024-07-19T13:24:38+01:00
New Revision: 7d8375b86ee490acafb4254603ccd4edc2a58256
URL: https://github.com/llvm/llvm-project/commit/7d8375b86ee490acafb4254603ccd4edc2a58256
DIFF: https://github.com/llvm/llvm-project/commit/7d8375b86ee490acafb4254603ccd4edc2a58256.diff
LOG: [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 <gaborh at apple.com>
Added:
clang/test/Driver/darwin-print-libgcc-file-name.c
Modified:
clang/include/clang/Driver/Driver.h
clang/lib/Driver/Driver.cpp
clang/lib/Driver/ToolChains/Darwin.cpp
clang/lib/Driver/ToolChains/Darwin.h
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index cc1538372d5f8..04b46782467d6 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -628,8 +628,9 @@ class Driver {
/// treated before building actions or binding tools.
///
/// \return Whether any compilation should be built for this
- /// invocation.
- bool HandleImmediateArgs(const Compilation &C);
+ /// invocation. The compilation can only be modified when
+ /// this function returns false.
+ bool HandleImmediateArgs(Compilation &C);
/// ConstructAction - Construct the appropriate action to do for
/// \p Phase on the \p Input, taking in to account arguments
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 28c3b52483e51..8e44d5afa40e0 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2128,7 +2128,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const {
llvm::outs() << llvm::join(SuggestedCompletions, "\n") << '\n';
}
-bool Driver::HandleImmediateArgs(const Compilation &C) {
+bool Driver::HandleImmediateArgs(Compilation &C) {
// The order these options are handled in gcc is all over the place, but we
// don't expect inconsistencies w.r.t. that to matter in practice.
@@ -2271,6 +2271,14 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(C.getArgs());
const llvm::Triple Triple(TC.ComputeEffectiveClangTriple(C.getArgs()));
+ // The 'Darwin' toolchain is initialized only when its arguments are
+ // computed. Get the default arguments for OFK_None to ensure that
+ // initialization is performed before trying to access properties of
+ // the toolchain in the functions below.
+ // FIXME: Remove when darwin's toolchain is initialized during construction.
+ // FIXME: For some more esoteric targets the default toolchain is not the
+ // correct one.
+ C.getArgsForToolChain(&TC, Triple.getArchName(), Action::OFK_None);
RegisterEffectiveTriple TripleRAII(TC, Triple);
switch (RLT) {
case ToolChain::RLT_CompilerRT:
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index f354b0974d5f2..c6f9d7beffb1d 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1272,23 +1272,8 @@ unsigned DarwinClang::GetDefaultDwarfVersion() const {
void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
StringRef Component, RuntimeLinkOptions Opts,
bool IsShared) const {
- SmallString<64> DarwinLibName = StringRef("libclang_rt.");
- // On Darwin the builtins component is not in the library name.
- if (Component != "builtins") {
- DarwinLibName += Component;
- if (!(Opts & RLO_IsEmbedded))
- DarwinLibName += "_";
- }
-
- DarwinLibName += getOSLibraryNameSuffix();
- DarwinLibName += IsShared ? "_dynamic.dylib" : ".a";
- SmallString<128> Dir(getDriver().ResourceDir);
- llvm::sys::path::append(Dir, "lib", "darwin");
- if (Opts & RLO_IsEmbedded)
- llvm::sys::path::append(Dir, "macho_embedded");
-
- SmallString<128> P(Dir);
- llvm::sys::path::append(P, DarwinLibName);
+ std::string P = getCompilerRT(
+ Args, Component, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static);
// For now, allow missing resource libraries to support developers who may
// not have compiler-rt checked out or integrated into their build (unless
@@ -1303,18 +1288,56 @@ void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
// rpaths. This is currently true from this place, but we need to be
// careful if this function is ever called before user's rpaths are emitted.
if (Opts & RLO_AddRPath) {
- assert(DarwinLibName.ends_with(".dylib") && "must be a dynamic library");
+ assert(StringRef(P).ends_with(".dylib") && "must be a dynamic library");
// Add @executable_path to rpath to support having the dylib copied with
// the executable.
CmdArgs.push_back("-rpath");
CmdArgs.push_back("@executable_path");
- // Add the path to the resource dir to rpath to support using the dylib
- // from the default location without copying.
+ // Add the compiler-rt library's directory to rpath to support using the
+ // dylib from the default location without copying.
CmdArgs.push_back("-rpath");
- CmdArgs.push_back(Args.MakeArgString(Dir));
+ CmdArgs.push_back(Args.MakeArgString(llvm::sys::path::parent_path(P)));
+ }
+}
+
+std::string MachO::getCompilerRT(const ArgList &, StringRef Component,
+ FileType Type) const {
+ assert(Type != ToolChain::FT_Object &&
+ "it doesn't make sense to ask for the compiler-rt library name as an "
+ "object file");
+ SmallString<64> MachOLibName = StringRef("libclang_rt");
+ // On MachO, the builtins component is not in the library name
+ if (Component != "builtins") {
+ MachOLibName += '.';
+ MachOLibName += Component;
+ }
+ MachOLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a";
+
+ SmallString<128> FullPath(getDriver().ResourceDir);
+ llvm::sys::path::append(FullPath, "lib", "darwin", "macho_embedded",
+ MachOLibName);
+ return std::string(FullPath);
+}
+
+std::string Darwin::getCompilerRT(const ArgList &, StringRef Component,
+ FileType Type) const {
+ assert(Type != ToolChain::FT_Object &&
+ "it doesn't make sense to ask for the compiler-rt library name as an "
+ "object file");
+ SmallString<64> DarwinLibName = StringRef("libclang_rt.");
+ // On Darwin, the builtins component is not in the library name
+ if (Component != "builtins") {
+ DarwinLibName += Component;
+ DarwinLibName += '_';
}
+ DarwinLibName += getOSLibraryNameSuffix();
+ DarwinLibName += Type == ToolChain::FT_Shared ? "_dynamic.dylib" : ".a";
+
+ SmallString<128> FullPath(getDriver().ResourceDir);
+ llvm::sys::path::append(FullPath, "lib", "darwin", DarwinLibName);
+ return std::string(FullPath);
}
StringRef Darwin::getPlatformFamily() const {
diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h
index b45279ecedeb2..2e55b49682a7e 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -223,6 +223,13 @@ class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
// There aren't any profiling libs for embedded targets currently.
}
+ // Return the full path of the compiler-rt library on a non-Darwin MachO
+ // system. Those are under
+ // <resourcedir>/lib/darwin/macho_embedded/<...>(.dylib|.a).
+ std::string
+ getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
+ FileType Type = ToolChain::FT_Static) const override;
+
/// }
/// @name ToolChain Implementation
/// {
@@ -356,6 +363,12 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
void addProfileRTLibs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
+ // Return the full path of the compiler-rt library on a Darwin MachO system.
+ // Those are under <resourcedir>/lib/darwin/<...>(.dylib|.a).
+ std::string
+ getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
+ FileType Type = ToolChain::FT_Static) const override;
+
protected:
/// }
/// @name Darwin specific Toolchain functions
diff --git a/clang/test/Driver/darwin-print-libgcc-file-name.c b/clang/test/Driver/darwin-print-libgcc-file-name.c
new file mode 100644
index 0000000000000..73e89b6718642
--- /dev/null
+++ b/clang/test/Driver/darwin-print-libgcc-file-name.c
@@ -0,0 +1,91 @@
+// Test the output of -print-libgcc-file-name on Darwin.
+
+//
+// All platforms
+//
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: --target=x86_64-apple-macos \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-MACOS %s
+// CHECK-CLANGRT-MACOS: libclang_rt.osx.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: --target=arm64-apple-ios \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-IOS %s
+// CHECK-CLANGRT-IOS: libclang_rt.ios.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: --target=arm64-apple-watchos \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-WATCHOS %s
+// CHECK-CLANGRT-WATCHOS: libclang_rt.watchos.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: --target=arm64-apple-tvos \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-TVOS %s
+// CHECK-CLANGRT-TVOS: libclang_rt.tvos.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: --target=arm64-apple-driverkit \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-DRIVERKIT %s
+// CHECK-CLANGRT-DRIVERKIT: libclang_rt.driverkit.a
+
+//
+// Simulators
+//
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: --target=arm64-apple-ios-simulator \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-IOS-SIMULATOR %s
+// CHECK-CLANGRT-IOS-SIMULATOR: libclang_rt.iossim.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: --target=arm64-apple-watchos-simulator \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-WATCHOS-SIMULATOR %s
+// CHECK-CLANGRT-WATCHOS-SIMULATOR: libclang_rt.watchossim.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: --target=arm64-apple-tvos-simulator \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-TVOS-SIMULATOR %s
+// CHECK-CLANGRT-TVOS-SIMULATOR: libclang_rt.tvossim.a
+
+// Check the sanitizer and profile variants
+// While the driver also links in sanitizer-specific dylibs, the result of
+// -print-libgcc-file-name is the path of the basic compiler-rt library.
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: -fsanitize=address --target=x86_64-apple-macos \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-MACOS-SAN %s
+// CHECK-CLANGRT-MACOS-SAN: libclang_rt.osx.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: -fsanitize=address --target=arm64-apple-ios \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-IOS-SAN %s
+// CHECK-CLANGRT-IOS-SAN: libclang_rt.ios.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: -fsanitize=address --target=arm64-apple-watchos \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-WATCHOS-SAN %s
+// CHECK-CLANGRT-WATCHOS-SAN: libclang_rt.watchos.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: -fsanitize=address --target=arm64-apple-tvos \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-TVOS-SAN %s
+// CHECK-CLANGRT-TVOS-SAN: libclang_rt.tvos.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
+// RUN: -fsanitize=address --target=arm64-apple-driverkit \
+// RUN: -resource-dir=%S/Inputs/resource_dir 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-DRIVERKIT-SAN %s
+// CHECK-CLANGRT-DRIVERKIT-SAN: libclang_rt.driverkit.a
More information about the cfe-commits
mailing list