[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`.
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index f2e8fa3..076e429 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -216,8 +216,8 @@
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 @@
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,
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index ad73814..36d0ae3 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -727,8 +727,8 @@
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 @@
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 @@
}
// 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 @@
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
diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp
index 001f3a51..26b9d4c 100644
--- a/clang/lib/Driver/ToolChains/AIX.cpp
+++ b/clang/lib/Driver/ToolChains/AIX.cpp
@@ -358,8 +358,8 @@
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 @@
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;
}
diff --git a/clang/lib/Driver/ToolChains/AIX.h b/clang/lib/Driver/ToolChains/AIX.h
index 8f130f6..17e8370 100644
--- a/clang/lib/Driver/ToolChains/AIX.h
+++ b/clang/lib/Driver/ToolChains/AIX.h
@@ -87,6 +87,9 @@
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;
diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp
index 08e906a..8b8956a 100644
--- a/clang/lib/Driver/ToolChains/AVR.cpp
+++ b/clang/lib/Driver/ToolChains/AVR.cpp
@@ -424,9 +424,10 @@
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.
diff --git a/clang/lib/Driver/ToolChains/AVR.h b/clang/lib/Driver/ToolChains/AVR.h
index 247188b..f4d74eb 100644
--- a/clang/lib/Driver/ToolChains/AVR.h
+++ b/clang/lib/Driver/ToolChains/AVR.h
@@ -34,7 +34,8 @@
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; }
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 5aac20e..ddeadff 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1339,61 +1339,6 @@
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) {
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 9b280e5..96bc061 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -121,15 +121,6 @@
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);
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 32a5fe6..e41720a 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -706,8 +706,8 @@
// 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 @@
}
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 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");
diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h
index 751a3ba..76523d6 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -232,9 +232,9 @@
// 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 @@
// 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:
/// }
diff --git a/clang/lib/Driver/ToolChains/DragonFly.cpp b/clang/lib/Driver/ToolChains/DragonFly.cpp
index 1e0a415..38a29ae 100644
--- a/clang/lib/Driver/ToolChains/DragonFly.cpp
+++ b/clang/lib/Driver/ToolChains/DragonFly.cpp
@@ -153,8 +153,8 @@
// 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");
}
diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp
index 62206c5..e7efe22 100644
--- a/clang/lib/Driver/ToolChains/FreeBSD.cpp
+++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp
@@ -319,8 +319,8 @@
// 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
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index a0fa3c6..d53039f 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -572,8 +572,8 @@
// 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");
}
diff --git a/clang/lib/Driver/ToolChains/Haiku.cpp b/clang/lib/Driver/ToolChains/Haiku.cpp
index 17fb724..0e55a71 100644
--- a/clang/lib/Driver/ToolChains/Haiku.cpp
+++ b/clang/lib/Driver/ToolChains/Haiku.cpp
@@ -123,8 +123,8 @@
// 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)
diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp
index d5a7fc7..9ae61a5 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -146,8 +146,8 @@
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
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index 9f0c616..0312406 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -259,8 +259,8 @@
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
diff --git a/clang/lib/Driver/ToolChains/MipsLinux.cpp b/clang/lib/Driver/ToolChains/MipsLinux.cpp
index f61ae47..0d02593 100644
--- a/clang/lib/Driver/ToolChains/MipsLinux.cpp
+++ b/clang/lib/Driver/ToolChains/MipsLinux.cpp
@@ -118,8 +118,8 @@
}
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());
diff --git a/clang/lib/Driver/ToolChains/MipsLinux.h b/clang/lib/Driver/ToolChains/MipsLinux.h
index a968804..f9bf2e1 100644
--- a/clang/lib/Driver/ToolChains/MipsLinux.h
+++ b/clang/lib/Driver/ToolChains/MipsLinux.h
@@ -37,9 +37,9 @@
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;
diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp
index c5469f3..ae164be 100644
--- a/clang/lib/Driver/ToolChains/NetBSD.cpp
+++ b/clang/lib/Driver/ToolChains/NetBSD.cpp
@@ -328,8 +328,8 @@
// 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");
}
diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp
index e213c69..1cfa2a8 100644
--- a/clang/lib/Driver/ToolChains/OHOS.cpp
+++ b/clang/lib/Driver/ToolChains/OHOS.cpp
@@ -341,7 +341,7 @@
}
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());
diff --git a/clang/lib/Driver/ToolChains/OHOS.h b/clang/lib/Driver/ToolChains/OHOS.h
index 2a38042..0e0543b 100644
--- a/clang/lib/Driver/ToolChains/OHOS.h
+++ b/clang/lib/Driver/ToolChains/OHOS.h
@@ -56,9 +56,9 @@
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";
diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp
index f668a11..a5b1f06 100644
--- a/clang/lib/Driver/ToolChains/OpenBSD.cpp
+++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp
@@ -241,8 +241,8 @@
// 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 @@
}
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 @@
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 {
diff --git a/clang/lib/Driver/ToolChains/OpenBSD.h b/clang/lib/Driver/ToolChains/OpenBSD.h
index b4350e7..11b873c 100644
--- a/clang/lib/Driver/ToolChains/OpenBSD.h
+++ b/clang/lib/Driver/ToolChains/OpenBSD.h
@@ -80,7 +80,8 @@
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;
diff --git a/clang/lib/Driver/ToolChains/PPCLinux.cpp b/clang/lib/Driver/ToolChains/PPCLinux.cpp
index 0ed0f91..575e88c 100644
--- a/clang/lib/Driver/ToolChains/PPCLinux.cpp
+++ b/clang/lib/Driver/ToolChains/PPCLinux.cpp
@@ -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 @@
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");
+}
diff --git a/clang/lib/Driver/ToolChains/PPCLinux.h b/clang/lib/Driver/ToolChains/PPCLinux.h
index 63adaff..910df3d 100644
--- a/clang/lib/Driver/ToolChains/PPCLinux.h
+++ b/clang/lib/Driver/ToolChains/PPCLinux.h
@@ -24,6 +24,9 @@
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;
diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp
index fd3232b..639497b 100644
--- a/clang/lib/Driver/ToolChains/Solaris.cpp
+++ b/clang/lib/Driver/ToolChains/Solaris.cpp
@@ -225,8 +225,8 @@
// 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) ||
diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/powerpc64-ibm-aix/libflang_rt.runtime.a b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/powerpc64-ibm-aix/libflang_rt.runtime.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/powerpc64-ibm-aix/libflang_rt.runtime.a
diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/powerpc64le-unknown-linux-gnu/libflang_rt.runtime.a b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/powerpc64le-unknown-linux-gnu/libflang_rt.runtime.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/powerpc64le-unknown-linux-gnu/libflang_rt.runtime.a
diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/powerpc64le-unknown-linux-gnu/libflang_rt.runtime.so b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/powerpc64le-unknown-linux-gnu/libflang_rt.runtime.so
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/powerpc64le-unknown-linux-gnu/libflang_rt.runtime.so
diff --git a/flang-rt/cmake/modules/GetToolchainDirs.cmake b/flang-rt/cmake/modules/GetToolchainDirs.cmake
index 8b38418..fba1250 100644
--- a/flang-rt/cmake/modules/GetToolchainDirs.cmake
+++ b/flang-rt/cmake/modules/GetToolchainDirs.cmake
@@ -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 ()
diff --git a/flang/test/Driver/flang-ld-powerpc.f90 b/flang/test/Driver/flang-ld-powerpc.f90
new file mode 100644
index 0000000..9a6ee45
--- /dev/null
+++ b/flang/test/Driver/flang-ld-powerpc.f90
@@ -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"