srctree

Andrew Kelley parent c808e546 bad9efbc 3661133f
Merge pull request #19399 from ypsvlq/mingw

mingw: support -municode
filename was Deleted added: 246, removed: 41, total 205
@@ -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 <windows.h>
#include <tchar.h>
#include <corecrt_startup.h>
 
#ifndef _UNICODE
#include <mbctype.h>
#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);
}
 
filename was Deleted added: 246, removed: 41, total 205
@@ -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"
 
lib/std/Build/Step/Compile.zig added: 246, removed: 41, total 205
@@ -161,6 +161,9 @@ dll_export_fns: ?bool = null,
 
subsystem: ?std.Target.SubSystem = null,
 
/// (Windows) When targeting the MinGW ABI, use the unicode entry point (wmain/wWinMain)
mingw_unicode_entry_point: bool = false,
 
/// How the linker must handle the entry point of the executable.
entry: Entry = .default,
 
@@ -1583,6 +1586,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
});
}
 
if (self.mingw_unicode_entry_point) {
try zig_args.append("-municode");
}
 
if (self.error_limit) |err_limit| try zig_args.appendSlice(&.{
"--error-limit",
b.fmt("{}", .{err_limit}),
 
src/Compilation.zig added: 246, removed: 41, total 205
@@ -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.
 
src/clang_options_data.zig added: 246, removed: 41, total 205
@@ -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=",
 
src/link/Coff/lld.zig added: 246, removed: 41, total 205
@@ -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 => "",
 
src/main.zig added: 246, removed: 41, total 205
@@ -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] <arch><sub>-<os>-<abi> 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 {
 
src/mingw.zig added: 246, removed: 41, total 205
@@ -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",
 
test/standalone.zig added: 246, removed: 41, total 205
@@ -195,6 +195,10 @@ pub const build_cases = [_]BuildCase{
.build_root = "test/standalone/windows_resources",
.import = @import("standalone/windows_resources/build.zig"),
},
.{
.build_root = "test/standalone/windows_entry_points",
.import = @import("standalone/windows_entry_points/build.zig"),
},
.{
.build_root = "test/standalone/windows_spawn",
.import = @import("standalone/windows_spawn/build.zig"),
 
filename was Deleted added: 246, removed: 41, total 205
@@ -0,0 +1,68 @@
const std = @import("std");
 
pub fn build(b: *std.Build) void {
const test_step = b.step("test", "Test it");
b.default_step = test_step;
 
const target = b.resolveTargetQuery(.{
.cpu_arch = .x86_64,
.os_tag = .windows,
.abi = .gnu,
});
 
{
const exe = b.addExecutable(.{
.name = "main",
.target = target,
.optimize = .Debug,
.link_libc = true,
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" } });
 
_ = exe.getEmittedBin();
test_step.dependOn(&exe.step);
}
 
{
const exe = b.addExecutable(.{
.name = "wmain",
.target = target,
.optimize = .Debug,
.link_libc = true,
});
exe.mingw_unicode_entry_point = true;
exe.addCSourceFile(.{ .file = .{ .path = "wmain.c" } });
 
_ = exe.getEmittedBin();
test_step.dependOn(&exe.step);
}
 
{
const exe = b.addExecutable(.{
.name = "winmain",
.target = target,
.optimize = .Debug,
.link_libc = true,
});
// Note: `exe.subsystem = .Windows;` is not necessary
exe.addCSourceFile(.{ .file = .{ .path = "winmain.c" } });
 
_ = exe.getEmittedBin();
test_step.dependOn(&exe.step);
}
 
{
const exe = b.addExecutable(.{
.name = "wwinmain",
.target = target,
.optimize = .Debug,
.link_libc = true,
});
exe.mingw_unicode_entry_point = true;
// Note: `exe.subsystem = .Windows;` is not necessary
exe.addCSourceFile(.{ .file = .{ .path = "wwinmain.c" } });
 
_ = exe.getEmittedBin();
test_step.dependOn(&exe.step);
}
}
 
filename was Deleted added: 246, removed: 41, total 205
@@ -0,0 +1,6 @@
#include <stdio.h>
 
int main(int argc, char *argv[ ], char *envp[ ]) {
printf("hello from main\n");
return 0;
}
No newline at end of file
 
filename was Deleted added: 246, removed: 41, total 205
@@ -0,0 +1,7 @@
#include <windows.h>
#include <stdio.h>
 
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
printf("hello from WinMain\n");
return 0;
}
No newline at end of file
 
filename was Deleted added: 246, removed: 41, total 205
@@ -0,0 +1,7 @@
#include <stdio.h>
#include <windows.h>
 
int wmain(int argc, wchar_t *argv[ ], wchar_t *envp[ ]) {
printf("hello from wmain\n");
return 0;
}
No newline at end of file
 
filename was Deleted added: 246, removed: 41, total 205
@@ -0,0 +1,7 @@
#include <windows.h>
#include <stdio.h>
 
int APIENTRY wWinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PWSTR cmdline, int cmdshow) {
printf("hello from wWinMain\n");
return 0;
}
No newline at end of file
 
tools/update_clang_options.zig added: 246, removed: 41, total 205
@@ -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{};