-
-
Notifications
You must be signed in to change notification settings - Fork 71
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
Conversation
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 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 referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. |
You (DMD) should probably switch to |
Currently missing symbols for a std.stdio-hello-world with LDC:
Looking pretty good IMO. |
Looks pretty good to me, too.
AFAICT
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.
/GS- ? If supplied should probably included in the library similar to atexit.
Could probably be also made to work with VS2013, seems to be part of msvcr120.dll. |
With the 2nd commit and some adaptations (incl.
I tried mocking out these few symbols via
I guess the generated .lib files aren't fully okay; e.g., there's |
lib.exe and link.exe don't support undocumented What we can definitely do is extract these special MinGW directives and auto-generate |
15706cd
to
4cd6f18
Compare
I added a 3rd commit which auto-generates |
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
|
For testing in naked
|
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 The dirty hacked-up @@ -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:
|
Finally got it to work (Win64) after patching |
I found the actual reason for the seemingly incomplete |
98c1f8b
to
9f4157a
Compare
I haven't tested with DMD at all. |
`_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).
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.
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.
Dealing with the stdcall/fastcall mangling mess is necessary for 32-bit. 32-bit hello-word links and starts successfully with LDC (still using Edit: Yep, related to the LLVM implementation (compiling and using the MS implementation from provided src asm works). Hello-world and dmd-testsuite's |
889f9cb
to
6e15e64
Compare
The 32-bit EH issue with LLD seems related to SafeSEH. I'm using |
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
|
With ldc-developers/ldc#2886, these libs now apparently work fine with just => This should be complete from my side. I'll adapt LDC's MSVC-detection logic and then bundle these libs with LDC v1.13. |
Ping @rainers @MartinNowak @WalterBright can you guys take a look? |
Good stuff! Looks pretty good to me, some comments:
|
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). |
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.
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
|
Yeah, but figuring out these missing ones and adding appropriate fixups in
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.
As for debug libs, there are
Sure, no problem from my side if that's easier for DMD; LDC uses |
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.
7e4bd56
to
bf5be11
Compare
We're now using Azure to build these libraries and have thus unified all builds back to master. |
There was a problem hiding this 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
Integration would be: #377 |
Thanks! |
Partial (?) support for UCRTSupport for Visual C++ 2002-2015[I'm trying to get these libs working with LDC too, which will require msvcr120 (VS 2013).] Pinging @rainers.