[clang] [clang][MinGW] Implement -mcrtdll option to switch crt choice (PR #149469)
Keno Fischer via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 18 00:56:48 PDT 2025
https://github.com/Keno created https://github.com/llvm/llvm-project/pull/149469
This implements the mingw `-mcrtdll` option recently added to gcc.
This option is useful for having the compiler be in charge of crt
version selection while only shipping a single copy of mingw for a
multi-ABI toolchain. That said, there are various ABI dependent compiler
libraries (e.g. libstdc++), so a certain degree of ABI awareness is
nevertheless required in order to use this option correctly.
See also #149434 (which this branch includes, since it touches the same code).
>From e3dd50c14f79dca0d28e482f707849c92ec0df76 Mon Sep 17 00:00:00 2001
From: Keno Fischer <keno at juliahub.com>
Date: Fri, 18 Jul 2025 01:02:00 +0000
Subject: [PATCH 1/2] [Driver][MinGW] Always put libc argument last, even if
non-standard
I was attempting to build openblas with clang in msys2's `ucrt64`
environment (I'm aware of the `clang64` environment, but I wanted
libstdc++). The openblas link failed with the following:
```
clang -march=native -mtune=native -m64 -O2 -fno-asynchronous-unwind-tables -O2 -DSMALL_MATRIX_OPT -DMS_ABI -DMAX_STACK_ALLOC=2048 -Wall -m64 -DF_INTERFACE_GFORT -DDYNAMIC_ARCH -DSMP_SERVER -DNO_WARMUP -DMAX_CPU_NUMBER=512 -DMAX_PARALLEL_NUMBER=1 -DBUILD_SINGLE=1 -DBUILD_DOUBLE=1 -DBUILD_COMPLEX=1 -DBUILD_COMPLEX16=1 -DVERSION=\"0.3.29\" -UASMNAME -UASMFNAME -UNAME -UCNAME -UCHAR_NAME -UCHAR_CNAME -DASMNAME= -DASMFNAME=_ -DNAME=_ -DCNAME= -DCHAR_NAME=\"_\" -DCHAR_CNAME=\"\" -DNO_AFFINITY -I.. libopenblas64_.def dllinit.obj \
-shared -o ../libopenblas64_.dll -Wl,--out-implib,../libopenblas64_.dll.a \
-Wl,--whole-archive ../libopenblas64_p-r0.3.29.a -Wl,--no-whole-archive -LC:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/15.1.0 -LC:/msys64/ucrt64/bin/../lib/gcc -LC:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/15.1.0/../../../../x86_64-w64-mingw32/lib/../lib -LC:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/15.1.0/../../../../lib -LC:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/15.1.0/../../../../x86_64-w64-mingw32/lib -LC:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/15.1.0/../../.. -lgfortran -lmingwex -lmsvcrt -lquadmath -lm -lpthread -lmingwex -lmsvcrt -defaultlib:advapi32 -lgfortran -defaultlib:advapi32 -lgfortran
C:/msys64/ucrt64/bin/ld: C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/15.1.0/../../../../lib/libmingw32.a(lib64_libmingw32_a-pseudo-reloc.o): in function `__report_error':
D:/W/B/src/mingw-w64/mingw-w64-crt/crt/pseudo-reloc.c:157:(.text+0x59): undefined reference to `abort'
C:/msys64/ucrt64/bin/ld: C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/15.1.0/../../../../lib/libmingw32.a(lib64_libmingw32_a-tlsthrd.o): in function `___w64_mingwthr_add_key_dtor':
D:/W/B/src/mingw-w64/mingw-w64-crt/crt/tlsthrd.c:48:(.text+0xa5): undefined reference to `calloc'
C:/msys64/ucrt64/bin/ld: C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/15.1.0/../../../../lib/libmingw32.a(lib64_libmingw32_a-pesect.o): in function `_FindPESectionByName':
D:/W/B/src/mingw-w64/mingw-w64-crt/crt/pesect.c:79:(.text+0xfd): undefined reference to `strncmp'
```
These symbols come from the `-lmingw32` dep that the driver added
and are ordinarily found in `-lmsvcrt`, which got skipped here,
because openblas passed `-lmsvcrt` explicitly. Since we always
add these libraries at the end here, I think that clang is "at fault"
(as opposed to a user or packaging mistake) and should have added some crt here.
To preserve the intent of letting the user override which crt is chosen,
duplicate the (first) user chosen crt `-l` into this position,
although we should perhaps consider an explicit `-mcrtdll` like gcc has as well.
---
clang/lib/Driver/ToolChains/MinGW.cpp | 11 +++++++++--
clang/test/Driver/mingw-msvcrt.c | 8 ++++----
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index 7d093d20b3dd9..58c59aa7f2237 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -85,11 +85,18 @@ void tools::MinGW::Linker::AddLibGCC(const ArgList &Args,
CmdArgs.push_back("-lmoldname");
CmdArgs.push_back("-lmingwex");
- for (auto Lib : Args.getAllArgValues(options::OPT_l))
+ for (auto Lib : Args.getAllArgValues(options::OPT_l)) {
if (StringRef(Lib).starts_with("msvcr") ||
StringRef(Lib).starts_with("ucrt") ||
- StringRef(Lib).starts_with("crtdll"))
+ StringRef(Lib).starts_with("crtdll")) {
+ Lib = (llvm::Twine("-l") + Lib).str();
+ // Respect the user's chosen crt variant, but still provide it
+ // again as the last linker argument, because some of the libraries
+ // we added above may depend on it.
+ CmdArgs.push_back(Args.MakeArgStringRef(Lib));
return;
+ }
+ }
CmdArgs.push_back("-lmsvcrt");
}
diff --git a/clang/test/Driver/mingw-msvcrt.c b/clang/test/Driver/mingw-msvcrt.c
index 340ce1f57b0f8..e1648630476a0 100644
--- a/clang/test/Driver/mingw-msvcrt.c
+++ b/clang/test/Driver/mingw-msvcrt.c
@@ -7,10 +7,10 @@
// CHECK_DEFAULT: "-lmingwex" "-lmsvcrt" "-ladvapi32"
// CHECK_DEFAULT-SAME: "-lmsvcrt" "-lkernel32" "{{.*}}crtend.o"
// CHECK_MSVCR120: "-lmsvcr120"
-// CHECK_MSVCR120-SAME: "-lmingwex" "-ladvapi32"
+// CHECK_MSVCR120-SAME: "-lmingwex" "-lmsvcr120" "-ladvapi32"
// CHECK_UCRTBASE: "-lucrtbase"
-// CHECK_UCRTBASE-SAME: "-lmingwex" "-ladvapi32"
+// CHECK_UCRTBASE-SAME: "-lmingwex" "-lucrtbase" "-ladvapi32"
// CHECK_UCRT: "-lucrt"
-// CHECK_UCRT-SAME: "-lmingwex" "-ladvapi32"
+// CHECK_UCRT-SAME: "-lmingwex" "-lucrt" "-ladvapi32"
// CHECK_CRTDLL: "-lcrtdll"
-// CHECK_CRTDLL-SAME: "-lmingwex" "-ladvapi32"
+// CHECK_CRTDLL-SAME: "-lmingwex" "-lcrtdll" "-ladvapi32"
>From 544048cfbd4d8fd2fc293aab119f190df40671aa Mon Sep 17 00:00:00 2001
From: Keno Fischer <keno at juliahub.com>
Date: Fri, 18 Jul 2025 07:29:15 +0000
Subject: [PATCH 2/2] [clang][MinGW] Implement -mcrtdll option to swtich crt
choice
This implements the mingw `-mcrtdll` option recently added to gcc.
This option is useful for having the compiler be in charge of crt
version selection while only shipping a single copy of mingw for a
multi-ABI toolchain. That said, there are various ABI dependent compiler
libraries (e.g. libstdc++), so a certain degree of ABI awareness is
nevertheless required in order to use this option correctly.
See also #149434
---
.../clang/Basic/DiagnosticFrontendKinds.td | 3 ++
clang/include/clang/Basic/LangOptions.def | 3 ++
clang/include/clang/Basic/LangOptions.h | 17 +++++++
clang/include/clang/Driver/Options.td | 6 +++
clang/lib/Basic/Targets/OSTargets.cpp | 48 ++++++++++++++++++-
clang/lib/Driver/ToolChains/Clang.cpp | 1 +
clang/lib/Driver/ToolChains/MinGW.cpp | 29 ++++++-----
clang/lib/Frontend/CompilerInvocation.cpp | 38 +++++++++++++++
clang/test/Driver/mingw-mcrtdll.c | 30 ++++++++++++
9 files changed, 162 insertions(+), 13 deletions(-)
create mode 100644 clang/test/Driver/mingw-mcrtdll.c
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 8a8db27490f06..3de97a0ec3955 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -393,6 +393,9 @@ def warn_hlsl_langstd_minimal :
"recommend using %1 instead">,
InGroup<HLSLDXCCompat>;
+def err_unknown_crtdll : Error<"unknown Windows/MinGW C runtime library '%0'">,
+ DefaultFatal;
+
// ClangIR frontend errors
def err_cir_to_cir_transform_failed : Error<
"CIR-to-CIR transformation failed">, DefaultFatal;
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index e43238ba683f2..46f03982a041b 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -493,6 +493,9 @@ LANGOPT(BoundsSafety, 1, 0, NotCompatible, "Bounds safety extension for C")
LANGOPT(PreserveVec3Type, 1, 0, NotCompatible, "Preserve 3-component vector type")
+ENUM_LANGOPT(MinGWCRTDll, WindowsCRTDLLVersion, 4, WindowsCRTDLLVersion::CRTDLL_Default, NotCompatible,
+ "MinGW specific. Controls the __MSVCRT_VERSION and related preprocessor defines.")
+
#undef LANGOPT
#undef ENUM_LANGOPT
#undef VALUE_LANGOPT
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 4c642c9e10c91..a0160017b6813 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -164,6 +164,23 @@ class LangOptionsBase {
MSVC2022_9 = 1939,
};
+ enum WindowsCRTDLLVersion {
+ CRTDLL_Default,
+ CRTDLL,
+ MSVCRT10,
+ MSVCRT20,
+ MSVCRT40,
+ MSVCRTD,
+ MSVCR70,
+ MSVCR71,
+ MSVCR80,
+ MSVCR90,
+ MSVCR100,
+ MSVCR110,
+ MSVCR120,
+ UCRT
+ };
+
enum SYCLMajorVersion {
SYCL_None,
SYCL_2017,
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d0b54a446309b..6ad978c525812 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1625,6 +1625,12 @@ defm auto_import : BoolFOption<"auto-import",
PosFlag<SetTrue, [], [], "MinGW specific. Enable code generation support for "
"automatic dllimport, and enable support for it in the linker. "
"Enabled by default.">>;
+def mcrtdll_EQ : Joined<["-"], "mcrtdll=">,
+ Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"MinGW specific. Changes preprocessor flags and "
+ "linker options to use the"
+ "specified C runtime library.">;
} // let Flags = [TargetSpecific]
// In the future this option will be supported by other offloading
diff --git a/clang/lib/Basic/Targets/OSTargets.cpp b/clang/lib/Basic/Targets/OSTargets.cpp
index e744e84a5b079..8e48228d1220f 100644
--- a/clang/lib/Basic/Targets/OSTargets.cpp
+++ b/clang/lib/Basic/Targets/OSTargets.cpp
@@ -141,8 +141,54 @@ static void addMinGWDefines(const llvm::Triple &Triple, const LangOptions &Opts,
DefineStd(Builder, "WIN64", Opts);
Builder.defineMacro("__MINGW64__");
}
- Builder.defineMacro("__MSVCRT__");
Builder.defineMacro("__MINGW32__");
+ if (Opts.getMinGWCRTDll() == LangOptions::WindowsCRTDLLVersion::CRTDLL) {
+ Builder.defineMacro("__CRTDLL__");
+ } else {
+ Builder.defineMacro("__MSVCRT__");
+ switch (Opts.getMinGWCRTDll()) {
+ case LangOptions::WindowsCRTDLLVersion::CRTDLL_Default:
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCRT10:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0x100");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCRT20:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0x200");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCRT40:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0x400");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCRTD:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0x600");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCR70:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0x700");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCR71:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0x701");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCR80:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0x800");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCR90:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0x900");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCR100:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0xA00");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCR110:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0xB00");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::MSVCR120:
+ Builder.defineMacro("__MSVCRT_VERSION__", "0xC00");
+ break;
+ case LangOptions::WindowsCRTDLLVersion::UCRT:
+ Builder.defineMacro("_UCRT");
+ break;
+ default:
+ llvm_unreachable("Unknown MinGW CRT version");
+ }
+ }
addCygMingDefines(Opts, Builder);
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index fe1865888bdd0..79344f4e760d9 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5970,6 +5970,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Triple.isWindowsGNUEnvironment()) {
Args.addOptOutFlag(CmdArgs, options::OPT_fauto_import,
options::OPT_fno_auto_import);
+ Args.addLastArg(CmdArgs, options::OPT_mcrtdll_EQ);
}
if (Args.hasFlag(options::OPT_fms_volatile, options::OPT_fno_ms_volatile,
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index 58c59aa7f2237..7223cda83fa70 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -85,19 +85,24 @@ void tools::MinGW::Linker::AddLibGCC(const ArgList &Args,
CmdArgs.push_back("-lmoldname");
CmdArgs.push_back("-lmingwex");
- for (auto Lib : Args.getAllArgValues(options::OPT_l)) {
- if (StringRef(Lib).starts_with("msvcr") ||
- StringRef(Lib).starts_with("ucrt") ||
- StringRef(Lib).starts_with("crtdll")) {
- Lib = (llvm::Twine("-l") + Lib).str();
- // Respect the user's chosen crt variant, but still provide it
- // again as the last linker argument, because some of the libraries
- // we added above may depend on it.
- CmdArgs.push_back(Args.MakeArgStringRef(Lib));
- return;
- }
+
+ if (Arg *A = Args.getLastArg(options::OPT_mcrtdll_EQ)) {
+ std::string mcrtdll = (Twine("-l") + A->getValue()).str();
+ CmdArgs.push_back(Args.MakeArgStringRef(mcrtdll));
+ } else {
+ for (auto Lib : Args.getAllArgValues(options::OPT_l))
+ if (StringRef(Lib).starts_with("msvcr") ||
+ StringRef(Lib).starts_with("ucrt") ||
+ StringRef(Lib).starts_with("crtdll")) {
+ Lib = (llvm::Twine("-l") + Lib).str();
+ // Respect the user's chosen crt variant, but still provide it
+ // again as the last linker argument, because some of the libraries
+ // we added above may depend on it.
+ CmdArgs.push_back(Args.MakeArgStringRef(Lib));
+ return;
+ }
+ CmdArgs.push_back("-lmsvcrt");
}
- CmdArgs.push_back("-lmsvcrt");
}
void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index b9f75796ecc16..26d05bc419ccb 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -4705,6 +4705,44 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
}
}
+ // Process MinGW -mcrtdll option
+ if (Arg *A = Args.getLastArg(OPT_mcrtdll_EQ)) {
+ Opts.MinGWCRTDll =
+ llvm::StringSwitch<enum LangOptions::WindowsCRTDLLVersion>(
+ A->getValue())
+ .StartsWithLower("crtdll",
+ LangOptions::WindowsCRTDLLVersion::CRTDLL)
+ .StartsWithLower("msvcrt10",
+ LangOptions::WindowsCRTDLLVersion::MSVCRT10)
+ .StartsWithLower("msvcrt20",
+ LangOptions::WindowsCRTDLLVersion::MSVCRT20)
+ .StartsWithLower("msvcrt40",
+ LangOptions::WindowsCRTDLLVersion::MSVCRT40)
+ .StartsWithLower("msvcr40",
+ LangOptions::WindowsCRTDLLVersion::MSVCRT40)
+ .StartsWithLower("msvcrtd",
+ LangOptions::WindowsCRTDLLVersion::MSVCRTD)
+ .StartsWithLower("msvcr70",
+ LangOptions::WindowsCRTDLLVersion::MSVCR70)
+ .StartsWithLower("msvcr71",
+ LangOptions::WindowsCRTDLLVersion::MSVCR71)
+ .StartsWithLower("msvcr80",
+ LangOptions::WindowsCRTDLLVersion::MSVCR80)
+ .StartsWithLower("msvcr90",
+ LangOptions::WindowsCRTDLLVersion::MSVCR90)
+ .StartsWithLower("msvcr100",
+ LangOptions::WindowsCRTDLLVersion::MSVCR100)
+ .StartsWithLower("msvcr110",
+ LangOptions::WindowsCRTDLLVersion::MSVCR110)
+ .StartsWithLower("msvcr120",
+ LangOptions::WindowsCRTDLLVersion::MSVCR120)
+ .StartsWithLower("ucrt", LangOptions::WindowsCRTDLLVersion::UCRT)
+ .Default(LangOptions::WindowsCRTDLLVersion::CRTDLL_Default);
+ if (Opts.MinGWCRTDll == LangOptions::WindowsCRTDLLVersion::CRTDLL_Default) {
+ Diags.Report(diag::err_unknown_crtdll) << A->getValue();
+ }
+ }
+
return Diags.getNumErrors() == NumErrorsBefore;
}
diff --git a/clang/test/Driver/mingw-mcrtdll.c b/clang/test/Driver/mingw-mcrtdll.c
new file mode 100644
index 0000000000000..4558628766169
--- /dev/null
+++ b/clang/test/Driver/mingw-mcrtdll.c
@@ -0,0 +1,30 @@
+// RUN: %clang -v --target=x86_64-w64-mingw32 -### %s 2>&1 | FileCheck -check-prefix=DEFAULT %s
+// RUN: %clang -v --target=x86_64-w64-mingw32 -mcrtdll=msvcr90 -### %s 2>&1 | FileCheck -check-prefix=MSVCR90 %s
+// RUN: %clang -v --target=x86_64-w64-mingw32 -mcrtdll=msvcr90_suffix -### %s 2>&1 | FileCheck -check-prefix=MSVCR90_SUFFIX %s
+// RUN: %clang -v --target=x86_64-w64-mingw32 -mcrtdll=ucrt -### %s 2>&1 | FileCheck -check-prefix=UCRT %s
+// RUN: %clang -v --target=x86_64-w64-mingw32 -mcrtdll=ucrtbase -### %s 2>&1 | FileCheck -check-prefix=UCRTBASE %s
+
+// RUN: %clang -dM -E --target=x86_64-w64-mingw32 %s 2>&1 | FileCheck -check-prefix=DEFINE_DEFAULT %s
+// RUN: %clang -dM -E --target=x86_64-w64-mingw32 -mcrtdll=msvcr90 %s 2>&1 | FileCheck -check-prefix=DEFINE_MSVCR90 %s
+// RUN: %clang -dM -E --target=x86_64-w64-mingw32 -mcrtdll=msvcr90_suffix %s 2>&1 | FileCheck -check-prefix=DEFINE_MSVCR90 %s
+// RUN: %clang -dM -E --target=x86_64-w64-mingw32 -mcrtdll=ucrt %s 2>&1 | FileCheck -check-prefix=DEFINE_UCRT %s
+// RUN: %clang -dM -E --target=x86_64-w64-mingw32 -mcrtdll=ucrtbase %s 2>&1 | FileCheck -check-prefix=DEFINE_UCRT %s
+// RUN: not %clang -dM -E --target=x86_64-w64-mingw32 -mcrtdll=bad %s 2>&1 | FileCheck -check-prefix=BAD %s
+
+// DEFAULT: "-lmingwex" "-lmsvcrt"
+// DEFINE_DEFAULT: #define __MSVCRT__
+// MSVCR90: "-lmingwex" "-lmsvcr90"
+// DEFINE_MSVCR90: #define __MSVCRT_VERSION__ 0x900
+// DEFINE_MSVCR90: #define __MSVCRT__
+// MSVCR90-NOT: "-lmsvcrt"
+// MSVCR90_SUFFIX: "-lmingwex" "-lmsvcr90_suffix"
+// MSVCR90_SUFFIX-NOT: "-lmsvcrt"
+// UCRT: "-lmingwex" "-lucrt"
+// DEFINE_UCRT: #define _UCRT
+// DEFINE_UCRT-NOT: #define __MSVCRT_VERSION__
+// UCRT-NOT: "-lmsvcrt"
+// UCRTBASE: "-lmingwex" "-lucrtbase"
+// UCRTBASE-NOT: "-lmsvcrt"
+// DEFINE_CRTDLL: #define __CRTDLL__
+// DEFINE_CRTDLL-NOT: #define __MSVCRT__
+// BAD: error: unknown Windows/MinGW C runtime library 'bad'
More information about the cfe-commits
mailing list