From ee1e5b9d368525de4bcdebc8cb470bdc4e70aec4 Mon Sep 17 00:00:00 2001 From: Albert Ziegenhagel Date: Thu, 26 Oct 2017 17:09:30 +0200 Subject: [PATCH] Add support to set linker flags for flang on windows --- lib/Driver/ToolChains/CommonArgs.cpp | 2 +- lib/Driver/ToolChains/CommonArgs.h | 2 + lib/Driver/ToolChains/MSVC.cpp | 56 ++++++++++++++++++++++++++++ lib/Driver/ToolChains/MSVC.h | 3 ++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp index fe22b76556..969656b364 100644 --- a/lib/Driver/ToolChains/CommonArgs.cpp +++ b/lib/Driver/ToolChains/CommonArgs.cpp @@ -67,7 +67,7 @@ bool tools::needFortranLibs(const Driver &D, const ArgList &Args) { } /// \brief Determine if Fortran "main" object is needed -static bool needFortranMain(const Driver &D, const ArgList &Args) { +bool tools::needFortranMain(const Driver &D, const ArgList &Args) { return (needFortranLibs(D, Args) && (!Args.hasArg(options::OPT_Mnomain) || !Args.hasArg(options::OPT_no_fortran_main))); diff --git a/lib/Driver/ToolChains/CommonArgs.h b/lib/Driver/ToolChains/CommonArgs.h index 70ac75b2de..8bfdf162b9 100644 --- a/lib/Driver/ToolChains/CommonArgs.h +++ b/lib/Driver/ToolChains/CommonArgs.h @@ -22,6 +22,8 @@ namespace tools { bool needFortranLibs(const Driver &D, const llvm::opt::ArgList &Args); +bool needFortranMain(const Driver &D, const llvm::opt::ArgList &Args); + void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths); diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp index 7978a6941c..e71af6a1e7 100644 --- a/lib/Driver/ToolChains/MSVC.cpp +++ b/lib/Driver/ToolChains/MSVC.cpp @@ -372,6 +372,16 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName)); } + // Add Fortran runtime libraries + if (needFortranLibs(TC.getDriver(), Args)) { + TC.AddFortranStdlibLibArgs(Args, CmdArgs); + } else { + // Claim "no Flang libraries" arguments if any + for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { + Arg->claim(); + } + } + if (TC.getSanitizerArgs().needsAsanRt()) { CmdArgs.push_back(Args.MakeArgString("-debug")); CmdArgs.push_back(Args.MakeArgString("-incremental:no")); @@ -1255,6 +1265,52 @@ void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, // FIXME: There should probably be logic here to find libc++ on Windows. } +void MSVCToolChain::AddFortranStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + bool staticFlangLibs = false; + bool useOpenMP = false; + + const auto &D = getDriver(); + + if (Args.hasArg(options::OPT_staticFlangLibs)) { + for (auto *A: Args.filtered(options::OPT_staticFlangLibs)) { + A->claim(); + staticFlangLibs = true; + } + } + + Arg *A = Args.getLastArg(options::OPT_mp, options::OPT_nomp, + options::OPT_fopenmp, options::OPT_fno_openmp); + if (A && + (A->getOption().matches(options::OPT_mp) || + A->getOption().matches(options::OPT_fopenmp))) { + useOpenMP = true; + } + + CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") + + D.Dir + "/../lib")); + + if (needFortranMain(D, Args)) { + CmdArgs.push_back("-defaultlib:flangmain"); + CmdArgs.push_back("-subsystem:console"); + } + + if (staticFlangLibs) { + CmdArgs.push_back("-defaultlib:libflang"); + CmdArgs.push_back("-defaultlib:libflangrti"); + if (!useOpenMP) { + CmdArgs.push_back("-defaultlib:libompstub"); + } + } + else { + CmdArgs.push_back("-defaultlib:flang"); + CmdArgs.push_back("-defaultlib:flangrti"); + if (!useOpenMP) { + CmdArgs.push_back("-defaultlib:ompstub"); + } + } +} + VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D, const ArgList &Args) const { bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment(); diff --git a/lib/Driver/ToolChains/MSVC.h b/lib/Driver/ToolChains/MSVC.h index 854f88a36f..440542743a 100644 --- a/lib/Driver/ToolChains/MSVC.h +++ b/lib/Driver/ToolChains/MSVC.h @@ -106,6 +106,9 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain { const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddFortranStdlibLibArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override;