Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from MinGW to MinGW-w64 #346

Merged
merged 20 commits into from
Apr 14, 2019
Merged

Conversation

kinke
Copy link
Contributor

@kinke kinke commented Oct 21, 2018

  • Proper support for Win64
  • Way more libs (900 for x64, 591 for x86 - currently around 115)
  • No stdcall mangling in 64-bit .def files
  • Partial (?) support for UCRT Support for Visual C++ 2002-2015

[I'm trying to get these libs working with LDC too, which will require msvcr120 (VS 2013).] Pinging @rainers.

@dlang-bot
Copy link
Contributor

dlang-bot commented Oct 21, 2018

Thanks for your pull request and interest in making D better, @kinke! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the annotated coverage diff directly on GitHub with CodeCov's browser extension
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

@kinke
Copy link
Contributor Author

kinke commented Oct 21, 2018

You (DMD) should probably switch to msvcr120.lib too. IIRC, druntime assumes that as min version in various places, leading to linking errors (e.g., math symbols) or wrong results otherwise, as MS added more-or-less-complete C99 compatibility with VS 2013, and some more additions/fixes with VS 2015.

@kinke
Copy link
Contributor Author

kinke commented Oct 21, 2018

Currently missing symbols for a std.stdio-hello-world with LDC:

[in a naked shell, no env variables except for VSINSTALLDIR=1]
$ ldc2 hello.d -L-LC:\LDC\installer\windows\mingw\lib64 -mscrtlib=msvcr120 -linker="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.15.26726\bin\Hostx64\x64\link.exe" -L/NODEFAULTLIB:vcruntime -L/NODEFAULTLIB:legacy_stdio_definitions
msvcr120.lib(msvcrt_atexit.obj) : error LNK2005: atexit already defined in msvcr120.lib(MSVCR120.dll)
phobos2-ldc.lib(gzlib.c.obj) : error LNK2019: unresolved external symbol __stdio_common_vsprintf referenced in function snprintf
phobos2-ldc.lib(file.obj) : error LNK2019: unresolved external symbol __chkstk referenced in function _D3std4file6getcwdFNeZAya
phobos2-ldc.lib(parallelism.obj) : error LNK2001: unresolved external symbol __chkstk
druntime-ldc.lib(dmain2.obj) : error LNK2001: unresolved external symbol __chkstk
phobos2-ldc.lib(crc32.c.obj) : error LNK2001: unresolved external symbol __GSHandlerCheck
phobos2-ldc.lib(inftrees.c.obj) : error LNK2001: unresolved external symbol __GSHandlerCheck
phobos2-ldc.lib(trees.c.obj) : error LNK2001: unresolved external symbol __GSHandlerCheck
phobos2-ldc.lib(crc32.c.obj) : error LNK2019: unresolved external symbol __security_check_cookie referenced in function crc32_combine_
phobos2-ldc.lib(inftrees.c.obj) : error LNK2001: unresolved external symbol __security_check_cookie
phobos2-ldc.lib(trees.c.obj) : error LNK2001: unresolved external symbol __security_check_cookie
phobos2-ldc.lib(crc32.c.obj) : error LNK2019: unresolved external symbol __security_cookie referenced in function crc32_combine_
phobos2-ldc.lib(inftrees.c.obj) : error LNK2001: unresolved external symbol __security_cookie
phobos2-ldc.lib(trees.c.obj) : error LNK2001: unresolved external symbol __security_cookie
phobos2-ldc.lib(inftrees.c.obj) : error LNK2019: unresolved external symbol __report_rangecheckfailure referenced in function inflate_table
druntime-ldc.lib(eh_msvc.obj) : error LNK2019: unresolved external symbol set_terminate referenced in function _d_throw_exception
druntime-ldc.lib(eh_msvc.obj) : error LNK2019: unresolved external symbol __processing_throw referenced in function _D3ldc7eh_msvc17msvc_eh_terminateFNbZv
druntime-ldc.lib(eh_msvc.obj) : error LNK2019: unresolved external symbol __current_exception referenced in function _d_eh_swapContext
druntime-ldc.lib(eh_msvc.obj) : error LNK2019: unresolved external symbol __current_exception_context referenced in function _d_eh_swapContext
hello.exe : fatal error LNK1120: 10 unresolved externals
  • atexit() is defined in one of the extra object files merged into the msvcrt import libs. Maybe the old MinGW .def was incomplete?
  • __stdio_common_vsprintf: Phobos' zlib was compiled with VS 2017. MS uses inline stdio functions starting with VS 2015 (for printf etc.); fixing this will require some tricks to make it work with both older and newer MS libs.
  • __chkstk: emitted by LLVM when coming across an alloca, to detect stack overflows.
  • __security_cookie, __report_rangecheckfailure, __GSHandlerCheck: I guess something similar (buffer overflow), but emitted by the MS C compiler; can presumably be omitted via compiler switch.
  • EH will need some work; the LDC implementation currently requires VS 2015+. Rainer knows all about it, as he implemented it. ;)

Looking pretty good IMO.

@rainers
Copy link
Member

rainers commented Oct 21, 2018

Looks pretty good to me, too.

  • atexit() is defined in one of the extra object files merged into the msvcrt import libs. Maybe the old MinGW .def was incomplete?

AFAICT atexit must exist in each DLL (if not for explicit calls, at least to allow destruction of C++ globals), Not sure why it's also exported by the MS-DLLs.

  • __stdio_common_vsprintf: Phobos' zlib was compiled with VS 2017. MS uses inline stdio functions starting with VS 2015 (for printf etc.); fixing this will require some tricks to make it work with both older and newer MS libs.

I guess it used to be compiled with VS2013. legacy_stdio_defiitions.lib probably doesn't help here, as it is for the reverse case.

  • __chkstk: emitted by LLVM when coming across an alloca, to detect stack overflows.

  • __security_cookie, __report_rangecheckfailure, __GSHandlerCheck: I guess something similar (buffer overflow), but emitted by the MS C compiler; can presumably be omitted via compiler switch.

/GS- ? If supplied should probably included in the library similar to atexit.

  • EH will need some work; the LDC implementation currently requires VS 2015+. Rainer knows all about it, as he implemented it. ;)

Could probably be also made to work with VS2013, seems to be part of msvcr120.dll.

@kinke
Copy link
Contributor Author

kinke commented Oct 21, 2018

With the 2nd commit and some adaptations (incl. /GS- for zlib compilation and linking in ntdll.lib for __chkstk), I'm now down to:

phobos2-ldc.lib(gzlib.c.obj) : error LNK2019: unresolved external symbol __stdio_common_vsprintf referenced in function snprintf
druntime-ldc.lib(eh_msvc.obj) : error LNK2019: unresolved external symbol set_terminate referenced in function _d_throw_exception
druntime-ldc.lib(eh_msvc.obj) : error LNK2019: unresolved external symbol __processing_throw referenced in function _D3ldc7eh_msvc17msvc_eh_terminateFNbZv
druntime-ldc.lib(eh_msvc.obj) : error LNK2019: unresolved external symbol __current_exception referenced in function _d_eh_swapContext
druntime-ldc.lib(eh_msvc.obj) : error LNK2019: unresolved external symbol __current_exception_context referenced in function _d_eh_swapContext

I tried mocking out these few symbols via extern (C) __gshared char globals in hello.d; linking succeeds, but when trying to run it, a Windows msgbox pops up:

The procedure entry point localtime could not be located in the dynamic link library C:\LDC\ninja-ldc\hello.exe

I guess the generated .lib files aren't fully okay; e.g., there's localtime=_localtime64 in msvcr120.def. Edit: Yep, the MS lib file C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib\amd64\msvcrt.lib doesn't export the alias; it's a WeakExternal symbol. The original .def has localtime == _localtime64, which isn't valid .def syntax (I just hoped I could fix it up like this); I guess we need to compile a C object for these defs/libs.

@kinke
Copy link
Contributor Author

kinke commented Oct 21, 2018

I guess we need to compile a C object for these defs/libs.

lib.exe and link.exe don't support undocumented /alternatename:alias=symbol in the command-line directly. Hacking it into an object file requires dragging it in and is so no option for each lib.

What we can definitely do is extract these special MinGW directives and auto-generate oldnames.{c,lib} from it, which should cover way more symbols then. E.g., open=_open is currently missing; current manual oldnames.c defines an apparently wrong alias _open=__open.

@kinke
Copy link
Contributor Author

kinke commented Oct 21, 2018

I added a 3rd commit which auto-generates oldnames.c; seems to work fine, the undefined open symbol is gone.

@kinke
Copy link
Contributor Author

kinke commented Oct 22, 2018

I'm now more interested in getting VS 2015+ working. I looked up the VS 2015 library changes again; it introduced hexadecimal floating-point parsing, fixed accuracy of fp parsing, changed to C99 nan and inf strings, fixed vulnerability of (_)vsnprintf etc. etc.
It also wouldn't require touching LDC's EH code in druntime and neither handling the stdio thingy (I'd have an idea for that but would rather not go down that path due to the numerous VS 2015 improvements).
There are some issues:

  • There's only vcruntime140_app.def; it seems to almost perfectly correspond to a .def auto-generated from the VS 2015 .dll though (well, after fixing the LIBRARY directive, I haven't found any vcruntime140_app.dll). [A .def can be generated from any DLL by using the gendef tool included in MinGW-w64 (src only, needs to be built in MSYS; configure + make; I can upload a prebuilt binary if there's interest - edit: here it is)].
    => Easy.
  • The UCRT with its large number of tiny app-ms-win-* DLLs is kinda strange. The generated .defs seem to indicate that all (?) exported functions in these tiny libs actually just forward to ucrtbase.dll (or other prominent DLLs). Using the MinGW-w64 ucrtbase.def doesn't really work though (e.g., no cos export, apparently because marked as DATA). The auto-generated .def (from latest Win10 SDK DLL) differs in quite a lot of places, so I gave that one a shot, looking much better. So in essence, I replaced msvcr120.lib by ucrtbase.lib + vcruntime140.lib + a manual legacy_stdio_definitions.obj. The binary will have a direct dependency on ucrtbase.dll instead of the various app-ms-win-* DLLs.
    => Will probably require adding auto-generated 32/64-bit ucrtbase.def files; could probably be upstreamed to MinGW-w64 then too.
  • When merging the current msvcrt_stub.obj etc. into some lib (I used vcruntime140.lib), the only remaining unresolved symbol is __getmainargs. And that seems like the hardest part, replicating the startup/shutdown code, which may have changed considerably with UCRT. ucrtbase seems to export a _configure_{wide,narrow}_argv function (presumably setting up __argc and __argv), but I guess the CRT sources will need to be studied to come up with a proper minimal version. Any help would be greatly appreciated. ;)

@kinke
Copy link
Contributor Author

kinke commented Oct 23, 2018

For testing in naked cmd.exe:

$ set VSINSTALLDIR=1 // make LDC skip VS auto-detection
$ ldc2 hello.d -L-LC:\LDC\installer\windows\mingw\lib64 -mscrtlib=ucrtbase -linker="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.15.26726\bin\Hostx64\x64\link.exe" -L/NODEFAULTLIB:vcruntime -Lvcruntime140.lib -Lntdll.lib
ucrtbase.lib(msvcrt_stub1.obj) : error LNK2019: unresolved external symbol __getmainargs referenced in function mainCRTStartup
hello.exe : fatal error LNK1120: 1 unresolved externals

@kinke
Copy link
Contributor Author

kinke commented Oct 24, 2018

Alright, somewhat closer - no linking errors anymore, C cmdline parsing works too. I only later realized that druntime's _d_run_main() parses the cmdline itself so that it's probably in vain. Anyway, current state is that the executable crashes at startup, at the [presumably] first GC collection (right before running the module ctors; access violation in processGCMarks()); possibly due to TLS not being initialized or something else missing from regular initialization code.

The dirty hacked-up msvcrt_stub.c getting me there:

@@ -1,4 +1,6 @@
 #include <windows.h>
+#include <fcntl.h>
+#include <stdlib.h>

 #define _CRTALLOC(x) __declspec(allocate(x))

@@ -61,8 +63,9 @@ DllMainCRTStartup (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)

 #else // _APPTYPE != __UNKNOWN_APP

-extern int    _argc;
-extern char **_argv;
+extern int    __argc;
+extern char **__argv;
+extern wchar_t **__wargv;

 /* In MSVCRT.DLL, Microsoft's initialization hook is called __getmainargs(),
  * and it expects a further structure argument, (which we don't use, but pass
@@ -71,6 +74,19 @@ extern char **_argv;
 typedef struct _startupinfo { int mode; } _startupinfo;
 extern void __getmainargs( int *argc, char ***argv, char ***penv, int glob, _startupinfo *info );

+extern int _initialize_narrow_environment();
+extern char **_get_initial_narrow_environment();
+extern wchar_t **_get_initial_wide_environment();
+extern char *_get_narrow_winmain_command_line();
+extern int _configure_narrow_argv(int);
+
+typedef enum _crt_argv_mode
+{
+    _crt_argv_no_arguments,
+    _crt_argv_unexpanded_arguments,
+    _crt_argv_expanded_arguments,
+} _crt_argv_mode;
+
 /* The function mainCRTStartup() is the entry point for all
  * console/desktop programs.
  */
@@ -87,27 +103,32 @@ void WinMainCRTStartup(void)
     /* The MSVCRT.DLL start-up hook requires this invocation
      * protocol...
      */
+/*
     char **envp = NULL;
     _startupinfo start_info = { 0 };
     __getmainargs(&_argc, &_argv, &envp, 0, &start_info);
+*/

     _initterm(__xi_a, __xi_z);
     _initterm(__xc_a, __xc_z);

 #if _APPTYPE == __CONSOLE_APP
-    nRet = main(_argc, _argv, envp);
+    _set_fmode(_O_TEXT);
+    _configure_narrow_argv(_crt_argv_unexpanded_arguments);
+    _initialize_narrow_environment();
+    nRet = main(__argc, __argv, _get_initial_narrow_environment());
 #else
     {
         STARTUPINFOA startupInfo;
         GetStartupInfoA(&startupInfo);
         int showWindowMode = startupInfo.dwFlags & STARTF_USESHOWWINDOW
                            ? startupInfo.wShowWindow : SW_SHOWDEFAULT;
-        PCSTR lpszCommandLine = GetCommandLineA();
+        PCSTR lpszCommandLine = _get_narrow_winmain_command_line();
         nRet = WinMain((HINSTANCE)&__ImageBase, NULL, lpszCommandLine, showWindowMode);
     }
 #endif

-    term_atexit();
+    //term_atexit();
     _initterm(__xp_a, __xp_z);
     _initterm(__xt_a, __xt_z);

Backtrace:

 	hello.exe!rt.lifetime::processGCMarks() Line 559	D
 	hello.exe!rt.tlsgc::processGCMarks() Line 81	D
	hello.exe!core.thread::thread_processGCMarks() Line 3330	D
 	hello.exe!gc.impl.conservative.gc::Gcx::fullcollect() Line 2420	D
 	hello.exe!gc.impl.conservative.gc::Gcx::smallAlloc() Line 1712	D
 	hello.exe!gc.impl.conservative.gc::Gcx::alloc() Line 1676	D
 	hello.exe!gc.impl.conservative.gc::ConservativeGC::mallocNoSync() Line 517	D
 	hello.exe!gc.impl.conservative.gc::ConservativeGC::runLocked() Line 390	D
 	hello.exe!gc.impl.conservative.gc::ConservativeGC::malloc() Line 495	D
 	hello.exe!gc.proxy::gc_malloc() Line 139	D
 	hello.exe!gc.impl.proto.gc::ProtoGC::malloc() Line 106	D
 	hello.exe!gc.proxy::gc_malloc() Line 139	D
 	hello.exe!core.memory::GC::malloc() Line 380	D
 	[Inline Frame] hello.exe!rt.lifetime::_d_newclass() Line 109	D
 	hello.exe!rt.lifetime::_d_allocclass() Line 152	D
 	hello.exe!ldc.eh_msvc::msvc_eh_init() Line 575	D
 	hello.exe!rt.dmain2::rt_init() Line 206	D
 	hello.exe!rt.dmain2._d_run_main.runAll() Line 501	D
 	hello.exe!rt.dmain2._d_run_main.tryExec() Line 489	D
 	hello.exe!rt.dmain2::_d_run_main() Line 536	D
 	hello.exe!__entrypoint::main() Line 8	D
 	hello.exe!mainCRTStartup�()	C

@kinke
Copy link
Contributor Author

kinke commented Oct 25, 2018

Finally got it to work (Win64) after patching msvcrt_data.c (different segment for TLS data). I still have to clean up my local mess before pushing some commits.

@kinke
Copy link
Contributor Author

kinke commented Oct 25, 2018

I found the actual reason for the seemingly incomplete ucrtbase.def.in file - they hide some functions which they override in their MinGW runtime, mainly math functions, by appending a DATA suffix. I revert that, so there's no more need to override full .def files.

@kinke
Copy link
Contributor Author

kinke commented Oct 26, 2018

$ ldc2 -L-LC:\LDC\installer\windows\mingw\lib64 -mscrtlib=vcruntime140 -linker="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.15.26726\bin\Hostx64\x64\link.exe" -L/NODEFAULTLIB:vcruntime -Lntdll.lib -run ..\hello.d
Hello LDC2 8
$ ldc2 -L-LC:\LDC\installer\windows\mingw\lib64 -mscrtlib=vcruntime140 -link-internally -L/NODEFAULTLIB:vcruntime -L/NODEFAULTLIB:LIBCMT.lib -Lucrtbase.lib -Lntdll.lib -run ..\hello.d
Hello LDC2 8

I haven't tested with DMD at all.

kinke added a commit to ldc-developers/druntime that referenced this pull request Oct 26, 2018
`_fileno` exists in the pre-2015 DLLs according to MinGW-w64.

This is required as preparation for the MinGW-w64 libs
(dlang/installer#346), as they define the weak
symbol like this, and LLD complains about mismatches (while MS' link.exe
doesn't).
kinke added a commit to kinke/ldc that referenced this pull request Oct 26, 2018
I got a std.stdio hello-world executable to work on Win64 using the
Visual C++ 2015 DLLs, with both MS linker and -link-internally, see
dlang/installer#346.

It still requires a couple of extra command-line args, but will in the
end enable us to get rid of all external dependencies for building on
Windows (via -link-internally and the MinGW-w64-based import libs, which
will only add a few MB to the prebuilt packages).

The Visual C++ 2015 *runtime* will need to be installed when running
binaries linked against the MinGW libs.
kinke added a commit to kinke/ldc that referenced this pull request Oct 26, 2018
I got a std.stdio hello-world executable to work on Win64 using the
Visual C++ 2015 DLLs, with both MS linker and -link-internally, see
dlang/installer#346.

It still requires a couple of extra command-line args, but will in the
end enable us to get rid of all external dependencies for building on
Windows (via -link-internally and the MinGW-w64-based import libs, which
will only add a few MB to the prebuilt packages).

The Visual C++ 2015 *runtime* will need to be installed when running
binaries linked against the MinGW libs.
@kinke
Copy link
Contributor Author

kinke commented Oct 27, 2018

Dealing with the stdcall/fastcall mangling mess is necessary for 32-bit. 32-bit hello-word links and starts successfully with LDC (still using vcruntime140), but segfaults a bit later on in memcpy; that is possibly related to the _chkstk implementation in LLVM's compiler-rt lib though, as it happens when accessing memory allocated via alloca [and I had troubles with the 64-bit variant too yesterday; that is finally working now].

Edit: Yep, related to the LLVM implementation (compiling and using the MS implementation from provided src asm works).


Hello-world and dmd-testsuite's runnable/eh[2].d work fine with these 32/64-bit libs (vcruntime140). On Win64, they work with both MS linker and LLD; on Win32, eh[2] crashes with LLD (0xC00001A5: An invalid exception handler routine has been detected (parameters: 0x00000001)).

@kinke
Copy link
Contributor Author

kinke commented Oct 28, 2018

The 32-bit EH issue with LLD seems related to SafeSEH. I'm using /SAFESEH:NO for Win32 with both linkers, as there are 2 ASM files without them (msvcrt_abs.asm here and LLVM's __chkstk implementation), and the linkers needs that flag for successful linking.

@kinke
Copy link
Contributor Author

kinke commented Oct 28, 2018

Alright, got this to work too now, see last 2 commits. I additionally had to hack the LLVM _chkstk asm file, to make that object file marked safe-EH compatible (as clang has no /safeseh option and no equivalent AFAICT, and ml cannot be used due to AT&T syntax...), by injecting this directly under .text:

.def    @feat.00;
.scl    3;
.type   0;
.endef
.globl  @feat.00
.set    @feat.00, 1

@kinke
Copy link
Contributor Author

kinke commented Oct 28, 2018

With ldc-developers/ldc#2886, these libs now apparently work fine with just ldc2 {-link-internally,-linker=...\link.exe} -L-LC:\LDC\installer\windows\mingw\lib{32,64} -mscrtlib=vcruntime140 in a naked cmd.exe with env variable VSINSTALLDIR=1.

=> This should be complete from my side. I'll adapt LDC's MSVC-detection logic and then bundle these libs with LDC v1.13.

kinke added a commit to ldc-developers/mingw-w64-libs that referenced this pull request Oct 28, 2018
@PetarKirov
Copy link
Member

Ping @rainers @MartinNowak @WalterBright can you guys take a look?

@rainers
Copy link
Member

rainers commented Oct 31, 2018

Good stuff! Looks pretty good to me, some comments:

  • druntime has only 165 files in core.sys.windows, I suspect there are no declarations for all the additional libraries. AFAICT the D files base on the old mingw sources, too.
  • to be a drop-in replacement for existing dmd distributions, msvcr100.lib should be renamed (or copied) to msvcrt100.lib.
  • I noticed quite a few symbols in msvcr100.dll and msvcrt100.dll, but not in the msvcr100.lib generated by this PR, e.g. wctob. The latter has more symbols, though, but mostly C++.

@kinke
Copy link
Contributor Author

kinke commented Oct 31, 2018

wctob is marked as DATA in the .def (the original MinGW-w64 one) - but only in msvcr90 and msvcr100; it's exported properly in 110, 120 and UCRT. I guess neither the MinGW nor the MinGW-w64 .def files are 100% okay. Edit: Ah, they have their own wctob implementation in their mingw-w64-crt library. Patching out their math overrides (80-bit long double...) was rather simple (common macro pattern in .def.in files), but doing so for all of their overrides is of course not feasible.

What's the reason for holding on to VS 2010? Is that runtime preinstalled on Windows 7+ or something like that?

Wrt. extra libs, I see the primary advantage in being able to basically link with all external Windows bindings, not just with what druntime exposes; e.g., various DirectX versions. And of course the option to choose from 6 Visual C++ versions. The 32+64 bit libs (36 MB) can be compressed down to 2.42 MB with 7Zip (max compression).

@rainers
Copy link
Member

rainers commented Nov 1, 2018

Ah, they have their own wctob implementation in their mingw-w64-crt library. Patching out their math overrides (80-bit long double...) was rather simple (common macro pattern in .def.in files), but doing so for all of their overrides is of course not feasible.

wctob might not be the most popular function, but it seems to affect quite a few others aswell, e.g. sqrt. I guess some will miss these.

What's the reason for holding on to VS 2010? Is that runtime preinstalled on Windows 7+ or something like that?

IIRC it was the latest version the old mingw-project provided. It is also more likely to be already installed on older systems, but I don't think any of these are actually preinstalled (but msvcrt.dll, i.e. VC7). The druntime/phobos makefiles also default to building against VS 2010, but I guess nobody but Walter uses that default.

I agree it is a plus to provide the platform import libraries, but it feels incomplete without the respective definitions in druntime. Being able to choose the VS runtime is also great, but if you are getting that serious with diving into D, you will likely want to install the static or debug libraries aswell.

I don't mind a few extra MB for the installer and I'd be fine with switching to VC12 as the default in the long run, but having the names match would make the transition easier and doesn't need adapting both dmd and the installer right now.

I'm not too happy about the chosen name msvcrt100.lib, too, but there is no precedent for msvcr100.lib aswell:

  • Microsoft calls the library msvcrt.lib
  • It is not a simple import library of the respective DLL, but adds some code, too.

@kinke
Copy link
Contributor Author

kinke commented Nov 1, 2018

wctob might not be the most popular function, but it seems to affect quite a few others aswell, e.g. sqrt. I guess some will miss these.

Yeah, but figuring out these missing ones and adding appropriate fixups in sanitizeDef() will be very tedious, especially if LDC is using VC14 and DMD VC10.
I've just tried linking & running the Phobos and druntime test runners (x64 only) with the VC14 libs with LDC; Phobos works fine, druntime complained about missing vfw32.lib. That lib is apparently a merge of 3 other libs; there's a corresponding .mri file in the MinGW-w64 src tree. Luckily, that one seems to be the only relevant special case, so I'll add that merge as additional step.

I agree it is a plus to provide the platform import libraries, but it feels incomplete without the respective definitions in druntime.

Well I don't think the DirectX bindings for example should be in druntime. But it's IMO nice that you can use 3rd party ones (https://forum.dlang.org/thread/pb170v$1bkq$1@digitalmars.com) and still link without having to install the MS toolchain.

Being able to choose the VS runtime is also great, but if you are getting that serious with diving into D, you will likely want to install the static or debug libraries aswell.

As for debug libs, there are msvcr90d and msvcr120d too, but only those 2. ;)
Sure, serious development will still require the MS libs, as those are guaranteed to be complete and correct and offer the static-linking option.
The different msvcr* versions don't add a lot to the package size, they're around 300 KB each.

having the names match

Sure, no problem from my side if that's easier for DMD; LDC uses vcruntime140 anyway. [The names without trailing 't' would match the DLL names (8.3 format...).]

kinke added 17 commits April 14, 2019 09:48
Seems to be working fine for Win64 and LDC, based on a hello-world
console app.
That symbol is available in LLVM's builtins compiler-rt library, so no
need to export it and link with ntdll.dll anymore.
This has gotten messy, as some .defs feature stdcall-mangled functions
as well as C++ ones, and some hide stdcall-mangled functions via `DATA`
suffix, so that we have to handle global variables with `@` characters
etc.
I switched from C to D, as `pragma(mangle)` is a big help when dealing
with arbitrary identifiers.
To prevent having to link with `/SAFESEH:NO`.
Containing the information displayed by `dumpbin /loadconfig`.
Seems to be required when generating a safe-EH compatible binary (32-bit
only).
Specifically tailored for ucrtbase.def (LDC) and msvcr100.def (DMD).

This list has been generated by side-by-side diffing the final patched
.def file and the .def file auto-generated by MinGW-w64's gendef tool.
The oldnames.list file has been generated by dumping the VS 2015
oldnames.lib symbols (`dumpbin /symbols`).
These aliases are added to or replace aliases defined in the MinGW-w64
.def files (`alias == realName`).

I checked the 32- and 64-bit libs; they are identical and only differ
wrt. symbol mangling.
Ignore the aliases in the MinGW-w64 .def files altogether; they are
not just incomplete, but sometimes also wrong (e.g.,
ldc-developers/ldc#2903; there were more of
these after I checked against msvcrt.lib).

I decided to write a little tool to extract these aliases from the MS
libs. The resulting output for VS 2015 oldnames.lib and msvcrt.lib is
included (as well as the tool) as input files for the generated linker
directives in oldnames.lib.
@wilzbach
Copy link
Member

We're now using Azure to build these libraries and have thus unified all builds back to master.
Hence, I went ahead and retargeted master and rebased for you.

Copy link
Member

@wilzbach wilzbach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has rotten here for too long. I'm just going to merge it and upload it to downloads.dlang.org/other
We still need to integrate it with DMD (and run its tests), but maybe we can do so before the 2.086 beta

@wilzbach wilzbach merged commit 3e6c459 into dlang:master Apr 14, 2019
@wilzbach
Copy link
Member

@wilzbach wilzbach mentioned this pull request Apr 14, 2019
@wilzbach
Copy link
Member

We still need to integrate it with DMD

Integration would be: #377

@kinke
Copy link
Contributor Author

kinke commented Apr 14, 2019

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants