[flang] [clang] [flang][windows] Add option to link against specific MSVC CRT (PR #70833)

Brad King via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 1 06:13:07 PDT 2023


================
@@ -976,12 +976,46 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
   return true;
 }
 
-void tools::addFortranRuntimeLibs(const ToolChain &TC,
+void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
                                   llvm::opt::ArgStringList &CmdArgs) {
   if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
-    CmdArgs.push_back("Fortran_main.lib");
-    CmdArgs.push_back("FortranRuntime.lib");
-    CmdArgs.push_back("FortranDecimal.lib");
+    CmdArgs.push_back(Args.MakeArgString(
+        "/DEFAULTLIB:" + TC.getCompilerRTBasename(Args, "builtins")));
+    unsigned RTOptionID = options::OPT__SLASH_MT;
+    if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
+      RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue())
+                       .Case("static", options::OPT__SLASH_MT)
+                       .Case("static_dbg", options::OPT__SLASH_MTd)
+                       .Case("dll", options::OPT__SLASH_MD)
+                       .Case("dll_dbg", options::OPT__SLASH_MDd)
+                       .Default(options::OPT__SLASH_MT);
+    }
+    switch (RTOptionID) {
+    case options::OPT__SLASH_MT:
+      CmdArgs.push_back("/DEFAULTLIB:libcmt");
+      CmdArgs.push_back("Fortran_main.static.lib");
+      CmdArgs.push_back("FortranRuntime.static.lib");
+      CmdArgs.push_back("FortranDecimal.static.lib");
+      break;
+    case options::OPT__SLASH_MTd:
+      CmdArgs.push_back("/DEFAULTLIB:libcmtd");
+      CmdArgs.push_back("Fortran_main.static_debug.lib");
+      CmdArgs.push_back("FortranRuntime.static_debug.lib");
+      CmdArgs.push_back("FortranDecimal.static_debug.lib");
+      break;
+    case options::OPT__SLASH_MD:
+      CmdArgs.push_back("/DEFAULTLIB:msvcrt");
+      CmdArgs.push_back("Fortran_main.dynamic.lib");
+      CmdArgs.push_back("FortranRuntime.dynamic.lib");
+      CmdArgs.push_back("FortranDecimal.dynamic.lib");
+      break;
----------------
bradking wrote:

>From https://github.com/llvm/llvm-project/pull/70833#issuecomment-1787651022:

> I think you're probably right in the linked issue that it'd be better to add defaultlib directives to the object files, but that appears to be quite difficult as we'd need to track the attributes all the way through our MLIR lowering, so as a (hopefully temporary) shortcut I have just passed the libraries on the link line.

This temporary approach will actually make things harder for CMake to support `flang-new`.  In order to support mixed-language (e.g., Fortran and C++) binaries we detect the implicit link directories and libraries that each compiler driver passes to the linker when used to drive linking.  Then if we have to link using a different language's tooling, we can add them explicitly.  We don't typically do that for the MSVC ABI though because the set of runtime libraries varies with the CRT choice and the defaultlib directives in object files handle it automatically anyway.  Currently CMake is working around the lack of defaultlib directives for `flang-new` by using the implicit-lib-detection approach.  Once the implicitly linked runtime libraries vary with the CRT, we would need a lot of dedicated non-trivial infrastructure to handle all the `MSVC_RUNTIME_LIBRARY` variants, and I'm not sure it's possible in all cases.

Can you instead add these four CRT-specific libraries as defaultlib directives in all object files, and add the more detailed conditions to remove unnecessary libraries later?  Since they are all static `.lib` files, unused directives may not hurt.



https://github.com/llvm/llvm-project/pull/70833


More information about the cfe-commits mailing list