| 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,6 +1451,7 @@ struct CodeGen { |
| 1451 | bool want_h_file; | 1451 | bool want_h_file; |
| 1452 | bool have_pub_main; | 1452 | bool have_pub_main; |
| 1453 | bool have_c_main; | 1453 | bool have_c_main; |
| 1454 | bool have_winmain; | ||
| 1454 | bool have_pub_panic; | 1455 | bool have_pub_panic; |
| 1455 | Buf *libc_lib_dir; | 1456 | Buf *libc_lib_dir; |
| 1456 | Buf *libc_static_lib_dir; | 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,6 +3200,12 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a |
| 3200 | g->have_c_main = true; | 3200 | g->have_c_main = true; |
| 3201 | g->windows_subsystem_windows = false; | 3201 | g->windows_subsystem_windows = false; |
| 3202 | g->windows_subsystem_console = true; | 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,7 +5157,7 @@ static void gen_root_source(CodeGen *g) { |
| 5157 | assert(g->root_out_name); | 5157 | assert(g->root_out_name); |
| 5158 | assert(g->out_type != OutTypeUnknown); | 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 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) | 5161 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) |
| 5162 | { | 5162 | { |
| 5163 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig"); | 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,7 +398,11 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 398 | //lj->args.append(get_libc_static_file(g, "crtbegin.o")); | 398 | //lj->args.append(get_libc_static_file(g, "crtbegin.o")); |
| 399 | } else { | 399 | } else { |
| 400 | lj->args.append("-NODEFAULTLIB"); | 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 | for (size_t i = 0; i < g->lib_dirs.length; i += 1) { | 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,6 +428,7 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 424 | } | 428 | } |
| 425 | 429 | ||
| 426 | Buf *def_contents = buf_alloc(); | 430 | Buf *def_contents = buf_alloc(); |
| 431 | ZigList<const char *> gen_lib_args = {0}; | ||
| 427 | for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) { | 432 | for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) { |
| 428 | LinkLib *link_lib = g->link_libs_list.at(lib_i); | 433 | LinkLib *link_lib = g->link_libs_list.at(lib_i); |
| 429 | if (buf_eql_str(link_lib->name, "c")) { | 434 | if (buf_eql_str(link_lib->name, "c")) { |
| ... | @@ -433,38 +438,34 @@ static void construct_linker_job_coff(LinkJob *lj) { | ... | @@ -433,38 +438,34 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 433 | Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name)); | 438 | Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name)); |
| 434 | lj->args.append(buf_ptr(arg)); | 439 | lj->args.append(buf_ptr(arg)); |
| 435 | } else { | 440 | } else { |
| 441 | buf_resize(def_contents, 0); | ||
| 436 | buf_appendf(def_contents, "LIBRARY %s\nEXPORTS\n", buf_ptr(link_lib->name)); | 442 | buf_appendf(def_contents, "LIBRARY %s\nEXPORTS\n", buf_ptr(link_lib->name)); |
| 437 | for (size_t exp_i = 0; exp_i < link_lib->symbols.length; exp_i += 1) { | 443 | for (size_t exp_i = 0; exp_i < link_lib->symbols.length; exp_i += 1) { |
| 438 | Buf *symbol_name = link_lib->symbols.at(exp_i); | 444 | Buf *symbol_name = link_lib->symbols.at(exp_i); |
| 439 | buf_appendf(def_contents, "%s\n", buf_ptr(symbol_name)); | 445 | buf_appendf(def_contents, "%s\n", buf_ptr(symbol_name)); |
| 440 | } | 446 | } |
| 441 | buf_appendf(def_contents, "\n"); | 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(); | 449 | Buf *def_path = buf_alloc(); |
| 450 | os_path_join(g->cache_dir, buf_create_from_str("all.lib"), all_lib_path); | 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 | Buf *generated_lib_path = buf_alloc(); |
| 453 | //os_path_join(g->cache_dir, buf_create_from_str("all.dll"), dll_path); | 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 | gen_lib_args.resize(0); |
| 456 | args.append("link"); | 457 | gen_lib_args.append("link"); |
| 457 | 458 | ||
| 458 | coff_append_machine_arg(g, &args); | 459 | coff_append_machine_arg(g, &gen_lib_args); |
| 459 | args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path)))); | 460 | gen_lib_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 | gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path)))); |
| 461 | Buf diag = BUF_INIT; | 462 | Buf diag = BUF_INIT; |
| 462 | if (!ZigLLDLink(g->zig_target.oformat, args.items, args.length, &diag)) { | 463 | if (!ZigLLDLink(g->zig_target.oformat, gen_lib_args.items, gen_lib_args.length, &diag)) { |
| 463 | fprintf(stderr, "%s\n", buf_ptr(&diag)); | 464 | fprintf(stderr, "%s\n", buf_ptr(&diag)); |
| 464 | exit(1); | 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 | if (g->libc_link_lib != nullptr) { | 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,6 +39,9 @@ pub extern "kernel32" stdcallcc fn WriteFile(in_hFile: HANDLE, in_lpBuffer: &con |
| 39 | 39 | ||
| 40 | pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD); | 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 | pub const PROV_RSA_FULL = 1; | 45 | pub const PROV_RSA_FULL = 1; |
| 43 | 46 | ||
| 44 | pub const UNICODE = false; | 47 | pub const UNICODE = false; |
| ... | @@ -46,13 +49,14 @@ pub const LPTSTR = if (unicode) LPWSTR else LPSTR; | ... | @@ -46,13 +49,14 @@ pub const LPTSTR = if (unicode) LPWSTR else LPSTR; |
| 46 | pub const LPWSTR = &WCHAR; | 49 | pub const LPWSTR = &WCHAR; |
| 47 | pub const LPSTR = &CHAR; | 50 | pub const LPSTR = &CHAR; |
| 48 | pub const CHAR = u8; | 51 | pub const CHAR = u8; |
| 49 | 52 | pub const PWSTR = &WCHAR; | |
| 50 | 53 | ||
| 51 | pub const BOOL = bool; | 54 | pub const BOOL = bool; |
| 52 | pub const BYTE = u8; | 55 | pub const BYTE = u8; |
| 53 | pub const DWORD = u32; | 56 | pub const DWORD = u32; |
| 54 | pub const FLOAT = f32; | 57 | pub const FLOAT = f32; |
| 55 | pub const HANDLE = &c_void; | 58 | pub const HANDLE = &c_void; |
| 59 | pub const HINSTANCE = &@OpaqueType(); | ||
| 56 | pub const HCRYPTPROV = ULONG_PTR; | 60 | pub const HCRYPTPROV = ULONG_PTR; |
| 57 | pub const LPCTSTR = &const TCHAR; | 61 | pub const LPCTSTR = &const TCHAR; |
| 58 | pub const LPDWORD = &DWORD; | 62 | pub const LPDWORD = &DWORD; |
| ... | @@ -60,6 +64,7 @@ pub const LPVOID = &c_void; | ... | @@ -60,6 +64,7 @@ pub const LPVOID = &c_void; |
| 60 | pub const PVOID = &c_void; | 64 | pub const PVOID = &c_void; |
| 61 | pub const TCHAR = if (UNICODE) WCHAR else u8; | 65 | pub const TCHAR = if (UNICODE) WCHAR else u8; |
| 62 | pub const UINT = c_uint; | 66 | pub const UINT = c_uint; |
| 67 | pub const INT = c_int; | ||
| 63 | pub const ULONG_PTR = usize; | 68 | pub const ULONG_PTR = usize; |
| 64 | pub const WCHAR = u16; | 69 | pub const WCHAR = u16; |
| 65 | pub const LPCVOID = &const c_void; | 70 | pub const LPCVOID = &const c_void; |