| author | |
| committer | |
| log | ba41be67f02158df964543d21b30c83f1b17550d |
| tree | 79532b92c9309e669fc7c96420e1efe9b7dd1f44 |
| parent | 41b588547cd49673ff632ed0fc3210c76ff48b42 |
6 files changed, 43 insertions(+), 24 deletions(-)
example/hello_world/hello_windows.zig created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | use @import("std").os.windows; | |
| 2 | ||
| 3 | export fn WinMain(hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: PWSTR, nCmdShow: INT) -> INT { | |
| 4 | _ = MessageBoxA(null, c"hello", c"title", 0); | |
| 5 | return 0; | |
| 6 | } |
src/all_types.hpp+1| ... | ... | @@ -1451,6 +1451,7 @@ struct CodeGen { |
| 1451 | 1451 | bool want_h_file; |
| 1452 | 1452 | bool have_pub_main; |
| 1453 | 1453 | bool have_c_main; |
| 1454 | bool have_winmain; | |
| 1454 | 1455 | bool have_pub_panic; |
| 1455 | 1456 | Buf *libc_lib_dir; |
| 1456 | 1457 | Buf *libc_static_lib_dir; |
src/analyze.cpp+6| ... | ... | @@ -3200,6 +3200,12 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a |
| 3200 | 3200 | g->have_c_main = true; |
| 3201 | 3201 | g->windows_subsystem_windows = false; |
| 3202 | 3202 | g->windows_subsystem_console = true; |
| 3203 | } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "WinMain") && | |
| 3204 | g->zig_target.os == ZigLLVM_Win32) | |
| 3205 | { | |
| 3206 | g->have_winmain = true; | |
| 3207 | g->windows_subsystem_windows = true; | |
| 3208 | g->windows_subsystem_console = false; | |
| 3203 | 3209 | } |
| 3204 | 3210 | |
| 3205 | 3211 | } |
src/codegen.cpp+1-1| ... | ... | @@ -5157,7 +5157,7 @@ static void gen_root_source(CodeGen *g) { |
| 5157 | 5157 | assert(g->root_out_name); |
| 5158 | 5158 | assert(g->out_type != OutTypeUnknown); |
| 5159 | 5159 | |
| 5160 | if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && !g->have_c_main && | |
| 5160 | if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && !g->have_c_main && !g->have_winmain && | |
| 5161 | 5161 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) |
| 5162 | 5162 | { |
| 5163 | 5163 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig"); |
src/link.cpp+23-22| ... | ... | @@ -398,7 +398,11 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 398 | 398 | //lj->args.append(get_libc_static_file(g, "crtbegin.o")); |
| 399 | 399 | } else { |
| 400 | 400 | lj->args.append("-NODEFAULTLIB"); |
| 401 | lj->args.append("-ENTRY:_start"); | |
| 401 | if (g->have_winmain) { | |
| 402 | lj->args.append("-ENTRY:WinMain"); | |
| 403 | } else { | |
| 404 | lj->args.append("-ENTRY:_start"); | |
| 405 | } | |
| 402 | 406 | } |
| 403 | 407 | |
| 404 | 408 | for (size_t i = 0; i < g->lib_dirs.length; i += 1) { |
| ... | ... | @@ -424,6 +428,7 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 424 | 428 | } |
| 425 | 429 | |
| 426 | 430 | Buf *def_contents = buf_alloc(); |
| 431 | ZigList<const char *> gen_lib_args = {0}; | |
| 427 | 432 | for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) { |
| 428 | 433 | LinkLib *link_lib = g->link_libs_list.at(lib_i); |
| 429 | 434 | if (buf_eql_str(link_lib->name, "c")) { |
| ... | ... | @@ -433,38 +438,34 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 433 | 438 | Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name)); |
| 434 | 439 | lj->args.append(buf_ptr(arg)); |
| 435 | 440 | } else { |
| 441 | buf_resize(def_contents, 0); | |
| 436 | 442 | buf_appendf(def_contents, "LIBRARY %s\nEXPORTS\n", buf_ptr(link_lib->name)); |
| 437 | 443 | for (size_t exp_i = 0; exp_i < link_lib->symbols.length; exp_i += 1) { |
| 438 | 444 | Buf *symbol_name = link_lib->symbols.at(exp_i); |
| 439 | 445 | buf_appendf(def_contents, "%s\n", buf_ptr(symbol_name)); |
| 440 | 446 | } |
| 441 | 447 | buf_appendf(def_contents, "\n"); |
| 442 | } | |
| 443 | } | |
| 444 | if (buf_len(def_contents) != 0) { | |
| 445 | Buf *def_path = buf_alloc(); | |
| 446 | os_path_join(g->cache_dir, buf_create_from_str("all.def"), def_path); | |
| 447 | os_write_file(def_path, def_contents); | |
| 448 | 448 | |
| 449 | Buf *all_lib_path = buf_alloc(); | |
| 450 | os_path_join(g->cache_dir, buf_create_from_str("all.lib"), all_lib_path); | |
| 449 | Buf *def_path = buf_alloc(); | |
| 450 | os_path_join(g->cache_dir, buf_sprintf("%s.def", buf_ptr(link_lib->name)), def_path); | |
| 451 | os_write_file(def_path, def_contents); | |
| 451 | 452 | |
| 452 | //Buf *dll_path = buf_alloc(); | |
| 453 | //os_path_join(g->cache_dir, buf_create_from_str("all.dll"), dll_path); | |
| 453 | Buf *generated_lib_path = buf_alloc(); | |
| 454 | os_path_join(g->cache_dir, buf_sprintf("%s.lib", buf_ptr(link_lib->name)), generated_lib_path); | |
| 454 | 455 | |
| 455 | ZigList<const char *> args = {0}; | |
| 456 | args.append("link"); | |
| 456 | gen_lib_args.resize(0); | |
| 457 | gen_lib_args.append("link"); | |
| 457 | 458 | |
| 458 | coff_append_machine_arg(g, &args); | |
| 459 | args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path)))); | |
| 460 | args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(all_lib_path)))); | |
| 461 | Buf diag = BUF_INIT; | |
| 462 | if (!ZigLLDLink(g->zig_target.oformat, args.items, args.length, &diag)) { | |
| 463 | fprintf(stderr, "%s\n", buf_ptr(&diag)); | |
| 464 | exit(1); | |
| 459 | coff_append_machine_arg(g, &gen_lib_args); | |
| 460 | gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path)))); | |
| 461 | gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path)))); | |
| 462 | Buf diag = BUF_INIT; | |
| 463 | if (!ZigLLDLink(g->zig_target.oformat, gen_lib_args.items, gen_lib_args.length, &diag)) { | |
| 464 | fprintf(stderr, "%s\n", buf_ptr(&diag)); | |
| 465 | exit(1); | |
| 466 | } | |
| 467 | lj->args.append(buf_ptr(generated_lib_path)); | |
| 465 | 468 | } |
| 466 | ||
| 467 | lj->args.append(buf_ptr(all_lib_path)); | |
| 468 | 469 | } |
| 469 | 470 | |
| 470 | 471 | if (g->libc_link_lib != nullptr) { |
std/os/windows/index.zig+6-1| ... | ... | @@ -39,6 +39,9 @@ pub extern "kernel32" stdcallcc fn WriteFile(in_hFile: HANDLE, in_lpBuffer: &con |
| 39 | 39 | |
| 40 | 40 | pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD); |
| 41 | 41 | |
| 42 | ||
| 43 | pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) -> c_int; | |
| 44 | ||
| 42 | 45 | pub const PROV_RSA_FULL = 1; |
| 43 | 46 | |
| 44 | 47 | pub const UNICODE = false; |
| ... | ... | @@ -46,13 +49,14 @@ pub const LPTSTR = if (unicode) LPWSTR else LPSTR; |
| 46 | 49 | pub const LPWSTR = &WCHAR; |
| 47 | 50 | pub const LPSTR = &CHAR; |
| 48 | 51 | pub const CHAR = u8; |
| 49 | ||
| 52 | pub const PWSTR = &WCHAR; | |
| 50 | 53 | |
| 51 | 54 | pub const BOOL = bool; |
| 52 | 55 | pub const BYTE = u8; |
| 53 | 56 | pub const DWORD = u32; |
| 54 | 57 | pub const FLOAT = f32; |
| 55 | 58 | pub const HANDLE = &c_void; |
| 59 | pub const HINSTANCE = &@OpaqueType(); | |
| 56 | 60 | pub const HCRYPTPROV = ULONG_PTR; |
| 57 | 61 | pub const LPCTSTR = &const TCHAR; |
| 58 | 62 | pub const LPDWORD = &DWORD; |
| ... | ... | @@ -60,6 +64,7 @@ pub const LPVOID = &c_void; |
| 60 | 64 | pub const PVOID = &c_void; |
| 61 | 65 | pub const TCHAR = if (UNICODE) WCHAR else u8; |
| 62 | 66 | pub const UINT = c_uint; |
| 67 | pub const INT = c_int; | |
| 63 | 68 | pub const ULONG_PTR = usize; |
| 64 | 69 | pub const WCHAR = u16; |
| 65 | 70 | pub const LPCVOID = &const c_void; |