Skip to content

Commit

Permalink
Fix --print-libgcc-file-name on Darwin platforms
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Gabor Horvath committed Jul 10, 2024
1 parent f50f7a7 commit bbd66df
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 23 deletions.
5 changes: 3 additions & 2 deletions clang/include/clang/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -2271,6 +2271,12 @@ 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.
C.getArgsForToolChain(&TC, Triple.getArchName(), Action::OFK_None);
RegisterEffectiveTriple TripleRAII(TC, Triple);
switch (RLT) {
case ToolChain::RLT_CompilerRT:
Expand Down
61 changes: 41 additions & 20 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -1303,18 +1288,54 @@ 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
// 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 += 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 {
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/Driver/ToolChains/Darwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ 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 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;

/// }
/// @name ToolChain Implementation
/// {
Expand Down Expand Up @@ -356,6 +361,10 @@ 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
Expand Down
55 changes: 55 additions & 0 deletions clang/test/Driver/darwin-print-libgcc-file-name.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// 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

// TODO add simulators

//
// Check the cc_kext variants
//

// TODO

//
// Check the sanitizer and profile variants
//

// TODO

//
// Check the dynamic library variants
//

// TODO

0 comments on commit bbd66df

Please sign in to comment.