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 flang-compiler#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.