[Clang] Let the linker choose shared or static libunwind unless specified

We shouldn't assume that libunwind.so is available. Rather can defer
the decision to the linker which defaults to libunwind.so, but if .so
isn't available, it'd pick libunwind.a. Users can use -static-libgcc
and -shared-libgcc to override this behavior and explicitly choose
the version they want.

Differential Revision: https://reviews.llvm.org/D127528
This commit is contained in:
Petr Hosek 2022-05-28 05:53:16 +00:00
parent 8c4a07c61f
commit 55ba0830e4
2 changed files with 23 additions and 18 deletions

View File

@ -1462,17 +1462,12 @@ enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
static LibGccType getLibGccType(const ToolChain &TC, const Driver &D,
const ArgList &Args) {
if (Args.hasArg(options::OPT_static_libgcc) ||
Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_static_pie))
Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_static_pie) ||
// The Android NDK only provides libunwind.a, not libunwind.so.
TC.getTriple().isAndroid())
return LibGccType::StaticLibGcc;
if (Args.hasArg(options::OPT_shared_libgcc))
return LibGccType::SharedLibGcc;
// The Android NDK only provides libunwind.a, not libunwind.so.
if (TC.getTriple().isAndroid())
return LibGccType::StaticLibGcc;
// For MinGW, don't imply a shared libgcc here, we only want to return
// SharedLibGcc if that was explicitly requested.
if (D.CCCIsCXX() && !TC.getTriple().isOSCygMing())
return LibGccType::SharedLibGcc;
return LibGccType::UnspecifiedLibGcc;
}
@ -1499,7 +1494,7 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
return;
LibGccType LGT = getLibGccType(TC, D, Args);
bool AsNeeded = LGT == LibGccType::UnspecifiedLibGcc &&
bool AsNeeded = LGT == LibGccType::UnspecifiedLibGcc && !D.CCCIsCXX() &&
!TC.getTriple().isAndroid() &&
!TC.getTriple().isOSCygMing() && !TC.getTriple().isOSAIX();
if (AsNeeded)
@ -1523,15 +1518,15 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
CmdArgs.push_back("-lunwind");
} else if (LGT == LibGccType::StaticLibGcc) {
CmdArgs.push_back("-l:libunwind.a");
} else if (TC.getTriple().isOSCygMing()) {
if (LGT == LibGccType::SharedLibGcc)
} else if (LGT == LibGccType::SharedLibGcc) {
if (TC.getTriple().isOSCygMing())
CmdArgs.push_back("-l:libunwind.dll.a");
else
// Let the linker choose between libunwind.dll.a and libunwind.a
// depending on what's available, and depending on the -static flag
CmdArgs.push_back("-lunwind");
CmdArgs.push_back("-l:libunwind.so");
} else {
CmdArgs.push_back("-l:libunwind.so");
// Let the linker choose between libunwind.so and libunwind.a
// depending on what's available, and depending on the -static flag
CmdArgs.push_back("-lunwind");
}
break;
}
@ -1543,10 +1538,12 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
static void AddLibgcc(const ToolChain &TC, const Driver &D,
ArgStringList &CmdArgs, const ArgList &Args) {
LibGccType LGT = getLibGccType(TC, D, Args);
if (LGT != LibGccType::SharedLibGcc)
if (LGT == LibGccType::StaticLibGcc ||
(LGT == LibGccType::UnspecifiedLibGcc && !D.CCCIsCXX()))
CmdArgs.push_back("-lgcc");
AddUnwindLibrary(TC, D, CmdArgs, Args);
if (LGT == LibGccType::SharedLibGcc)
if (LGT == LibGccType::SharedLibGcc ||
(LGT == LibGccType::UnspecifiedLibGcc && D.CCCIsCXX()))
CmdArgs.push_back("-lgcc");
}

View File

@ -13,7 +13,15 @@
// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \
// RUN: | FileCheck --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER-RT %s
// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lgcc"
// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}l:libunwind.so"
// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lunwind"
//
// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
// RUN: -shared-libgcc \
// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \
// RUN: | FileCheck --check-prefix=RTLIB-GCC-SHARED-UNWINDLIB-COMPILER-RT %s
// RTLIB-GCC-SHARED-UNWINDLIB-COMPILER-RT: "{{.*}}l:libunwind.so"
// RTLIB-GCC-SHARED-UNWINDLIB-COMPILER-RT: "{{.*}}lgcc"
//
// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \