Skip to content
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
68 changes: 68 additions & 0 deletions lib/libc/mingw/crt/crtexewin.c
Original file line number Diff line number Diff line change
@@ -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);
}
14 changes: 14 additions & 0 deletions lib/libc/mingw/crt/ucrtexewin.c
Original file line number Diff line number Diff line change
@@ -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"
7 changes: 7 additions & 0 deletions lib/std/Build/Step/Compile.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down Expand Up @@ -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}),
Expand Down
7 changes: 5 additions & 2 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down
9 changes: 8 additions & 1 deletion src/clang_options_data.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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=",
Expand Down
2 changes: 1 addition & 1 deletion src/link/Coff/lld.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 => "",
Expand Down
7 changes: 7 additions & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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});
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -5792,6 +5798,7 @@ pub const ClangArgIterator = struct {
install_name,
undefined,
force_load_objc,
mingw_unicode_entry_point,
};

const Args = struct {
Expand Down
40 changes: 18 additions & 22 deletions src/mingw.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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{
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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);
},
}
}
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand Down
4 changes: 4 additions & 0 deletions test/standalone.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
Loading