On Wed, 19 Jul 2023, Thiago Macieira wrote:

On Wednesday, 19 July 2023 08:46:27 PDT Cristian Adam via Development wrote:

With this migration would should also switch to Universal
CRT<https://devblogs.microsoft.com/cppblog/introducing-the-universal-crt/>.
The toolchain comes in both ucrt and msvcrt variants, but the former is
preferrable nowadays.

Indeed and that's great, but that's a BC break. That means you'll need to
provide two sets of binaries for a time.

It's also orthogonal, because GCC supports UCRT too, with this patch:
https://github.com/msys2/MINGW-packages/raw/
8d9ebb74412c1faabc2a3935bfc705bec19edb9a/mingw-w64-gcc/0006-Windows-New-
feature-to-allow-overriding.patch

Indeed UCRT support isn't Clang specific at all - but GCC doesn't really need that patch either.

And conversely, that patch (and a later recently upstreamed version of the same) gives a false sense of being able to switch between msvcrt and UCRT at will; that feature really needs to come with a big disclaimer.

That flag, allowing you to decide whether to target msvcrt or UCRT when building/linking your end user executable, only works in a small subset of scenarios if you're really careful and know what you're doing - if not, it's a very subtle footgun.

There are significant differences in how the mingw-w64 CRT headers behave between msvcrt and UCRT mode; in one mode, some functions may be inlined or directed towards a symbol with one name, and towards one with another name in the other mode. (If you strike that, you get a fairly visible linking error.) Worse, some structs have different layout, and there are other ABI differences (for the UCRT mode, we decided to modernize things with defaulting to a 64 bit time_t in 32 bit mode).

The only really safe way of doing this, is picking one as default and bootstrap the whole toolchain with that, and then having separate toolchains targeting ucrt or msvcrt. (In msys2, the mingw64 environment is gcc-based targeting msvcrt, while the ucrt64 environment is gcc-based targeting ucrt).

Switching with those flags works, as long as you're building a C-only executable and linking libgcc statically (and not linking in any static libraries that were built for another CRT). I'm pretty sure that libstdc++ touches lots of the things that have a differing ABI. A shared linked libgcc will use the CRT that the toolchain was built with - although I'm not sure if libgcc shares any CRT objects across the DLL boundary (whether it is a real issue or just messy).

So TL;DR, pretend that flag doesn't exist in GCC, and just use a toolchain that was bootstrapped for the desired CRT. (The flag is more useful for switching between older variants of the MSVC CRTs that have less hairy ABI differences.)

// Martin

--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to