Skip to content

Commit dd1efa0

Browse files
isurufbryanpkc
authored andcommitted
Pass Flang libraries to MSVC linker correctly
The orignal PR was created by Isuruf #65
1 parent 2f45f73 commit dd1efa0

File tree

5 files changed

+91
-1
lines changed

5 files changed

+91
-1
lines changed

clang/lib/Driver/ToolChains/ClassicFlang.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,14 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA,
12041204
LowerCmdArgs.push_back(Args.MakeArgString(OutFile));
12051205
}
12061206

1207+
bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
1208+
if (IsWindowsMSVC && !Args.hasArg(options::OPT_noFlangLibs)) {
1209+
getToolChain().AddFortranStdlibLibArgs(Args, LowerCmdArgs);
1210+
for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) {
1211+
Arg->claim();
1212+
}
1213+
}
1214+
12071215
C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileUTF8(), LowerExec, LowerCmdArgs, Inputs));
12081216
}
12091217

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ static bool shouldIgnoreUnsupportedTargetFeature(const Arg &TargetFeatureArg,
339339

340340
#ifdef ENABLE_CLASSIC_FLANG
341341
/// \brief Determine if Fortran "main" object is needed
342-
static bool needFortranMain(const Driver &D, const ArgList &Args) {
342+
bool tools::needFortranMain(const Driver &D, const ArgList &Args) {
343343
return (needFortranLibs(D, Args)
344344
&& (!Args.hasArg(options::OPT_Mnomain) ||
345345
!Args.hasArg(options::OPT_no_fortran_main)));

clang/lib/Driver/ToolChains/CommonArgs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace tools {
2626

2727
#ifdef ENABLE_CLASSIC_FLANG
2828
bool needFortranLibs(const Driver &D, const llvm::opt::ArgList &Args);
29+
30+
bool needFortranMain(const Driver &D, const llvm::opt::ArgList &Args);
2931
#endif
3032

3133
void addPathIfExists(const Driver &D, const Twine &Path,

clang/lib/Driver/ToolChains/MSVC.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,13 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
268268
}
269269
}
270270

271+
#ifdef ENABLE_CLASSIC_FLANG
272+
if (C.getDriver().IsFlangMode()) {
273+
CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
274+
TC.getDriver().Dir + "/../lib"));
275+
}
276+
#endif
277+
271278
// Add compiler-rt lib in case if it was explicitly
272279
// specified as an argument for --rtlib option.
273280
if (!Args.hasArg(options::OPT_nostdlib)) {
@@ -513,6 +520,74 @@ void MSVCToolChain::AddHIPRuntimeLibArgs(const ArgList &Args,
513520
"amdhip64.lib"});
514521
}
515522

523+
#ifdef ENABLE_CLASSIC_FLANG
524+
void MSVCToolChain::AddFortranStdlibLibArgs(const ArgList &Args,
525+
ArgStringList &CmdArgs) const {
526+
bool staticFlangLibs = false;
527+
bool useOpenMP = false;
528+
529+
if (Args.hasArg(options::OPT_staticFlangLibs)) {
530+
for (auto *A: Args.filtered(options::OPT_staticFlangLibs)) {
531+
A->claim();
532+
staticFlangLibs = true;
533+
}
534+
}
535+
536+
Arg *A = Args.getLastArg(options::OPT_mp, options::OPT_nomp,
537+
options::OPT_fopenmp, options::OPT_fno_openmp);
538+
if (A &&
539+
(A->getOption().matches(options::OPT_mp) ||
540+
A->getOption().matches(options::OPT_fopenmp))) {
541+
useOpenMP = true;
542+
}
543+
544+
if (needFortranMain(getDriver(), Args)) {
545+
// flangmain is always static
546+
CmdArgs.push_back("-linker");
547+
CmdArgs.push_back("/subsystem:console");
548+
CmdArgs.push_back("-linker");
549+
CmdArgs.push_back("/defaultlib:flangmain.lib");
550+
}
551+
552+
if (staticFlangLibs) {
553+
CmdArgs.push_back("-linker");
554+
CmdArgs.push_back("/defaultlib:libflang.lib");
555+
CmdArgs.push_back("-linker");
556+
CmdArgs.push_back("/defaultlib:libflangrti.lib");
557+
CmdArgs.push_back("-linker");
558+
CmdArgs.push_back("/defaultlib:libpgmath.lib");
559+
} else {
560+
CmdArgs.push_back("-linker");
561+
CmdArgs.push_back("/defaultlib:flang.lib");
562+
CmdArgs.push_back("-linker");
563+
CmdArgs.push_back("/defaultlib:flangrti.lib");
564+
CmdArgs.push_back("-linker");
565+
CmdArgs.push_back("/defaultlib:pgmath.lib");
566+
}
567+
if (useOpenMP) {
568+
CmdArgs.push_back("-linker");
569+
CmdArgs.push_back("/nodefaultlib:vcomp.lib");
570+
CmdArgs.push_back("-linker");
571+
CmdArgs.push_back("/nodefaultlib:vcompd.lib");
572+
CmdArgs.push_back("-linker");
573+
CmdArgs.push_back("/defaultlib:libomp.lib");
574+
}
575+
576+
// Allways link Fortran executables with Pthreads
577+
// CmdArgs.push_back("-lpthread");
578+
579+
// These options are added clang-cl in Clang.cpp for C/C++
580+
// In clang-cl.exe -MD and -MT control these options, but in
581+
// flang.exe like clang.exe these are different options for
582+
// dependency tracking. Let's assume that if somebody needs
583+
// static flang libs, they don't need static C runtime libs.
584+
// FIXME: Use LLVM_USE_CRT_<CMAKE_BUILD_TYPE> variable
585+
// to use libcmt.lib or msvcrt.lib
586+
CmdArgs.push_back("-linker");
587+
CmdArgs.push_back("/defaultlib:libcmt.lib");
588+
}
589+
#endif
590+
516591
void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
517592
CudaInstallation->print(OS);
518593
RocmInstallation->print(OS);

clang/lib/Driver/ToolChains/MSVC.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
100100
void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args,
101101
llvm::opt::ArgStringList &CmdArgs) const override;
102102

103+
#ifdef ENABLE_CLASSIC_FLANG
104+
void AddFortranStdlibLibArgs(const llvm::opt::ArgList &Args,
105+
llvm::opt::ArgStringList &CmdArgs) const override;
106+
#endif
107+
103108
bool getWindowsSDKLibraryPath(
104109
const llvm::opt::ArgList &Args, std::string &path) const;
105110
bool getUniversalCRTLibraryPath(const llvm::opt::ArgList &Args,

0 commit comments

Comments
 (0)