From 5f1137e5bb64e11626c58aed6f53a44db7d2e6e8 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 23 May 2019 20:35:08 -0500 Subject: [PATCH 1/4] MSVC linking --- lib/Driver/ToolChains/CommonArgs.cpp | 2 +- lib/Driver/ToolChains/CommonArgs.h | 2 + lib/Driver/ToolChains/MSVC.cpp | 79 +++++++++++++++++++++++++++- lib/Driver/ToolChains/MSVC.h | 3 ++ 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp index 535ae12193a5..59beec5b5959 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 6e1ed090611e..815b3faf5f77 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 ae41ee9e22cf..b2dd057ed259 100644 --- a/lib/Driver/ToolChains/MSVC.cpp +++ b/lib/Driver/ToolChains/MSVC.cpp @@ -326,7 +326,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(std::string("-out:") + Output.getFilename())); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && - !C.getDriver().IsCLMode()) + !C.getDriver().IsCLMode() && !C.getDriver().IsFortranMode()) CmdArgs.push_back("-defaultlib:libcmt"); if (!llvm::sys::Process::GetEnv("LIB")) { @@ -426,6 +426,16 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } + // 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(); + } + } + // Add compiler-rt lib in case if it was explicitly // specified as an argument for --rtlib option. if (!Args.hasArg(options::OPT_nostdlib)) { @@ -736,6 +746,73 @@ void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); } + +void MSVCToolChain::AddFortranStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + bool staticFlangLibs = false; + bool useOpenMP = false; + + 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:") + + getDriver().Dir + "/../lib")); + + if (needFortranMain(getDriver(), Args)) { + // flangmain is always static + CmdArgs.push_back("-subsystem:console"); + CmdArgs.push_back("-defaultlib:flangmain"); + } + + if (staticFlangLibs) { + CmdArgs.push_back("-defaultlib:libflang"); + CmdArgs.push_back("-defaultlib:libflangrti"); + CmdArgs.push_back("-defaultlib:libpgmath"); + } else { + CmdArgs.push_back("-defaultlib:flang"); + CmdArgs.push_back("-defaultlib:flangrti"); + CmdArgs.push_back("-defaultlib:pgmath"); + } + if (useOpenMP) { + // openmp is added in ConstructJob + } + else { + if (staticFlangLibs) { + CmdArgs.push_back("-defaultlib:libompstub"); + } else { + CmdArgs.push_back("-defaultlib:ompstub"); + } + } + + // Allways link Fortran executables with Pthreads + // CmdArgs.push_back("-lpthread"); + + // These options are added clang-cl in Clang.cpp for C/C++ + // In clang-cl.exe -MD and -MT control these options, but in + // flang.exe like clang.exe these are different options for + // dependency tracking. Let's assume that if somebody needs + // static flang libs, they need static runtime libs as well. + if (staticFlangLibs) { + CmdArgs.push_back("-defaultlib:libcmt"); + } else { + CmdArgs.push_back("-defaultlib:msvcrt"); + } + CmdArgs.push_back("-defaultlib:oldnames"); + +} + void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const { CudaInstallation.print(OS); } diff --git a/lib/Driver/ToolChains/MSVC.h b/lib/Driver/ToolChains/MSVC.h index 854f88a36fd2..b7c89090e175 100644 --- a/lib/Driver/ToolChains/MSVC.h +++ b/lib/Driver/ToolChains/MSVC.h @@ -109,6 +109,9 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain { void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddFortranStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + bool getWindowsSDKLibraryPath(std::string &path) const; /// \brief Check if Universal CRT should be used if available bool getUniversalCRTLibraryPath(std::string &path) const; From 444418e18ad8d78aa39d57a273239f5125259bc2 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 1 Jun 2019 12:58:47 -0500 Subject: [PATCH 2/4] Pass linker options to flang2 --- lib/Driver/ToolChains/Flang.cpp | 8 +++++ lib/Driver/ToolChains/MSVC.cpp | 59 +++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/lib/Driver/ToolChains/Flang.cpp b/lib/Driver/ToolChains/Flang.cpp index fb44cdcbc1aa..2e571c3ee30b 100644 --- a/lib/Driver/ToolChains/Flang.cpp +++ b/lib/Driver/ToolChains/Flang.cpp @@ -1050,6 +1050,14 @@ if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) { LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); } + bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment(); + if (IsWindowsMSVC && !Args.hasArg(options::OPT_noFlangLibs)) { + getToolChain().AddFortranStdlibLibArgs(Args, LowerCmdArgs); + } + for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { + Arg->claim(); + } + C.addCommand(llvm::make_unique(JA, *this, LowerExec, LowerCmdArgs, Inputs)); } diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp index b2dd057ed259..1b6c91b3e8ab 100644 --- a/lib/Driver/ToolChains/MSVC.cpp +++ b/lib/Driver/ToolChains/MSVC.cpp @@ -426,16 +426,6 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } - // 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(); - } - } - // Add compiler-rt lib in case if it was explicitly // specified as an argument for --rtlib option. if (!Args.hasArg(options::OPT_nostdlib)) { @@ -767,32 +757,48 @@ void MSVCToolChain::AddFortranStdlibLibArgs(const ArgList &Args, useOpenMP = true; } - CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") + + CmdArgs.push_back("-linker"); + CmdArgs.push_back(Args.MakeArgString(std::string("/libpath:") + getDriver().Dir + "/../lib")); if (needFortranMain(getDriver(), Args)) { // flangmain is always static - CmdArgs.push_back("-subsystem:console"); - CmdArgs.push_back("-defaultlib:flangmain"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/subsystem:console"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:flangmain.lib"); } if (staticFlangLibs) { - CmdArgs.push_back("-defaultlib:libflang"); - CmdArgs.push_back("-defaultlib:libflangrti"); - CmdArgs.push_back("-defaultlib:libpgmath"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libflang.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libflangrti.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libpgmath.lib"); } else { - CmdArgs.push_back("-defaultlib:flang"); - CmdArgs.push_back("-defaultlib:flangrti"); - CmdArgs.push_back("-defaultlib:pgmath"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:flang.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:flangrti.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:pgmath.lib"); } if (useOpenMP) { - // openmp is added in ConstructJob + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/nodefaultlib:vcomp.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/nodefaultlib:vcompd.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libomp.lib"); } else { if (staticFlangLibs) { - CmdArgs.push_back("-defaultlib:libompstub"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libompstub.lib"); } else { - CmdArgs.push_back("-defaultlib:ompstub"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:ompstub.lib"); } } @@ -805,11 +811,14 @@ void MSVCToolChain::AddFortranStdlibLibArgs(const ArgList &Args, // dependency tracking. Let's assume that if somebody needs // static flang libs, they need static runtime libs as well. if (staticFlangLibs) { - CmdArgs.push_back("-defaultlib:libcmt"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libcmt.lib"); } else { - CmdArgs.push_back("-defaultlib:msvcrt"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:msvcrt.lib"); } - CmdArgs.push_back("-defaultlib:oldnames"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:oldnames.lib"); } From 3cdd3d06c6dfba1a6681d828aa209b45ee667d84 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 1 Jun 2019 19:30:41 -0500 Subject: [PATCH 3/4] No need of oldnames.lib --- lib/Driver/ToolChains/MSVC.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp index 1b6c91b3e8ab..03edca9cc7c6 100644 --- a/lib/Driver/ToolChains/MSVC.cpp +++ b/lib/Driver/ToolChains/MSVC.cpp @@ -817,9 +817,6 @@ void MSVCToolChain::AddFortranStdlibLibArgs(const ArgList &Args, CmdArgs.push_back("-linker"); CmdArgs.push_back("/defaultlib:msvcrt.lib"); } - CmdArgs.push_back("-linker"); - CmdArgs.push_back("/defaultlib:oldnames.lib"); - } void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const { From e0c266de0b41884bbe628b97dcc1137985203a6f Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 2 Jun 2019 05:49:30 -0500 Subject: [PATCH 4/4] Don't add libpath to object file --- lib/Driver/ToolChains/Flang.cpp | 6 +++--- lib/Driver/ToolChains/MSVC.cpp | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/Driver/ToolChains/Flang.cpp b/lib/Driver/ToolChains/Flang.cpp index 2e571c3ee30b..968ec8f5f49f 100644 --- a/lib/Driver/ToolChains/Flang.cpp +++ b/lib/Driver/ToolChains/Flang.cpp @@ -1053,9 +1053,9 @@ if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) { bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment(); if (IsWindowsMSVC && !Args.hasArg(options::OPT_noFlangLibs)) { getToolChain().AddFortranStdlibLibArgs(Args, LowerCmdArgs); - } - for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { - Arg->claim(); + for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { + Arg->claim(); + } } C.addCommand(llvm::make_unique(JA, *this, LowerExec, LowerCmdArgs, Inputs)); diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp index 03edca9cc7c6..d1cde6496567 100644 --- a/lib/Driver/ToolChains/MSVC.cpp +++ b/lib/Driver/ToolChains/MSVC.cpp @@ -426,6 +426,11 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } + if (C.getDriver().IsFortranMode()) { + CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") + + TC.getDriver().Dir + "/../lib")); + } + // Add compiler-rt lib in case if it was explicitly // specified as an argument for --rtlib option. if (!Args.hasArg(options::OPT_nostdlib)) { @@ -757,10 +762,6 @@ void MSVCToolChain::AddFortranStdlibLibArgs(const ArgList &Args, useOpenMP = true; } - CmdArgs.push_back("-linker"); - CmdArgs.push_back(Args.MakeArgString(std::string("/libpath:") + - getDriver().Dir + "/../lib")); - if (needFortranMain(getDriver(), Args)) { // flangmain is always static CmdArgs.push_back("-linker");