diff --git a/lib/libc/mingw/crt/crtexewin.c b/lib/libc/mingw/crt/crtexewin.c new file mode 100644 index 0000000000..26179fa905 --- /dev/null +++ b/lib/libc/mingw/crt/crtexewin.c @@ -0,0 +1,68 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#include +#include +#include + +#ifndef _UNICODE +#include +#endif + +#define SPACECHAR _T(' ') +#define DQUOTECHAR _T('\"') + +extern IMAGE_DOS_HEADER __ImageBase; + +int _tmain (int, _TCHAR **, _TCHAR **); +int _tmain (int __UNUSED_PARAM(argc), + _TCHAR ** __UNUSED_PARAM(argv), + _TCHAR ** __UNUSED_PARAM(envp)) +{ + HINSTANCE hInstance; + _TCHAR *lpCmdLine; + DWORD nShowCmd; + + hInstance = (HINSTANCE) &__ImageBase; + +#ifdef _UNICODE + lpCmdLine = _wcmdln; +#else + lpCmdLine = _acmdln; +#endif + if (lpCmdLine) + { + BOOL inDoubleQuote = FALSE; + while (*lpCmdLine > SPACECHAR || (*lpCmdLine && inDoubleQuote)) + { + if (*lpCmdLine == DQUOTECHAR) + inDoubleQuote = !inDoubleQuote; +#ifndef _UNICODE + if (_ismbblead (*lpCmdLine)) + { + if (lpCmdLine[1]) + ++lpCmdLine; + } +#endif + ++lpCmdLine; + } + while (*lpCmdLine && (*lpCmdLine <= SPACECHAR)) + lpCmdLine++; + } + else + lpCmdLine = _TEXT(""); + + { + STARTUPINFO StartupInfo; + memset (&StartupInfo, 0, sizeof (STARTUPINFO)); + GetStartupInfo (&StartupInfo); + if (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) + nShowCmd = StartupInfo.wShowWindow; + else + nShowCmd = SW_SHOWDEFAULT; + } + + return _tWinMain (hInstance, NULL, lpCmdLine, nShowCmd); +} diff --git a/lib/libc/mingw/crt/ucrtexewin.c b/lib/libc/mingw/crt/ucrtexewin.c new file mode 100644 index 0000000000..e3b7d4ddc2 --- /dev/null +++ b/lib/libc/mingw/crt/ucrtexewin.c @@ -0,0 +1,14 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#ifndef UNICODE +#define UNICODE +#endif +#ifndef _UNICODE +#define _UNICODE +#endif + +#include "crtexewin.c" diff --git a/src/Compilation.zig b/src/Compilation.zig index 5bbca51ede..003ecb8e28 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -173,6 +173,7 @@ global_cache_directory: Directory, libc_include_dir_list: []const []const u8, libc_framework_dir_list: []const []const u8, rc_includes: RcIncludes, +mingw_unicode_entry_point: bool, thread_pool: *ThreadPool, /// Populated when we build the libc++ static library. A Job to build this is placed in the queue @@ -758,7 +759,7 @@ pub const MiscTask = enum { @"mingw-w64 crt2.o", @"mingw-w64 dllcrt2.o", - @"mingw-w64 mingwex.lib", + @"mingw-w64 mingw32.lib", }; pub const MiscError = struct { @@ -1101,6 +1102,7 @@ pub const CreateOptions = struct { test_name_prefix: ?[]const u8 = null, test_runner_path: ?[]const u8 = null, subsystem: ?std.Target.SubSystem = null, + mingw_unicode_entry_point: bool = false, /// (Zig compiler development) Enable dumping linker's state as JSON. enable_link_snapshots: bool = false, /// (Darwin) Install name of the dylib @@ -1427,6 +1429,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil .libc_include_dir_list = libc_dirs.libc_include_dir_list, .libc_framework_dir_list = libc_dirs.libc_framework_dir_list, .rc_includes = options.rc_includes, + .mingw_unicode_entry_point = options.mingw_unicode_entry_point, .thread_pool = options.thread_pool, .clang_passthrough_mode = options.clang_passthrough_mode, .clang_preprocessor_mode = options.clang_preprocessor_mode, @@ -1768,7 +1771,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil const crt_job: Job = .{ .mingw_crt_file = if (is_dyn_lib) .dllcrt2_o else .crt2_o }; try comp.work_queue.ensureUnusedCapacity(2); - comp.work_queue.writeItemAssumeCapacity(.{ .mingw_crt_file = .mingwex_lib }); + comp.work_queue.writeItemAssumeCapacity(.{ .mingw_crt_file = .mingw32_lib }); comp.work_queue.writeItemAssumeCapacity(crt_job); // When linking mingw-w64 there are some import libs we always need. diff --git a/src/clang_options_data.zig b/src/clang_options_data.zig index 0137d2cbfc..0d5bab676c 100644 --- a/src/clang_options_data.zig +++ b/src/clang_options_data.zig @@ -6895,7 +6895,14 @@ joinpd1("mdouble="), joinpd1("mfpmath="), joinpd1("mhwmult="), joinpd1("mthreads"), -joinpd1("municode"), +.{ + .name = "municode", + .syntax = .joined, + .zig_equivalent = .mingw_unicode_entry_point, + .pd1 = true, + .pd2 = false, + .psl = false, +}, joinpd1("mwindows"), .{ .name = "offload=", diff --git a/src/link/Coff/lld.zig b/src/link/Coff/lld.zig index 1543415d0e..cf9c06a70f 100644 --- a/src/link/Coff/lld.zig +++ b/src/link/Coff/lld.zig @@ -409,7 +409,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) try argv.append(try comp.get_libc_crt_file(arena, "crt2.obj")); } - try argv.append(try comp.get_libc_crt_file(arena, "mingwex.lib")); + try argv.append(try comp.get_libc_crt_file(arena, "mingw32.lib")); } else { const lib_str = switch (comp.config.link_mode) { .dynamic => "", diff --git a/src/main.zig b/src/main.zig index c60cc100ab..2edc3864c6 100644 --- a/src/main.zig +++ b/src/main.zig @@ -450,6 +450,7 @@ const usage_build_generic = \\ -fstructured-cfg (SPIR-V) force SPIR-V kernels to use structured control flow \\ -fno-structured-cfg (SPIR-V) force SPIR-V kernels to not use structured control flow \\ -mexec-model=[value] (WASI) Execution model + \\ -municode (Windows) Use wmain/wWinMain as entry point \\ \\Per-Module Compile Options: \\ -target [name] -- see the targets command @@ -893,6 +894,7 @@ fn buildOutputType( var subsystem: ?std.Target.SubSystem = null; var major_subsystem_version: ?u16 = null; var minor_subsystem_version: ?u16 = null; + var mingw_unicode_entry_point: bool = false; var enable_link_snapshots: bool = false; var debug_incremental: bool = false; var install_name: ?[]const u8 = null; @@ -1686,6 +1688,8 @@ fn buildOutputType( } } else if (mem.startsWith(u8, arg, "-mexec-model=")) { create_module.opts.wasi_exec_model = parseWasiExecModel(arg["-mexec-model=".len..]); + } else if (mem.eql(u8, arg, "-municode")) { + mingw_unicode_entry_point = true; } else { fatal("unrecognized parameter: '{s}'", .{arg}); } @@ -2091,6 +2095,7 @@ fn buildOutputType( try force_undefined_symbols.put(arena, it.only_arg, {}); }, .force_load_objc => force_load_objc = true, + .mingw_unicode_entry_point => mingw_unicode_entry_point = true, .weak_library => try create_module.system_libs.put(arena, it.only_arg, .{ .needed = false, .weak = true, @@ -3229,6 +3234,7 @@ fn buildOutputType( .rc_source_files = create_module.rc_source_files.items, .manifest_file = manifest_file, .rc_includes = rc_includes, + .mingw_unicode_entry_point = mingw_unicode_entry_point, .link_objects = create_module.link_objects.items, .framework_dirs = create_module.framework_dirs.items, .frameworks = resolved_frameworks.items, @@ -5792,6 +5798,7 @@ pub const ClangArgIterator = struct { install_name, undefined, force_load_objc, + mingw_unicode_entry_point, }; const Args = struct { diff --git a/src/mingw.zig b/src/mingw.zig index b711ad7515..803c0f9367 100644 --- a/src/mingw.zig +++ b/src/mingw.zig @@ -13,7 +13,7 @@ const Cache = std.Build.Cache; pub const CRTFile = enum { crt2_o, dllcrt2_o, - mingwex_lib, + mingw32_lib, }; pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progress.Node) !void { @@ -28,14 +28,9 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr .crt2_o => { var args = std.ArrayList([]const u8).init(arena); try add_cc_args(comp, arena, &args); - try args.appendSlice(&[_][]const u8{ - // Prevents warning: 'used' attribute ignored on a non-definition declaration - // pointing at extern _CRTALLOC - "-Wno-ignored-attributes", - // Uncommenting this makes mingw-w64 look for wmain instead of main. - //"-DUNICODE", - //"-D_UNICODE", - }); + if (comp.mingw_unicode_entry_point) { + try args.appendSlice(&.{ "-DUNICODE", "-D_UNICODE" }); + } var files = [_]Compilation.CSourceFile{ .{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ @@ -63,12 +58,12 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &files); }, - .mingwex_lib => { + .mingw32_lib => { var args = std.ArrayList([]const u8).init(arena); try add_cc_args(comp, arena, &args); var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); - for (mingwex_generic_src) |dep| { + for (mingw32_generic_src) |dep| { try c_source_files.append(.{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", dep, @@ -79,7 +74,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr } const target = comp.getTarget(); if (target.cpu.arch == .x86 or target.cpu.arch == .x86_64) { - for (mingwex_x86_src) |dep| { + for (mingw32_x86_src) |dep| { try c_source_files.append(.{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", dep, @@ -89,7 +84,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr }); } if (target.cpu.arch == .x86) { - for (mingwex_x86_32_src) |dep| { + for (mingw32_x86_32_src) |dep| { try c_source_files.append(.{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", dep, @@ -100,7 +95,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr } } } else if (target.cpu.arch.isARM()) { - for (mingwex_arm32_src) |dep| { + for (mingw32_arm32_src) |dep| { try c_source_files.append(.{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", dep, @@ -110,7 +105,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr }); } } else if (target.cpu.arch.isAARCH64()) { - for (mingwex_arm64_src) |dep| { + for (mingw32_arm64_src) |dep| { try c_source_files.append(.{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", dep, @@ -122,7 +117,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr } else { @panic("unsupported arch"); } - return comp.build_crt_file("mingwex", .Lib, .@"mingw-w64 mingwex.lib", prog_node, c_source_files.items); + return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items); }, } } @@ -389,14 +384,16 @@ fn findDef( return error.FileNotFound; } -const mingwex_generic_src = [_][]const u8{ +const mingw32_generic_src = [_][]const u8{ // mingw32 + "crt" ++ path.sep_str ++ "crtexewin.c", "crt" ++ path.sep_str ++ "dll_argv.c", "crt" ++ path.sep_str ++ "gccmain.c", "crt" ++ path.sep_str ++ "natstart.c", "crt" ++ path.sep_str ++ "pseudo-reloc-list.c", "crt" ++ path.sep_str ++ "wildcard.c", "crt" ++ path.sep_str ++ "charmax.c", + "crt" ++ path.sep_str ++ "ucrtexewin.c", "crt" ++ path.sep_str ++ "dllargv.c", "crt" ++ path.sep_str ++ "_newmode.c", "crt" ++ path.sep_str ++ "tlssup.c", @@ -814,7 +811,7 @@ const mingwex_generic_src = [_][]const u8{ "libsrc" ++ path.sep_str ++ "activeds-uuid.c", }; -const mingwex_x86_src = [_][]const u8{ +const mingw32_x86_src = [_][]const u8{ // mingwex "math" ++ path.sep_str ++ "cbrtl.c", "math" ++ path.sep_str ++ "erfl.c", @@ -873,8 +870,7 @@ const mingwex_x86_src = [_][]const u8{ "math" ++ path.sep_str ++ "nexttowardf.c", }; -const mingwex_x86_32_src = [_][]const u8{ - // ucrtbase +const mingw32_x86_32_src = [_][]const u8{ "math" ++ path.sep_str ++ "coshf.c", "math" ++ path.sep_str ++ "expf.c", "math" ++ path.sep_str ++ "log10f.c", @@ -896,7 +892,7 @@ const mingwex_x86_32_src = [_][]const u8{ "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "tanf.c", }; -const mingwex_arm32_src = [_][]const u8{ +const mingw32_arm32_src = [_][]const u8{ "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "ldexpl.c", "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "_chgsignl.S", "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "s_rint.c", @@ -905,7 +901,7 @@ const mingwex_arm32_src = [_][]const u8{ "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "sincosf.S", }; -const mingwex_arm64_src = [_][]const u8{ +const mingw32_arm64_src = [_][]const u8{ "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "ldexpl.c", "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "_chgsignl.S", "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rint.c", diff --git a/tools/update_clang_options.zig b/tools/update_clang_options.zig index e632e18854..8031e6dcdb 100644 --- a/tools/update_clang_options.zig +++ b/tools/update_clang_options.zig @@ -532,6 +532,10 @@ const known_options = [_]KnownOpt{ .name = "ObjC", .ident = "force_load_objc", }, + .{ + .name = "municode", + .ident = "mingw_unicode_entry_point", + }, }; const blacklisted_options = [_][]const u8{};