Index: clang/lib/Driver/ToolChains/CommonArgs.h =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.h +++ clang/lib/Driver/ToolChains/CommonArgs.h @@ -121,7 +121,8 @@ bool IsOffloadingHost = false, bool GompNeedsRT = false); /// Adds Fortran runtime libraries to \p CmdArgs. -void addFortranRuntimeLibs(llvm::opt::ArgStringList &CmdArgs); +void addFortranRuntimeLibs(const ToolChain &TC, + llvm::opt::ArgStringList &CmdArgs); /// Adds the path for the Fortran runtime libraries to \p CmdArgs. void addFortranRuntimeLibraryPath(const ToolChain &TC, Index: clang/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.cpp +++ clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -751,10 +751,17 @@ return true; } -void tools::addFortranRuntimeLibs(llvm::opt::ArgStringList &CmdArgs) { - CmdArgs.push_back("-lFortran_main"); - CmdArgs.push_back("-lFortranRuntime"); - CmdArgs.push_back("-lFortranDecimal"); +void tools::addFortranRuntimeLibs(const ToolChain &TC, + llvm::opt::ArgStringList &CmdArgs) { + if (TC.getTriple().isKnownWindowsMSVCEnvironment()) { + CmdArgs.push_back("Fortran_main.lib"); + CmdArgs.push_back("FortranRuntime.lib"); + CmdArgs.push_back("FortranDecimal.lib"); + } else { + CmdArgs.push_back("-lFortran_main"); + CmdArgs.push_back("-lFortranRuntime"); + CmdArgs.push_back("-lFortranDecimal"); + } } void tools::addFortranRuntimeLibraryPath(const ToolChain &TC, @@ -767,7 +774,10 @@ SmallString<256> DefaultLibPath = llvm::sys::path::parent_path(TC.getDriver().Dir); llvm::sys::path::append(DefaultLibPath, "lib"); - CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath)); + if (TC.getTriple().isKnownWindowsMSVCEnvironment()) + CmdArgs.push_back(Args.MakeArgString("-libpath:" + DefaultLibPath)); + else + CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath)); } static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args, Index: clang/lib/Driver/ToolChains/Darwin.cpp =================================================================== --- clang/lib/Driver/ToolChains/Darwin.cpp +++ clang/lib/Driver/ToolChains/Darwin.cpp @@ -644,7 +644,7 @@ if (getToolChain().getDriver().IsFlangMode() && Args.hasArg(options::OPT_flang_experimental_exec)) { addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs); - addFortranRuntimeLibs(CmdArgs); + addFortranRuntimeLibs(getToolChain(), CmdArgs); } if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) Index: clang/lib/Driver/ToolChains/Gnu.cpp =================================================================== --- clang/lib/Driver/ToolChains/Gnu.cpp +++ clang/lib/Driver/ToolChains/Gnu.cpp @@ -599,7 +599,7 @@ // TODO: Make this work unconditionally once Flang is mature enough. if (D.IsFlangMode() && Args.hasArg(options::OPT_flang_experimental_exec)) { addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs); - addFortranRuntimeLibs(CmdArgs); + addFortranRuntimeLibs(ToolChain, CmdArgs); CmdArgs.push_back("-lm"); } Index: clang/lib/Driver/ToolChains/MSVC.cpp =================================================================== --- clang/lib/Driver/ToolChains/MSVC.cpp +++ clang/lib/Driver/ToolChains/MSVC.cpp @@ -81,7 +81,7 @@ Args.MakeArgString(std::string("-out:") + Output.getFilename())); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && - !C.getDriver().IsCLMode()) { + !C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) { CmdArgs.push_back("-defaultlib:libcmt"); CmdArgs.push_back("-defaultlib:oldnames"); } @@ -130,6 +130,16 @@ Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath)); } + if (C.getDriver().IsFlangMode()) { + tools::addFortranRuntimeLibraryPath(TC, Args, CmdArgs); + tools::addFortranRuntimeLibs(TC, CmdArgs); + + // Inform the MSVC linker that we're generating a console application, i.e. + // one with `main` as the "user-defined" entry point. The `main` function is + // defined in flang's runtime libraries. + CmdArgs.push_back("/subsystem:console"); + } + // Add the compiler-rt library directories to libpath if they exist to help // the linker find the various sanitizer, builtin, and profiling runtimes. for (const auto &LibPath : TC.getLibraryPaths()) { Index: clang/lib/Driver/ToolChains/MinGW.cpp =================================================================== --- clang/lib/Driver/ToolChains/MinGW.cpp +++ clang/lib/Driver/ToolChains/MinGW.cpp @@ -218,6 +218,11 @@ AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); + if (C.getDriver().IsFlangMode()) { + tools::addFortranRuntimeLibraryPath(TC, Args, CmdArgs); + tools::addFortranRuntimeLibs(TC, CmdArgs); + } + // TODO: Add profile stuff here if (TC.ShouldLinkCXXStdlib(Args)) { Index: flang/test/Driver/linker-flags-windows.f90 =================================================================== --- /dev/null +++ flang/test/Driver/linker-flags-windows.f90 @@ -0,0 +1,25 @@ +! Verify that the Fortran runtime libraries are present in the linker +! invocation. These libraries are added on top of other standard runtime +! libraries that the Clang driver will include. + +! NOTE: The additional linker flags tested here are currently specified in +! clang/lib/Driver/Toolchains/MSVC.cpp. +! REQUIRES: windows-msvc + +! RUN: %flang -### %S/Inputs/hello.f90 2>&1 | FileCheck %s + +! Compiler invocation to generate the object file +! CHECK-LABEL: {{.*}} "-emit-obj" +! CHECK-SAME: "-o" "[[object_file:.*]]" {{.*}}Inputs/hello.f90 + +! Linker invocation to generate the executable +! NOTE: This check should also match if the default linker is lld-link.exe +! CHECK-LABEL: link.exe +! CHECK-NOT: libcmt +! CHECK-NOT: oldnames +! CHECK-SAME: Fortran_main.lib +! CHECK-SAME: FortranRuntime.lib +! CHECK-SAME: FortranDecimal.lib +! CHECK-SAME: /subsystem:console +! CHECK-SAME: "[[object_file]]" + Index: flang/test/Driver/linker-flags.f90 =================================================================== --- flang/test/Driver/linker-flags.f90 +++ flang/test/Driver/linker-flags.f90 @@ -5,8 +5,8 @@ ! NOTE: The additional linker flags tested here are currently only specified for ! GNU and Darwin. The following line will make sure that this test is skipped on ! Windows. If you are running this test on a yet another platform and it is -! failing for you, please either update the following or (preferably) update the -! linker invocation accordingly. +! failing for you, please either update the following or (preferably) +! create a similar test for your platform. ! UNSUPPORTED: system-windows !------------