On Fri, 8 Jul 2022, Allen Hewes wrote:
I'm not the OP, but I've got some questions. I've been helping a little
with mingw-builds and I am curious about ucrt as well. I don't much
about ucrt/ucrtbase, so bear with me. I did find Martin's post about
ucrt from 2019.
I don't know exactly what mail you're referring to, but some parts of your
comments sounds like it was from early discussions, which might not
entirely reflect how things ended up in practice.
I have downloaded a few of the MSYS2 mingw-w64-ucrt packages and
uncompressed them. I then did ldd on the DLL/EXEs and I often find that
both msvcrt.dll and ucrtbase.dll are imports. Is this correct? I was
expecting to see no imports for msvcrt.dll or only imports for a single
C runtime, not both. How does this work? How does this not have
linking/loader issues?
Windows DLLs/EXEs load symbols explicitly from specific DLLs. You can have
one DLL lib1.dll signalling "load 'malloc' from ucrtbase.dll" and another
DLL lib2.dll signalling "load 'malloc' from msvcrt.dll". This doesn't
conflict; lib1.dll's references to malloc gets resolved from ucrtbase.dll
and lib2.dll's references get resolved from msvcrt.dll.
There's no global symbol namespace between DLLs at runtime - contrary to
e.g. ELF.
The reason why you're seeing msvcrt.dll here is because many system
libraries link against msvcrt.dll (that's what it is after all - the
Windows system internal C runtime). Some system components link against
UCRT, some against msvcrt.dll. ldd prints all libraries that end up loaded
in practice, not only the ones that are referenced directly.
To see the DLLs that an executable references directly, you can run e.g.
"llvm-readobj --coff-imports <exe>" (if you happen to have that tool
available), or e.g. "objdump -p <exe>" (which prints a lot more, so the
reference DLLs is a bit harder to see in isolation). If you look at
binaries in the msys2 mingw-w64-ucrt repo, I would expect that none of
them directly load msvcrt.dll.
In Martin's post, he mentions dumping the current gcc specs and
modifying them, then using the gcc arg to use custom specs when linking
for ucrt. I guess my question is this seems harder than sticking with
msvcrt because It Just Works. Will folks ever be able to use
ucrt/ucrtbase in replacement of msvcrt and just have gcc/ld/libtool use
ucrt/ucrtbase?
The use of spec file hackery was only discussed early on as an alternative
way of choosing what CRT to link against. It's not something that is
recommended that you do in practice.
All packages in the MSYS2 mingw-w64-ucrt repo all use ucrt/ucrtbase
instead of msvcrt, in all of gcc/ld/libtool etc.
I guess I'd assume mingw-w64 to set gcc specs if I used
--with-default-msvcrt=ucrt. With this configure option, I still get
import libs for msvcrt/msvcrt-os and ucrt/ucrtbase, why is that?
Configuring the toolchain with --with-default-msvcrt=ucrt (in both
mingw-w64-headers and mingw-w64-crt, then building the rest of the
toolchain, e.g. libgcc/libstdc++ on top of that) is indeed the correct way
to set it up.
When you build mingw-w64-crt, you do get the import libraries for all CRT
alternatives (UCRT and msvcrt) installed - you do get libucrt.a,
libmsvcrt-os.a. libmsvcrt-os.a is the library that always links against
"the msvcrt.dll that comes with the OS".
Now in practice, gcc and clang and possibly lots of other tools default to
linking with "-lmsvcrt" (in the spec files in gcc, hardcoded in clang). So
instead of trying to clumsily change that default in various places, we
settled on repurposing what "libmsvcrt.a" is.
libmsvcrt.a is the import library for the default CRT that you chose with
the --with-default-msvcrt= option when mingw-w64-crt was built. It's a
copy of libmsvcrt-os.a or libucrt.a (or libucrtbase.a, or
libmsvcr<numbers>.a if you picked that).
If using ucrt/ucrtbase is kinda this road with curves,
It really isn't a road with curves - I don't understand how you got that
picture.
If you download a toolchain that is built defaulting to ucrt, it
practically works just as smoothly as toolchains defaulting to msvcrt.
Many such toolchains are available, e.g. the ucrt repo in msys2.
why use it over msvcrt? What are the advantages of using ucrt/ucrtbase
over msvcrt? (Other than one is "legacy"...)
There's lots of various reasons one might have for wanting it.
UCRT is not "legacy" indeed - linking against msvcrt.dll is explicitly
discouraged by Microsoft (other than for the small subset of MSVC6
functions).
UCRT has got working locale support, and provides functions that are C99
compliant, allowing us to potentially get rid of a bunch of statically
linked mingw specific functions.
Using UCRT improves interop with code built with MSVC, if different parts
of the setup pass around CRT objects between modules built with MSVC and
mingw (e.g. call fopen in one DLL and fclose in another, call malloc in
one DLL and free in another, etc).
For arm64, there never shipped any version of Windows supporting arm64
that didn't have ucrt, so there's no reason not to use the modern CRT as
baseline by default for such configurations.
Plus possibly a bunch of other reasons.
// Martin
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public