Commit ba41be67f0

Andrew Kelley <superjoe30@gmail.com>
2017-09-24 09:54:59
windows gui hello world
1 parent 41b5885
Changed files (6)
example/hello_world/hello_windows.zig
@@ -0,0 +1,6 @@
+use @import("std").os.windows;
+
+export fn WinMain(hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: PWSTR, nCmdShow: INT) -> INT {
+    _ = MessageBoxA(null, c"hello", c"title", 0);
+    return 0;
+}
src/all_types.hpp
@@ -1451,6 +1451,7 @@ struct CodeGen {
     bool want_h_file;
     bool have_pub_main;
     bool have_c_main;
+    bool have_winmain;
     bool have_pub_panic;
     Buf *libc_lib_dir;
     Buf *libc_static_lib_dir;
src/analyze.cpp
@@ -3200,6 +3200,12 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
                 g->have_c_main = true;
                 g->windows_subsystem_windows = false;
                 g->windows_subsystem_console = true;
+            } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "WinMain") &&
+                    g->zig_target.os == ZigLLVM_Win32)
+            {
+                g->have_winmain = true;
+                g->windows_subsystem_windows = true;
+                g->windows_subsystem_console = false;
             }
 
         }
src/codegen.cpp
@@ -5157,7 +5157,7 @@ static void gen_root_source(CodeGen *g) {
     assert(g->root_out_name);
     assert(g->out_type != OutTypeUnknown);
 
-    if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && !g->have_c_main &&
+    if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && !g->have_c_main && !g->have_winmain &&
         ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe))
     {
         g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig");
src/link.cpp
@@ -398,7 +398,11 @@ static void construct_linker_job_coff(LinkJob *lj) {
         //lj->args.append(get_libc_static_file(g, "crtbegin.o"));
     } else {
         lj->args.append("-NODEFAULTLIB");
-        lj->args.append("-ENTRY:_start");
+        if (g->have_winmain) {
+            lj->args.append("-ENTRY:WinMain");
+        } else {
+            lj->args.append("-ENTRY:_start");
+        }
     }
 
     for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
@@ -424,6 +428,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
     }
 
     Buf *def_contents = buf_alloc();
+    ZigList<const char *> gen_lib_args = {0};
     for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
         LinkLib *link_lib = g->link_libs_list.at(lib_i);
         if (buf_eql_str(link_lib->name, "c")) {
@@ -433,38 +438,34 @@ static void construct_linker_job_coff(LinkJob *lj) {
             Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
             lj->args.append(buf_ptr(arg));
         } else {
+            buf_resize(def_contents, 0);
             buf_appendf(def_contents, "LIBRARY %s\nEXPORTS\n", buf_ptr(link_lib->name));
             for (size_t exp_i = 0; exp_i < link_lib->symbols.length; exp_i += 1) {
                 Buf *symbol_name = link_lib->symbols.at(exp_i);
                 buf_appendf(def_contents, "%s\n", buf_ptr(symbol_name));
             }
             buf_appendf(def_contents, "\n");
-        }
-    }
-    if (buf_len(def_contents) != 0) {
-        Buf *def_path = buf_alloc();
-        os_path_join(g->cache_dir, buf_create_from_str("all.def"), def_path);
-        os_write_file(def_path, def_contents);
 
-        Buf *all_lib_path = buf_alloc();
-        os_path_join(g->cache_dir, buf_create_from_str("all.lib"), all_lib_path);
+            Buf *def_path = buf_alloc();
+            os_path_join(g->cache_dir, buf_sprintf("%s.def", buf_ptr(link_lib->name)), def_path);
+            os_write_file(def_path, def_contents);
 
-        //Buf *dll_path = buf_alloc();
-        //os_path_join(g->cache_dir, buf_create_from_str("all.dll"), dll_path);
+            Buf *generated_lib_path = buf_alloc();
+            os_path_join(g->cache_dir, buf_sprintf("%s.lib", buf_ptr(link_lib->name)), generated_lib_path);
 
-        ZigList<const char *> args = {0};
-        args.append("link");
+            gen_lib_args.resize(0);
+            gen_lib_args.append("link");
 
-        coff_append_machine_arg(g, &args);
-        args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));
-        args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(all_lib_path))));
-        Buf diag = BUF_INIT;
-        if (!ZigLLDLink(g->zig_target.oformat, args.items, args.length, &diag)) {
-            fprintf(stderr, "%s\n", buf_ptr(&diag));
-            exit(1);
+            coff_append_machine_arg(g, &gen_lib_args);
+            gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));
+            gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path))));
+            Buf diag = BUF_INIT;
+            if (!ZigLLDLink(g->zig_target.oformat, gen_lib_args.items, gen_lib_args.length, &diag)) {
+                fprintf(stderr, "%s\n", buf_ptr(&diag));
+                exit(1);
+            }
+            lj->args.append(buf_ptr(generated_lib_path));
         }
-
-        lj->args.append(buf_ptr(all_lib_path));
     }
 
     if (g->libc_link_lib != nullptr) {
std/os/windows/index.zig
@@ -39,6 +39,9 @@ pub extern "kernel32" stdcallcc fn WriteFile(in_hFile: HANDLE, in_lpBuffer: &con
 
 pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD);
 
+
+pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) -> c_int;
+
 pub const PROV_RSA_FULL = 1;
 
 pub const UNICODE = false;
@@ -46,13 +49,14 @@ pub const LPTSTR = if (unicode) LPWSTR else LPSTR;
 pub const LPWSTR = &WCHAR;
 pub const LPSTR = &CHAR;
 pub const CHAR = u8;
-
+pub const PWSTR = &WCHAR;
 
 pub const BOOL = bool;
 pub const BYTE = u8;
 pub const DWORD = u32;
 pub const FLOAT = f32;
 pub const HANDLE = &c_void;
+pub const HINSTANCE = &@OpaqueType();
 pub const HCRYPTPROV = ULONG_PTR;
 pub const LPCTSTR = &const TCHAR;
 pub const LPDWORD = &DWORD;
@@ -60,6 +64,7 @@ pub const LPVOID = &c_void;
 pub const PVOID = &c_void;
 pub const TCHAR = if (UNICODE) WCHAR else u8;
 pub const UINT = c_uint;
+pub const INT = c_int;
 pub const ULONG_PTR = usize;
 pub const WCHAR = u16;
 pub const LPCVOID = &const c_void;