[flang-rt] Pass the whole path of libflang_rt.runtime.a to linker on AIX and LoP (#131041)

This PR is to improve the driver code to build `flang-rt` path by
re-using the logic and code of `compiler-rt`.

1. Moved `addFortranRuntimeLibraryPath` and `addFortranRuntimeLibs` to
`ToolChain.h` and made them virtual so that they can be overridden if
customization is needed. The current implementation of those two
procedures is moved to `ToolChain.cpp` as the base implementation to
default to.

2. Both AIX and PPCLinux now override `addFortranRuntimeLibs`. 
The overriding function of `addFortranRuntimeLibs` for both AIX and
PPCLinux calls `getCompilerRTArgString` => `getCompilerRT` =>
`buildCompilerRTBasename` to get the path to `flang-rt`. This code
handles `LLVM_ENABLE_PER_TARGET_RUNTIME_DIR` setting. As shown in
`PPCLinux.cpp`, `FT_static` is the default. If not found, it will search
and build for `FT_shared`. To differentiate `flang-rt` from `clang-rt`,
a boolean flag `IsFortran` is passed to the chain of functions in order
to reach `buildCompilerRTBasename`.
This commit is contained in:
Daniel Chen 2025-04-03 11:21:19 -04:00 committed by GitHub
parent f23bb530cf
commit 2080334574
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 206 additions and 130 deletions

View File

@ -216,8 +216,8 @@ protected:
virtual std::string buildCompilerRTBasename(const llvm::opt::ArgList &Args,
StringRef Component,
FileType Type,
bool AddArch) const;
FileType Type, bool AddArch,
bool IsFortran = false) const;
/// Find the target-specific subdirectory for the current target triple under
/// \p BaseDir, doing fallback triple searches as necessary.
@ -509,11 +509,22 @@ public:
virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
StringRef Component,
FileType Type = ToolChain::FT_Static) const;
FileType Type = ToolChain::FT_Static,
bool IsFortran = false) const;
const char *
getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component,
FileType Type = ToolChain::FT_Static) const;
/// Adds Fortran runtime libraries to \p CmdArgs.
virtual void addFortranRuntimeLibs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
/// Adds the path for the Fortran runtime libraries to \p CmdArgs.
virtual void
addFortranRuntimeLibraryPath(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
const char *getCompilerRTArgString(const llvm::opt::ArgList &Args,
StringRef Component,
FileType Type = ToolChain::FT_Static,
bool IsFortran = false) const;
std::string getCompilerRTBasename(const llvm::opt::ArgList &Args,
StringRef Component,

View File

@ -727,8 +727,8 @@ std::string ToolChain::getCompilerRTBasename(const ArgList &Args,
std::string ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args,
StringRef Component,
FileType Type,
bool AddArch) const {
FileType Type, bool AddArch,
bool IsFortran) const {
const llvm::Triple &TT = getTriple();
bool IsITANMSVCWindows =
TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
@ -756,14 +756,16 @@ std::string ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args,
const char *Env = TT.isAndroid() ? "-android" : "";
ArchAndEnv = ("-" + Arch + Env).str();
}
return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str();
std::string LibName = IsFortran ? "flang_rt." : "clang_rt.";
return (Prefix + Twine(LibName) + Component + ArchAndEnv + Suffix).str();
}
std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
FileType Type) const {
FileType Type, bool IsFortran) const {
// Check for runtime files in the new layout without the architecture first.
std::string CRTBasename =
buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false);
std::string CRTBasename = buildCompilerRTBasename(
Args, Component, Type, /*AddArch=*/false, IsFortran);
SmallString<128> Path;
for (const auto &LibPath : getLibraryPaths()) {
SmallString<128> P(LibPath);
@ -775,8 +777,8 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
}
// Check the filename for the old layout if the new one does not exist.
CRTBasename =
buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/true);
CRTBasename = buildCompilerRTBasename(Args, Component, Type,
/*AddArch=*/!IsFortran, IsFortran);
SmallString<128> OldPath(getCompilerRTPath());
llvm::sys::path::append(OldPath, CRTBasename);
if (Path.empty() || getVFS().exists(OldPath))
@ -790,8 +792,62 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
StringRef Component,
FileType Type) const {
return Args.MakeArgString(getCompilerRT(Args, Component, Type));
FileType Type,
bool isFortran) const {
return Args.MakeArgString(getCompilerRT(Args, Component, Type, isFortran));
}
/// Add Fortran runtime libs
void ToolChain::addFortranRuntimeLibs(const ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const {
// Link flang_rt.runtime
// These are handled earlier on Windows by telling the frontend driver to
// add the correct libraries to link against as dependents in the object
// file.
if (!getTriple().isKnownWindowsMSVCEnvironment()) {
StringRef F128LibName = getDriver().getFlangF128MathLibrary();
F128LibName.consume_front_insensitive("lib");
if (!F128LibName.empty()) {
bool AsNeeded = !getTriple().isOSAIX();
CmdArgs.push_back("-lflang_rt.quadmath");
if (AsNeeded)
addAsNeededOption(*this, Args, CmdArgs, /*as_needed=*/true);
CmdArgs.push_back(Args.MakeArgString("-l" + F128LibName));
if (AsNeeded)
addAsNeededOption(*this, Args, CmdArgs, /*as_needed=*/false);
}
CmdArgs.push_back("-lflang_rt.runtime");
addArchSpecificRPath(*this, Args, CmdArgs);
// needs libexecinfo for backtrace functions
if (getTriple().isOSFreeBSD() || getTriple().isOSNetBSD() ||
getTriple().isOSOpenBSD() || getTriple().isOSDragonFly())
CmdArgs.push_back("-lexecinfo");
}
// libomp needs libatomic for atomic operations if using libgcc
if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
options::OPT_fno_openmp, false)) {
Driver::OpenMPRuntimeKind OMPRuntime = getDriver().getOpenMPRuntime(Args);
ToolChain::RuntimeLibType RuntimeLib = GetRuntimeLibType(Args);
if (OMPRuntime == Driver::OMPRT_OMP && RuntimeLib == ToolChain::RLT_Libgcc)
CmdArgs.push_back("-latomic");
}
}
void ToolChain::addFortranRuntimeLibraryPath(const llvm::opt::ArgList &Args,
ArgStringList &CmdArgs) const {
// Default to the <driver-path>/../lib directory. This works fine on the
// platforms that we have tested so far. We will probably have to re-fine
// this in the future. In particular, on some platforms, we may need to use
// lib64 instead of lib.
SmallString<256> DefaultLibPath =
llvm::sys::path::parent_path(getDriver().Dir);
llvm::sys::path::append(DefaultLibPath, "lib");
if (getTriple().isKnownWindowsMSVCEnvironment())
CmdArgs.push_back(Args.MakeArgString("-libpath:" + DefaultLibPath));
else
CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
}
// Android target triples contain a target version. If we don't have libraries

View File

@ -358,8 +358,8 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (D.IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
CmdArgs.push_back("-lm");
CmdArgs.push_back("-lpthread");
}
@ -608,6 +608,14 @@ void AIX::addProfileRTLibs(const llvm::opt::ArgList &Args,
ToolChain::addProfileRTLibs(Args, CmdArgs);
}
void AIX::addFortranRuntimeLibs(const ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const {
// Link flang_rt.runtime.a. On AIX, the static and shared library are all
// named .a
CmdArgs.push_back(
getCompilerRTArgString(Args, "runtime", ToolChain::FT_Static, true));
}
ToolChain::CXXStdlibType AIX::GetDefaultCXXStdlibType() const {
return ToolChain::CST_Libcxx;
}

View File

@ -87,6 +87,9 @@ public:
void addProfileRTLibs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
void addFortranRuntimeLibs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
CXXStdlibType GetDefaultCXXStdlibType() const override;
RuntimeLibType GetDefaultRuntimeLibType() const override;

View File

@ -424,9 +424,10 @@ Tool *AVRToolChain::buildLinker() const {
return new tools::AVR::Linker(getTriple(), *this);
}
std::string
AVRToolChain::getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
FileType Type = ToolChain::FT_Static) const {
std::string AVRToolChain::getCompilerRT(const llvm::opt::ArgList &Args,
StringRef Component,
FileType Type = ToolChain::FT_Static,
bool IsFortran) const {
assert(Type == ToolChain::FT_Static && "AVR only supports static libraries");
// Since AVR can never be a host environment, its compiler-rt library files
// should always have ".a" suffix, even on windows.

View File

@ -34,7 +34,8 @@ public:
std::optional<std::string> findAVRLibcInstallation() const;
StringRef getGCCInstallPath() const { return GCCInstallPath; }
std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
FileType Type) const override;
FileType Type,
bool IsFortran = false) const override;
bool HasNativeLLVMSupport() const override { return true; }

View File

@ -1339,61 +1339,6 @@ void tools::addOpenMPHostOffloadingArgs(const Compilation &C,
Args.MakeArgString(Twine(Targets) + llvm::join(Triples, ",")));
}
/// Add Fortran runtime libs
void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) {
// Link flang_rt.runtime
// These are handled earlier on Windows by telling the frontend driver to
// add the correct libraries to link against as dependents in the object
// file.
if (!TC.getTriple().isKnownWindowsMSVCEnvironment()) {
StringRef F128LibName = TC.getDriver().getFlangF128MathLibrary();
F128LibName.consume_front_insensitive("lib");
if (!F128LibName.empty()) {
bool AsNeeded = !TC.getTriple().isOSAIX();
CmdArgs.push_back("-lflang_rt.quadmath");
if (AsNeeded)
addAsNeededOption(TC, Args, CmdArgs, /*as_needed=*/true);
CmdArgs.push_back(Args.MakeArgString("-l" + F128LibName));
if (AsNeeded)
addAsNeededOption(TC, Args, CmdArgs, /*as_needed=*/false);
}
CmdArgs.push_back("-lflang_rt.runtime");
addArchSpecificRPath(TC, Args, CmdArgs);
// needs libexecinfo for backtrace functions
if (TC.getTriple().isOSFreeBSD() || TC.getTriple().isOSNetBSD() ||
TC.getTriple().isOSOpenBSD() || TC.getTriple().isOSDragonFly())
CmdArgs.push_back("-lexecinfo");
}
// libomp needs libatomic for atomic operations if using libgcc
if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
options::OPT_fno_openmp, false)) {
Driver::OpenMPRuntimeKind OMPRuntime =
TC.getDriver().getOpenMPRuntime(Args);
ToolChain::RuntimeLibType RuntimeLib = TC.GetRuntimeLibType(Args);
if (OMPRuntime == Driver::OMPRT_OMP && RuntimeLib == ToolChain::RLT_Libgcc)
CmdArgs.push_back("-latomic");
}
}
void tools::addFortranRuntimeLibraryPath(const ToolChain &TC,
const llvm::opt::ArgList &Args,
ArgStringList &CmdArgs) {
// Default to the <driver-path>/../lib directory. This works fine on the
// platforms that we have tested so far. We will probably have to re-fine
// this in the future. In particular, on some platforms, we may need to use
// lib64 instead of lib.
SmallString<256> DefaultLibPath =
llvm::sys::path::parent_path(TC.getDriver().Dir);
llvm::sys::path::append(DefaultLibPath, "lib");
if (TC.getTriple().isKnownWindowsMSVCEnvironment())
CmdArgs.push_back(Args.MakeArgString("-libpath:" + DefaultLibPath));
else
CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
}
static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs, StringRef Sanitizer,
bool IsShared, bool IsWhole) {

View File

@ -121,15 +121,6 @@ void addOpenMPHostOffloadingArgs(const Compilation &C, const JobAction &JA,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
/// Adds Fortran runtime libraries to \p CmdArgs.
void addFortranRuntimeLibs(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
/// Adds the path for the Fortran runtime libraries to \p CmdArgs.
void addFortranRuntimeLibraryPath(const ToolChain &TC,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
void addHIPRuntimeLibArgs(const ToolChain &TC, Compilation &C,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);

View File

@ -706,8 +706,8 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// to generate executables.
if (getToolChain().getDriver().IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs);
addFortranRuntimeLibs(getToolChain(), Args, CmdArgs);
getToolChain().addFortranRuntimeLibraryPath(Args, CmdArgs);
getToolChain().addFortranRuntimeLibs(Args, CmdArgs);
}
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
@ -1348,7 +1348,7 @@ void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
}
std::string MachO::getCompilerRT(const ArgList &, StringRef Component,
FileType Type) const {
FileType Type, bool IsFortran) const {
assert(Type != ToolChain::FT_Object &&
"it doesn't make sense to ask for the compiler-rt library name as an "
"object file");
@ -1367,7 +1367,7 @@ std::string MachO::getCompilerRT(const ArgList &, StringRef Component,
}
std::string Darwin::getCompilerRT(const ArgList &, StringRef Component,
FileType Type) const {
FileType Type, bool IsFortran) const {
assert(Type != ToolChain::FT_Object &&
"it doesn't make sense to ask for the compiler-rt library name as an "
"object file");

View File

@ -232,9 +232,9 @@ public:
// 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;
std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
FileType Type = ToolChain::FT_Static,
bool IsFortran = false) const override;
/// }
/// @name ToolChain Implementation
@ -412,9 +412,9 @@ public:
// 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;
std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
FileType Type = ToolChain::FT_Static,
bool IsFortran = false) const override;
protected:
/// }

View File

@ -153,8 +153,8 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
CmdArgs.push_back("-lm");
}

View File

@ -319,8 +319,8 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
if (Profiling)
CmdArgs.push_back("-lm_p");
else

View File

@ -572,8 +572,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
CmdArgs.push_back("-lm");
}

View File

@ -123,8 +123,8 @@ void haiku::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
}
if (NeedsSanitizerDeps)

View File

@ -146,8 +146,8 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (C.getDriver().IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(TC, Args, CmdArgs);
addFortranRuntimeLibs(TC, Args, CmdArgs);
TC.addFortranRuntimeLibraryPath(Args, CmdArgs);
TC.addFortranRuntimeLibs(Args, CmdArgs);
// Inform the MSVC linker that we're generating a console application, i.e.
// one with `main` as the "user-defined" entry point. The `main` function is

View File

@ -259,8 +259,8 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (C.getDriver().IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(TC, Args, CmdArgs);
addFortranRuntimeLibs(TC, Args, CmdArgs);
TC.addFortranRuntimeLibraryPath(Args, CmdArgs);
TC.addFortranRuntimeLibs(Args, CmdArgs);
}
// TODO: Add profile stuff here

View File

@ -118,8 +118,8 @@ void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
}
std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args,
StringRef Component,
FileType Type) const {
StringRef Component, FileType Type,
bool IsFortran) const {
SmallString<128> Path(getDriver().ResourceDir);
llvm::sys::path::append(Path, SelectedMultilibs.back().osSuffix(), "lib" + LibSuffix,
getOS());

View File

@ -37,9 +37,9 @@ public:
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
std::string
getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
FileType Type = ToolChain::FT_Static) const override;
std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
FileType Type = ToolChain::FT_Static,
bool IsFortran = false) const override;
std::string computeSysRoot() const override;

View File

@ -328,8 +328,8 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
CmdArgs.push_back("-lm");
}

View File

@ -341,7 +341,7 @@ std::string OHOS::getDynamicLinker(const ArgList &Args) const {
}
std::string OHOS::getCompilerRT(const ArgList &Args, StringRef Component,
FileType Type) const {
FileType Type, bool IsFortran) const {
SmallString<128> Path(getDriver().ResourceDir);
llvm::sys::path::append(Path, "lib", getMultiarchTriple(getTriple()),
SelectedMultilib.gccSuffix());

View File

@ -56,9 +56,9 @@ public:
std::string computeSysRoot() const override;
std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override;
std::string
getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
FileType Type = ToolChain::FT_Static) const override;
std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
FileType Type = ToolChain::FT_Static,
bool IsFortran = false) const override;
const char *getDefaultLinker() const override {
return "ld.lld";

View File

@ -241,8 +241,8 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// AddRunTimeLibs).
if (D.IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
if (Profiling)
CmdArgs.push_back("-lm_p");
else
@ -372,7 +372,7 @@ void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args,
}
std::string OpenBSD::getCompilerRT(const ArgList &Args, StringRef Component,
FileType Type) const {
FileType Type, bool IsFortran) const {
if (Component == "builtins") {
SmallString<128> Path(getDriver().SysRoot);
llvm::sys::path::append(Path, "/usr/lib/libcompiler_rt.a");
@ -380,13 +380,13 @@ std::string OpenBSD::getCompilerRT(const ArgList &Args, StringRef Component,
return std::string(Path);
}
SmallString<128> P(getDriver().ResourceDir);
std::string CRTBasename =
buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false);
std::string CRTBasename = buildCompilerRTBasename(
Args, Component, Type, /*AddArch=*/false, IsFortran);
llvm::sys::path::append(P, "lib", CRTBasename);
// Checks if this is the base system case which uses a different location.
if (getVFS().exists(P))
return std::string(P);
return ToolChain::getCompilerRT(Args, Component, Type);
return ToolChain::getCompilerRT(Args, Component, Type, IsFortran);
}
Tool *OpenBSD::buildAssembler() const {

View File

@ -80,7 +80,8 @@ public:
llvm::opt::ArgStringList &CmdArgs) const override;
std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
FileType Type = ToolChain::FT_Static) const override;
FileType Type = ToolChain::FT_Static,
bool IsFortran = false) const override;
UnwindTableLevel
getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override;

View File

@ -12,6 +12,7 @@
#include "clang/Driver/Options.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VirtualFileSystem.h"
using namespace clang::driver;
using namespace clang::driver::toolchains;
@ -101,3 +102,18 @@ bool PPCLinuxToolChain::SupportIEEEFloat128(
return GlibcSupportsFloat128((Twine(D.DyldPrefix) + Linker).str()) &&
!(D.CCCIsCXX() && HasUnsupportedCXXLib);
}
void PPCLinuxToolChain::addFortranRuntimeLibs(
const ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const {
// Link static flang_rt.runtime.a or shared flang_rt.runtime.so
const char *Path;
if (getVFS().exists(Twine(Path = getCompilerRTArgString(
Args, "runtime", ToolChain::FT_Static, true))))
CmdArgs.push_back(Path);
else if (getVFS().exists(
Twine(Path = getCompilerRTArgString(
Args, "runtime", ToolChain::FT_Shared, true))))
CmdArgs.push_back(Path);
else
CmdArgs.push_back("-lflang_rt.runtime");
}

View File

@ -24,6 +24,9 @@ public:
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
void addFortranRuntimeLibs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
private:
bool SupportIEEEFloat128(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args) const;

View File

@ -225,8 +225,8 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// these dependencies need to be listed before the C runtime below.
if (D.IsFlangMode() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs);
addFortranRuntimeLibs(getToolChain(), Args, CmdArgs);
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
CmdArgs.push_back("-lm");
}
if (Args.hasArg(options::OPT_fstack_protector) ||

View File

@ -34,9 +34,8 @@
function (get_toolchain_library_subdir outvar)
set(outval "lib")
if (APPLE OR (UNIX AND CMAKE_SYSTEM_NAME MATCHES "AIX"))
if (APPLE)
# Required to be "darwin" for MachO toolchain.
# AIX uses lib/${os_dir} as if LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF
get_toolchain_os_dirname(os_dirname)
set(outval "${outval}/${os_dirname}")
else ()

View File

@ -0,0 +1,41 @@
!! Testing ld command with flang on POWERPC.
!! TODO: The AIX test case is meant to test the behavior of linking the static
!! libflang_rt.runtime.a, which will be enabled by a new compiler option
!! -static-libflang_rt in the future. Need to add that option here.
!! Because flang-rt currently only supports
!! LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON, use
!! resource_dir_with_per_target_subdir as inputs.
! Check powerpc64-ibm-aix 64-bit linking to static flang-rt
! RUN: %flang %s -### 2>&1 \
! RUN: --target=powerpc64-ibm-aix \
! RUN: -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_per_target_subdir \
! RUN: | FileCheck %s --check-prefix=AIX64-LD-PER-TARGET
! AIX64-LD-PER-TARGET-NOT: warning:
! AIX64-LD-PER-TARGET: "-fc1" "-triple" "powerpc64-ibm-aix"
! AIX64-LD-PER-TARGET-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
! AIX64-LD-PER-TARGET: "{{.*}}ld{{(.exe)?}}"
! AIX64-LD-PER-TARGET-NOT: "-bnso"
! AIX64-LD-PER-TARGET-SAME: "-b64"
! AIX64-LD-PER-TARGET-SAME: "-bpT:0x100000000" "-bpD:0x110000000"
! AIX64-LD-PER-TARGET-SAME: "-lc"
! AIX64-LD-PER-TARGET-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}powerpc64-ibm-aix{{/|\\\\}}libflang_rt.runtime.a"
! AIX64-LD-PER-TARGET-SAME: "-lm"
! AIX64-LD-PER-TARGET-SAME: "-lpthread"
! Check powerpc64le-unknown-linux-gnu 64-bit linking to static flang-rt
! RUN: %flang %s -### 2>&1 \
! RUN: --target=powerpc64le-unknown-linux-gnu \
! RUN: -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_per_target_subdir \
! RUN: | FileCheck %s --check-prefixes=LOP64-LD-PER-TARGET
! LOP64-LD-PER-TARGET-NOT: warning:
! LOP64-LD-PER-TARGET: "-fc1" "-triple" "powerpc64le-unknown-linux-gnu"
! LOP64-LD-PER-TARGET-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
! LOP64-LD-PER-TARGET: "{{.*}}ld{{(.exe)?}}"
! LOP64-LD-PER-TARGET-NOT: "-bnso"
! LOP64-LD-PER-TARGET-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}powerpc64le-unknown-linux-gnu{{/|\\\\}}libflang_rt.runtime.a"
! LOP64-LD-PER-TARGET-SAME: "-lm"
! LOP64-LD-PER-TARGET-SAME: "-lc"