diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index f2e8fa306e3a..076e4296c309 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -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, diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index ad73814b3efb..36d0ae34dec8 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -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 diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp index 001f3a517894..26b9d4c772be 100644 --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -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; } diff --git a/clang/lib/Driver/ToolChains/AIX.h b/clang/lib/Driver/ToolChains/AIX.h index 8f130f6b5454..17e8370cd121 100644 --- a/clang/lib/Driver/ToolChains/AIX.h +++ b/clang/lib/Driver/ToolChains/AIX.h @@ -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; diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp index 08e906ac9e80..8b8956a0a15e 100644 --- a/clang/lib/Driver/ToolChains/AVR.cpp +++ b/clang/lib/Driver/ToolChains/AVR.cpp @@ -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. diff --git a/clang/lib/Driver/ToolChains/AVR.h b/clang/lib/Driver/ToolChains/AVR.h index 247188b7eaad..f4d74eb94425 100644 --- a/clang/lib/Driver/ToolChains/AVR.h +++ b/clang/lib/Driver/ToolChains/AVR.h @@ -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; } diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 5aac20e1cdf4..ddeadff8f6df 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -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) { diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 9b280e5d871c..96bc0619dcbc 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -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); diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 32a5fe68e8cf..e41720a82438 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -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"); diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h index 751a3ba2ad5e..76523d636ce0 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -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: /// } diff --git a/clang/lib/Driver/ToolChains/DragonFly.cpp b/clang/lib/Driver/ToolChains/DragonFly.cpp index 1e0a4159bf4a..38a29ae49e8d 100644 --- a/clang/lib/Driver/ToolChains/DragonFly.cpp +++ b/clang/lib/Driver/ToolChains/DragonFly.cpp @@ -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"); } diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp index 62206c5fb3c5..e7efe22aa59a 100644 --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -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 diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index a0fa3c66d7de..d53039f6302d 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -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"); } diff --git a/clang/lib/Driver/ToolChains/Haiku.cpp b/clang/lib/Driver/ToolChains/Haiku.cpp index 17fb724b6a7c..0e55a71280af 100644 --- a/clang/lib/Driver/ToolChains/Haiku.cpp +++ b/clang/lib/Driver/ToolChains/Haiku.cpp @@ -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) diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index d5a7fc7e8523..9ae61a528eb1 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -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 diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp index 9f0c6160a309..031240610eef 100644 --- a/clang/lib/Driver/ToolChains/MinGW.cpp +++ b/clang/lib/Driver/ToolChains/MinGW.cpp @@ -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 diff --git a/clang/lib/Driver/ToolChains/MipsLinux.cpp b/clang/lib/Driver/ToolChains/MipsLinux.cpp index f61ae471b86d..0d025937cec9 100644 --- a/clang/lib/Driver/ToolChains/MipsLinux.cpp +++ b/clang/lib/Driver/ToolChains/MipsLinux.cpp @@ -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()); diff --git a/clang/lib/Driver/ToolChains/MipsLinux.h b/clang/lib/Driver/ToolChains/MipsLinux.h index a968804f2a6e..f9bf2e1fcd36 100644 --- a/clang/lib/Driver/ToolChains/MipsLinux.h +++ b/clang/lib/Driver/ToolChains/MipsLinux.h @@ -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; diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp index c5469f32ac80..ae164be1b4e8 100644 --- a/clang/lib/Driver/ToolChains/NetBSD.cpp +++ b/clang/lib/Driver/ToolChains/NetBSD.cpp @@ -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"); } diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp index e213c695a9fe..1cfa2a8f43b9 100644 --- a/clang/lib/Driver/ToolChains/OHOS.cpp +++ b/clang/lib/Driver/ToolChains/OHOS.cpp @@ -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()); diff --git a/clang/lib/Driver/ToolChains/OHOS.h b/clang/lib/Driver/ToolChains/OHOS.h index 2a380420922d..0e0543b40606 100644 --- a/clang/lib/Driver/ToolChains/OHOS.h +++ b/clang/lib/Driver/ToolChains/OHOS.h @@ -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"; diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp index f668a11e78f8..a5b1f06449b7 100644 --- a/clang/lib/Driver/ToolChains/OpenBSD.cpp +++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp @@ -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 { diff --git a/clang/lib/Driver/ToolChains/OpenBSD.h b/clang/lib/Driver/ToolChains/OpenBSD.h index b4350e72d5d2..11b873cb3003 100644 --- a/clang/lib/Driver/ToolChains/OpenBSD.h +++ b/clang/lib/Driver/ToolChains/OpenBSD.h @@ -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; diff --git a/clang/lib/Driver/ToolChains/PPCLinux.cpp b/clang/lib/Driver/ToolChains/PPCLinux.cpp index 0ed0f91ad166..575e88c6ab12 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 @@ 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"); +} diff --git a/clang/lib/Driver/ToolChains/PPCLinux.h b/clang/lib/Driver/ToolChains/PPCLinux.h index 63adaff6be9c..910df3d16e6a 100644 --- a/clang/lib/Driver/ToolChains/PPCLinux.h +++ b/clang/lib/Driver/ToolChains/PPCLinux.h @@ -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; diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index fd3232b7c1b0..639497b8fbad 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -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) || 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 000000000000..e69de29bb2d1 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 000000000000..e69de29bb2d1 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 000000000000..e69de29bb2d1 diff --git a/flang-rt/cmake/modules/GetToolchainDirs.cmake b/flang-rt/cmake/modules/GetToolchainDirs.cmake index 8b384180bcc3..fba12502b594 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 000000000000..9a6ee453a22e --- /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"