Skip to content

MinGW-based libs: Add wide entry points #427

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

Merged
merged 2 commits into from
Feb 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions windows/build_mingw.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
set ROOT=%CD%
mkdir "%ROOT%\artifacts"

set TAG=mingw-libs-%MINGW_VER%-2
set ARTIFACT=%TAG%.zip
set ARTIFACTPATH=%ROOT%\artifacts\%ARTIFACT%
set GITHUB_RELEASE=https://github.com/dlang/installer/releases/download/%TAG%/%ARTIFACT%

REM Stop early if the artifact already exists
powershell -Command "Invoke-WebRequest downloads.dlang.org/other/mingw-libs-%MINGW_VER%.zip -OutFile %ROOT%\artifacts\mingw-libs-%MINGW_VER%.zip" && exit /B 0
powershell -Command "Invoke-WebRequest %GITHUB_RELEASE% -OutFile %ARTIFACTPATH%" && exit /B 0

set DMD_URL=http://downloads.dlang.org/releases/2.x/%D_VERSION%/dmd.%D_VERSION%.windows.7z
echo DMD_URL=%DMD_URL%
Expand Down Expand Up @@ -35,4 +40,4 @@ call "%VSINSTALLDIR%\VC\Auxiliary\Build\vcvarsall.bat" x86
cd %ROOT%\windows\mingw
dmd -run buildsdk.d x86 %ROOT%\mingw-w64 dmd2\windows\lib32mscoff\mingw || exit /B 1

7z a %ROOT%\artifacts\mingw-libs-%MINGW_VER%.zip dmd2\windows
7z a "%ARTIFACTPATH%" dmd2\windows
2 changes: 2 additions & 0 deletions windows/mingw/buildsdk.d
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ void buildMsvcrt(string outDir)
// compile some additional objects
foreach (i; 0 .. 3)
addObj(format!"msvcrt_stub%d.obj"(i), format!"/D_APPTYPE=%d msvcrt_stub.c"(i));
foreach (i; 1 .. 3) // not needed for DLLs
addObj(format!"msvcrt_stub_wide%d.obj"(i), format!"/D_APPTYPE=%d /D_UNICODE msvcrt_stub.c"(i));
addObj("msvcrt_data.obj", "msvcrt_data.c");
addObj("msvcrt_atexit.obj", "msvcrt_atexit.c");
if (!x64)
Expand Down
73 changes: 61 additions & 12 deletions windows/mingw/msvcrt_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ extern _PVFV __xp_z[];
extern _PVFV __xt_a[];
extern _PVFV __xt_z[];

extern int main (int, char **, char **);
extern void _setargv (void);
extern void term_atexit();

Expand Down Expand Up @@ -78,7 +77,14 @@ __pragma(comment(linker, "/alternatename:_DllMain@12=___DefaultDllMain@12"));
#else // _APPTYPE != __UNKNOWN_APP

extern int __argc;

#ifndef _UNICODE
extern char **__argv;
extern int main(int, char **, char **);
#else
extern wchar_t **__wargv;
extern int wmain(int, wchar_t **, wchar_t **);
#endif

#if MSVCRT_VERSION >= 140 // UCRT

Expand All @@ -95,10 +101,17 @@ enum _crt_argv_mode
_crt_argv_expanded_arguments,
};

#ifndef _UNICODE
extern int _initialize_narrow_environment();
extern char **_get_initial_narrow_environment();
extern int _configure_narrow_argv(int);
extern char *_get_narrow_winmain_command_line();
#else // _UNICODE
extern int _initialize_wide_environment();
extern wchar_t **_get_initial_wide_environment();
extern int _configure_wide_argv(int);
extern wchar_t *_get_wide_winmain_command_line();
#endif

#else // MSVCRT_VERSION < 140

Expand All @@ -107,55 +120,91 @@ extern char *_get_narrow_winmain_command_line();
* it as a dummy, with a declared size of zero in its first and only field).
*/
typedef struct _startupinfo { int mode; } _startupinfo;
extern void __getmainargs( int *argc, char ***argv, char ***penv, int glob, _startupinfo *info );

#ifndef _UNICODE
extern int __getmainargs(int *argc, char ***argv, char ***penv, int glob, _startupinfo *info);
#else
extern int __wgetmainargs(int *argc, wchar_t ***argv, wchar_t ***penv, int glob, _startupinfo *info);
#endif

#endif // MSVCRT_VERSION < 140

/* The function mainCRTStartup() is the entry point for all
* console/desktop programs.
*/
#if _APPTYPE == __CONSOLE_APP
#ifndef _UNICODE
void mainCRTStartup(void)
#else
#else
void wmainCRTStartup(void)
#endif
#else // desktop app
#ifndef _UNICODE
void WinMainCRTStartup(void)
#else
void wWinMainCRTStartup(void)
#endif
#endif
{
int nRet;
__set_app_type(_APPTYPE);
__ref_oldnames = 0; // drag in alternate definitions

#if MSVCRT_VERSION >= 140 // UCRT
#ifndef _UNICODE
_configure_narrow_argv(_crt_argv_unexpanded_arguments);
_initialize_narrow_environment();
char **envp = _get_initial_narrow_environment();
#else
#else
_configure_wide_argv(_crt_argv_unexpanded_arguments);
_initialize_wide_environment();
wchar_t **wenvp = _get_initial_wide_environment();
#endif
#else // MSVCRT_VERSION < 140
/* The MSVCRT.DLL start-up hook requires this invocation
* protocol...
*/
char **envp = NULL;
_startupinfo start_info = { 0 };
#ifndef _UNICODE
char **envp = NULL;
__getmainargs(&__argc, &__argv, &envp, 0, &start_info);
#endif
#else
wchar_t **wenvp = NULL;
__wgetmainargs(&__argc, &__wargv, &wenvp, 0, &start_info);
#endif
#endif // MSVCRT_VERSION < 140

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

#if _APPTYPE == __CONSOLE_APP
#ifndef _UNICODE
nRet = main(__argc, __argv, envp);
#else
#else
nRet = wmain(__argc, __wargv, wenvp);
#endif
#else // desktop app
{
STARTUPINFOA startupInfo;
GetStartupInfoA(&startupInfo);
int showWindowMode = startupInfo.dwFlags & STARTF_USESHOWWINDOW
? startupInfo.wShowWindow : SW_SHOWDEFAULT;
#if MSVCRT_VERSION >= 140 // UCRT
#ifndef _UNICODE
#if MSVCRT_VERSION >= 140 // UCRT
LPSTR lpszCommandLine = _get_narrow_winmain_command_line();
#else
#else
LPSTR lpszCommandLine = GetCommandLineA();
#endif
#endif
nRet = WinMain((HINSTANCE)&__ImageBase, NULL, lpszCommandLine, showWindowMode);
#else // _UNICODE
#if MSVCRT_VERSION >= 140 // UCRT
LPWSTR lpszCommandLine = _get_wide_winmain_command_line();
#else
LPWSTR lpszCommandLine = GetCommandLineW();
#endif
nRet = wWinMain((HINSTANCE)&__ImageBase, NULL, lpszCommandLine, showWindowMode);
#endif
}
#endif
#endif // desktop app

term_atexit();
_initterm(__xp_a, __xp_z);
Expand Down