[PATCH v4 0/8] MR9027: winegcc: Force subsystem version to 5.2 on both Clang and MinGW.
This would hopefully fix some comctl32 test failures which started happening after I changed my nightly winetest runs to build Wine with Clang. -- v4: winegcc: Force default subsystem version to 6.0. user32/tests: Force console subsystem version 5.2. quartz/tests: Force console subsystem version 5.2. dxgi/tests: Force console subsystem version 5.2. comctl32/tests: Force console subsystem version 5.2. winegcc: Set the default subsystem to console. winegcc: Consistently use the subsystem option with Clang and MinGW. winegcc: Support subsystem version number in link.exe-style cmdline. https://gitlab.winehq.org/wine/wine/-/merge_requests/9027
From: Rémi Bernon <rbernon(a)codeweavers.com> --- tools/winegcc/winegcc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 7322feaaf80..aed4f28616c 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -496,6 +496,7 @@ static struct strarray get_link_args( const char *output_name ) { struct strarray link_args = get_translator(); struct strarray flags = empty_strarray; + char *version; strarray_addall( &link_args, linker_args ); @@ -601,7 +602,11 @@ static struct strarray get_link_args( const char *output_name ) if (entry_point) strarray_add( &flags, strmake( "-Wl,-entry:%s", entry_point )); if (subsystem) - strarray_add( &flags, strmake("-Wl,-subsystem:%s", subsystem )); + { + if ((version = strchr( subsystem, ':' ))) subsystem = strmake( "%.*s,%s", (int)(version - subsystem), subsystem, version + 1 ); + strarray_add( &flags, "-Xlinker" ); + strarray_add( &flags, strmake( "-subsystem:%s", subsystem ) ); + } else strarray_add( &flags, strmake("-Wl,-subsystem:%s", is_gui_app ? "windows" : "console" )); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9027
From: Rémi Bernon <rbernon(a)codeweavers.com> Instead of the -mwindows / -mconsole flags with MinGW. --- tools/winegcc/winegcc.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index aed4f28616c..d98c0e18ce3 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -170,7 +170,6 @@ enum file_type { file_na, file_other, file_obj, file_res, file_rc, file_arh, fil static bool is_pe; static bool is_static; static bool is_shared; -static bool is_gui_app; static bool is_unicode_app; static bool is_win16_app; static bool is_arm64x; @@ -542,7 +541,6 @@ static struct strarray get_link_args( const char *output_name ) strarray_add( &flags, "-shared" ); strarray_add( &flags, "-Wl,--kill-at" ); } - else strarray_add( &flags, is_gui_app ? "-mwindows" : "-mconsole" ); if (is_unicode_app) strarray_add( &flags, "-municode" ); if (subsystem) strarray_add( &flags, strmake("-Wl,--subsystem,%s", subsystem )); @@ -607,8 +605,6 @@ static struct strarray get_link_args( const char *output_name ) strarray_add( &flags, "-Xlinker" ); strarray_add( &flags, strmake( "-subsystem:%s", subsystem ) ); } - else - strarray_add( &flags, strmake("-Wl,-subsystem:%s", is_gui_app ? "windows" : "console" )); STRARRAY_FOR_EACH( file, &output_debug_files ) { @@ -1142,13 +1138,14 @@ static void build_spec_obj( const char *spec_file, const char *output_file, strarray_add(&spec_args, output_name); } - if (!is_shared) + if (subsystem) { - strarray_add(&spec_args, "--subsystem"); - strarray_add(&spec_args, is_gui_app ? "windows" : "console"); - if (large_address_aware) strarray_add( &spec_args, "--large-address-aware" ); + strarray_add( &spec_args, "--subsystem" ); + strarray_add( &spec_args, subsystem ); } + if (!is_shared && large_address_aware) strarray_add( &spec_args, "--large-address-aware" ); + if (target.platform == PLATFORM_WINDOWS && target.cpu == CPU_i386) strarray_add(&spec_args, "--safeseh"); @@ -1158,12 +1155,6 @@ static void build_spec_obj( const char *spec_file, const char *output_file, strarray_add(&spec_args, entry_point); } - if (subsystem) - { - strarray_add(&spec_args, "--subsystem"); - strarray_add(&spec_args, subsystem); - } - if (!is_pe) STRARRAY_FOR_EACH( imp, &delayimports ) strarray_add(&spec_args, strmake("-d%s", imp)); strarray_addall( &spec_args, resources ); @@ -1323,7 +1314,7 @@ static void build(struct strarray input_files, const char *output) if (!wine_objdir && !nodefaultlibs) { - if (is_gui_app) + if (subsystem && !strncmp( subsystem, "windows", 7 )) { add_library(lib_dirs, &files, "shell32"); add_library(lib_dirs, &files, "comdlg32"); @@ -1781,12 +1772,12 @@ int main(int argc, char **argv) } else if (strcmp("-mwindows", args.str[i]) == 0) { - is_gui_app = true; + if (!subsystem || strncmp( subsystem, "windows", 7 )) subsystem = "windows"; raw_compiler_arg = 0; } else if (strcmp("-mconsole", args.str[i]) == 0) { - is_gui_app = false; + if (!subsystem || strncmp( subsystem, "console", 7 )) subsystem = "console"; raw_compiler_arg = 0; } else if (strcmp("-municode", args.str[i]) == 0) @@ -1861,6 +1852,7 @@ int main(int argc, char **argv) { is_shared = true; raw_compiler_arg = raw_linker_arg = 0; + if (!subsystem) subsystem = "console"; } else if (strcmp("-s", args.str[i]) == 0) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9027
From: Rémi Bernon <rbernon(a)codeweavers.com> --- tools/winegcc/winegcc.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index d98c0e18ce3..8f5b7df71a1 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -543,7 +543,7 @@ static struct strarray get_link_args( const char *output_name ) } if (is_unicode_app) strarray_add( &flags, "-municode" ); - if (subsystem) strarray_add( &flags, strmake("-Wl,--subsystem,%s", subsystem )); + strarray_add( &flags, strmake( "-Wl,--subsystem,%s", subsystem ) ); strarray_add( &flags, "-Wl,--exclude-all-symbols" ); strarray_add( &flags, "-Wl,--nxcompat" ); @@ -599,12 +599,9 @@ static struct strarray get_link_args( const char *output_name ) if (entry_point) strarray_add( &flags, strmake( "-Wl,-entry:%s", entry_point )); - if (subsystem) - { - if ((version = strchr( subsystem, ':' ))) subsystem = strmake( "%.*s,%s", (int)(version - subsystem), subsystem, version + 1 ); - strarray_add( &flags, "-Xlinker" ); - strarray_add( &flags, strmake( "-subsystem:%s", subsystem ) ); - } + if ((version = strchr( subsystem, ':' ))) subsystem = strmake( "%.*s,%s", (int)(version - subsystem), subsystem, version + 1 ); + strarray_add( &flags, "-Xlinker" ); + strarray_add( &flags, strmake( "-subsystem:%s", subsystem ) ); STRARRAY_FOR_EACH( file, &output_debug_files ) { @@ -1138,11 +1135,8 @@ static void build_spec_obj( const char *spec_file, const char *output_file, strarray_add(&spec_args, output_name); } - if (subsystem) - { - strarray_add( &spec_args, "--subsystem" ); - strarray_add( &spec_args, subsystem ); - } + strarray_add( &spec_args, "--subsystem" ); + strarray_add( &spec_args, subsystem ); if (!is_shared && large_address_aware) strarray_add( &spec_args, "--large-address-aware" ); @@ -1314,7 +1308,7 @@ static void build(struct strarray input_files, const char *output) if (!wine_objdir && !nodefaultlibs) { - if (subsystem && !strncmp( subsystem, "windows", 7 )) + if (!strncmp( subsystem, "windows", 7 )) { add_library(lib_dirs, &files, "shell32"); add_library(lib_dirs, &files, "comdlg32"); @@ -1344,7 +1338,7 @@ static void build(struct strarray input_files, const char *output) /* set default entry point, if needed */ if (!entry_point) { - if (subsystem && !strcmp( subsystem, "native" )) + if (!strcmp( subsystem, "native" )) entry_point = (is_pe && target.cpu == CPU_i386) ? "DriverEntry(a)8" : "DriverEntry"; else if (use_msvcrt && !is_shared && !is_win16_app) entry_point = is_unicode_app ? "wmainCRTStartup" : "mainCRTStartup"; @@ -1627,6 +1621,7 @@ int main(int argc, char **argv) includedir = get_includedir( bindir ); target = init_argv0_target( argv[0] ); path_dirs = strarray_frompath( getenv( "PATH" )); + subsystem = "console"; /* setup tmp file removal at exit */ atexit(clean_temp_files); @@ -1772,12 +1767,12 @@ int main(int argc, char **argv) } else if (strcmp("-mwindows", args.str[i]) == 0) { - if (!subsystem || strncmp( subsystem, "windows", 7 )) subsystem = "windows"; + if (strncmp( subsystem, "windows", 7 )) subsystem = "windows"; raw_compiler_arg = 0; } else if (strcmp("-mconsole", args.str[i]) == 0) { - if (!subsystem || strncmp( subsystem, "console", 7 )) subsystem = "console"; + if (strncmp( subsystem, "console", 7 )) subsystem = "console"; raw_compiler_arg = 0; } else if (strcmp("-municode", args.str[i]) == 0) @@ -1852,7 +1847,6 @@ int main(int argc, char **argv) { is_shared = true; raw_compiler_arg = raw_linker_arg = 0; - if (!subsystem) subsystem = "console"; } else if (strcmp("-s", args.str[i]) == 0) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9027
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/comctl32/tests/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/comctl32/tests/Makefile.in b/dlls/comctl32/tests/Makefile.in index ee7fe6527fe..9c17acd77d7 100644 --- a/dlls/comctl32/tests/Makefile.in +++ b/dlls/comctl32/tests/Makefile.in @@ -1,5 +1,6 @@ TESTDLL = comctl32.dll IMPORTS = ole32 user32 gdi32 advapi32 imm32 uxtheme oleacc oleaut32 +EXTRADLLFLAGS = -Wl,--subsystem,console:5.2 SOURCES = \ animate.c \ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9027
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/dxgi/tests/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/dxgi/tests/Makefile.in b/dlls/dxgi/tests/Makefile.in index 43c7a55a88c..add3803ca40 100644 --- a/dlls/dxgi/tests/Makefile.in +++ b/dlls/dxgi/tests/Makefile.in @@ -1,5 +1,6 @@ TESTDLL = dxgi.dll IMPORTS = d3d10_1 dxgi user32 +EXTRADLLFLAGS = -Wl,--subsystem,console:5.2 SOURCES = \ dxgi.c -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9027
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/quartz/tests/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/quartz/tests/Makefile.in b/dlls/quartz/tests/Makefile.in index c3b96272fbf..1dd25efd19f 100644 --- a/dlls/quartz/tests/Makefile.in +++ b/dlls/quartz/tests/Makefile.in @@ -1,5 +1,6 @@ TESTDLL = quartz.dll IMPORTS = strmbase advapi32 d3d9 ddraw dsound msdmo msvfw32 ole32 oleaut32 user32 uuid winmm +EXTRADLLFLAGS = -Wl,--subsystem,console:5.2 SOURCES = \ acmwrapper.c \ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9027
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/user32/tests/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index bff53de7713..4bc7172bdb9 100644 --- a/dlls/user32/tests/Makefile.in +++ b/dlls/user32/tests/Makefile.in @@ -1,5 +1,6 @@ TESTDLL = user32.dll IMPORTS = user32 gdi32 advapi32 hid imm32 setupapi +EXTRADLLFLAGS = -Wl,--subsystem,console:5.2 testdll_IMPORTS = user32 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9027
From: Rémi Bernon <rbernon(a)codeweavers.com> Modern windows uses 10.0, but compiling a program with this version prevents it from running on Windows with STATUS_INVALID_IMAGE_FORMAT. --- tools/winegcc/winegcc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 8f5b7df71a1..a837c204a52 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -1621,7 +1621,7 @@ int main(int argc, char **argv) includedir = get_includedir( bindir ); target = init_argv0_target( argv[0] ); path_dirs = strarray_frompath( getenv( "PATH" )); - subsystem = "console"; + subsystem = "console:6.0"; /* setup tmp file removal at exit */ atexit(clean_temp_files); @@ -1767,12 +1767,12 @@ int main(int argc, char **argv) } else if (strcmp("-mwindows", args.str[i]) == 0) { - if (strncmp( subsystem, "windows", 7 )) subsystem = "windows"; + if (strncmp( subsystem, "windows", 7 )) subsystem = "windows:6.0"; raw_compiler_arg = 0; } else if (strcmp("-mconsole", args.str[i]) == 0) { - if (strncmp( subsystem, "console", 7 )) subsystem = "console"; + if (strncmp( subsystem, "console", 7 )) subsystem = "console:6.0"; raw_compiler_arg = 0; } else if (strcmp("-municode", args.str[i]) == 0) @@ -1903,6 +1903,8 @@ int main(int argc, char **argv) if (!strcmp(Wl.str[j], "--subsystem") && j < Wl.count - 1) { subsystem = xstrdup( Wl.str[++j] ); + if (!strcmp( subsystem, "windows" ) || !strcmp( subsystem, "console" )) + subsystem = strmake( "%s:6.0", subsystem ); continue; } if (!strcmp(Wl.str[j], "--entry") && j < Wl.count - 1) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9027
v3: Reorder commits a bit, fix the typo. Override subsystem from -mwindows / -mconsole only if it was different, keep the previous value (and its eventual version) otherwise. Force default version to 6.0. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9027#note_119196
On Tue Oct 21 11:49:26 2025 +0000, Rémi Bernon wrote:
Then what if command-line is like: `--subsystem=native:4.0 -mwindows`? Shouldn't `-mwindows` take over any previously set subsystem (which it does already) *and* its version? Right, I forgot there’s a compiler driver involved. On mingw, `-mwindows` and `-mconsole` are effectively ignored in such case (they’re passed to the linker as `--subsystem`, but since that always appears before `-Wl,...` arguments, it’s overridden when the linker processes them). While not very important, it would be easy to keep compatibility by preserving the existing command-line parsing and using `is_gui_app` to set the default subsystem right after that.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9027#note_119197
participants (2)
-
Jacek Caban (@jacek) -
Rémi Bernon