Skip to content

Commit

Permalink
Pass Flang libraries to MSVC linker correctly
Browse files Browse the repository at this point in the history
The orignal PR was created by Isuruf #65
  • Loading branch information
isuruf authored and bryanpkc committed Sep 19, 2024
1 parent 2f45f73 commit dd1efa0
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 1 deletion.
8 changes: 8 additions & 0 deletions clang/lib/Driver/ToolChains/ClassicFlang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,14 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA,
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(std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileUTF8(), LowerExec, LowerCmdArgs, Inputs));
}

2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ static bool shouldIgnoreUnsupportedTargetFeature(const Arg &TargetFeatureArg,

#ifdef ENABLE_CLASSIC_FLANG
/// \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)));
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ namespace tools {

#ifdef ENABLE_CLASSIC_FLANG
bool needFortranLibs(const Driver &D, const llvm::opt::ArgList &Args);

bool needFortranMain(const Driver &D, const llvm::opt::ArgList &Args);
#endif

void addPathIfExists(const Driver &D, const Twine &Path,
Expand Down
75 changes: 75 additions & 0 deletions clang/lib/Driver/ToolChains/MSVC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,13 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
}

#ifdef ENABLE_CLASSIC_FLANG
if (C.getDriver().IsFlangMode()) {
CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
TC.getDriver().Dir + "/../lib"));
}
#endif

// Add compiler-rt lib in case if it was explicitly
// specified as an argument for --rtlib option.
if (!Args.hasArg(options::OPT_nostdlib)) {
Expand Down Expand Up @@ -513,6 +520,74 @@ void MSVCToolChain::AddHIPRuntimeLibArgs(const ArgList &Args,
"amdhip64.lib"});
}

#ifdef ENABLE_CLASSIC_FLANG
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;
}

if (needFortranMain(getDriver(), Args)) {
// flangmain is always static
CmdArgs.push_back("-linker");
CmdArgs.push_back("/subsystem:console");
CmdArgs.push_back("-linker");
CmdArgs.push_back("/defaultlib:flangmain.lib");
}

if (staticFlangLibs) {
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("-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) {
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");
}

// 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 don't need static C runtime libs.
// FIXME: Use LLVM_USE_CRT_<CMAKE_BUILD_TYPE> variable
// to use libcmt.lib or msvcrt.lib
CmdArgs.push_back("-linker");
CmdArgs.push_back("/defaultlib:libcmt.lib");
}
#endif

void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
CudaInstallation->print(OS);
RocmInstallation->print(OS);
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Driver/ToolChains/MSVC.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;

#ifdef ENABLE_CLASSIC_FLANG
void AddFortranStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
#endif

bool getWindowsSDKLibraryPath(
const llvm::opt::ArgList &Args, std::string &path) const;
bool getUniversalCRTLibraryPath(const llvm::opt::ArgList &Args,
Expand Down

0 comments on commit dd1efa0

Please sign in to comment.