Commit a918ce26b8

Andrew Kelley <andrew@ziglang.org>
2018-12-26 21:25:54
fixups
1 parent f49b45b
src/all_types.hpp
@@ -1750,11 +1750,11 @@ struct CodeGen {
     BuildMode build_mode;
     OutType out_type;
     ZigTarget zig_target;
+    TargetSubsystem subsystem;
     bool is_static;
     bool strip_debug_symbols;
     bool is_test_build;
     bool is_native_target;
-    ZigLLVM_MSVCSubsystemType msvc_subsystem;
     bool linker_rdynamic;
     bool no_rosegment_workaround;
     bool each_lib_rpath;
src/analyze.cpp
@@ -3203,22 +3203,20 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi
     if (ccc) {
         if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) {
             g->have_c_main = true;
-            g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE;
+            g->subsystem = TargetSubsystemConsole;
         } else if (buf_eql_str(symbol_name, "WinMain") &&
             g->zig_target.os == OsWindows)
         {
             g->have_winmain = true;
-            g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS;
+            g->subsystem = TargetSubsystemWindows;
         } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&
             g->zig_target.os == OsWindows)
         {
             g->have_winmain_crt_startup = true;
-            g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS;
         } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") &&
             g->zig_target.os == OsWindows)
         {
             g->have_dllmain_crt_startup = true;
-            g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS;
         }
     }
 
@@ -4377,7 +4375,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r
             if (is_pub && ok_cc) {
                 if (buf_eql_str(proto_name, "main")) {
                     g->have_pub_main = true;
-                    g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE;
+                    g->subsystem = TargetSubsystemConsole;
                 } else if (buf_eql_str(proto_name, "panic")) {
                     g->have_pub_panic = true;
                 }
src/codegen.cpp
@@ -7231,7 +7231,7 @@ static void init(CodeGen *g) {
     }
 
     if (g->is_test_build) {
-        g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE;
+        g->subsystem = TargetSubsystemConsole;
     }
 
     assert(g->root_out_name);
@@ -7513,7 +7513,7 @@ static void gen_root_source(CodeGen *g) {
     report_errors_and_maybe_exit(g);
 
     if (!g->is_test_build && g->zig_target.os != OsFreestanding &&
-        g->zig_target.os != OsZen && g->zig_target.os != OsUefi &&
+        g->zig_target.os != OsUefi &&
         !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup &&
         ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe))
     {
@@ -8070,11 +8070,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
     cache_int(ch, g->zig_target.os);
     cache_int(ch, g->zig_target.env_type);
     cache_int(ch, g->zig_target.oformat);
+    cache_int(ch, g->subsystem);
     cache_bool(ch, g->is_static);
     cache_bool(ch, g->strip_debug_symbols);
     cache_bool(ch, g->is_test_build);
     cache_bool(ch, g->is_native_target);
-    cache_int(ch, g->msvc_subsystem);
     cache_bool(ch, g->linker_rdynamic);
     cache_bool(ch, g->no_rosegment_workaround);
     cache_bool(ch, g->each_lib_rpath);
src/ir.cpp
@@ -17872,13 +17872,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
     if (type_is_invalid(cimport_result->value.type))
         return ira->codegen->invalid_instruction;
 
-    if (ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_APPLICATION &&
-		ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER &&
-		ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_ROM &&
-		ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_RUNTIME_DRIVER) {
-
-		find_libc_include_path(ira->codegen);
-	}
+    find_libc_include_path(ira->codegen);
 
     ImportTableEntry *child_import = allocate<ImportTableEntry>(1);
     child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import);
src/link.cpp
@@ -444,97 +444,20 @@ static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, si
     return ZigLLDLink(oformat, args, arg_count, link_diag_callback, diag);
 }
 
-static void construct_linker_job_coff(LinkJob *lj) {
-    CodeGen *g = lj->codegen;
-
-    lj->args.append("/ERRORLIMIT:0");
-
-    if (g->libc_link_lib != nullptr) {
-        find_libc_lib_path(g);
-    }
-
-    lj->args.append("-NOLOGO");
-
-    if (!g->strip_debug_symbols && g->zig_target.os != Os::OsUefi) {
-        lj->args.append("-DEBUG");
-    }
-
-    if (g->out_type == OutTypeExe) {
-        // TODO compile time stack upper bound detection
-        lj->args.append("/STACK:16777216");
-    }
-
-    coff_append_machine_arg(g, &lj->args);
-
-    // The commented out stuff is from when we linked with MinGW
-    // Now that we're linking with LLD it remains to be determined
-    // how to handle --target-environ gnu
-    // These comments are a clue
-
-    bool is_library = g->out_type == OutTypeLib;
-    //bool dll = g->out_type == OutTypeLib;
-    //bool shared = !g->is_static && dll;
-    //if (g->is_static) {
-    //    lj->args.append("-Bstatic");
-    //} else {
-    //    if (dll) {
-    //        lj->args.append("--dll");
-    //    } else if (shared) {
-    //        lj->args.append("--shared");
-    //    }
-    //    lj->args.append("-Bdynamic");
-    //    if (dll || shared) {
-    //        lj->args.append("-e");
-    //        if (g->zig_target.arch.arch == ZigLLVM_x86) {
-    //            lj->args.append("_DllMainCRTStartup@12");
-    //        } else {
-    //            lj->args.append("DllMainCRTStartup");
-    //        }
-    //        lj->args.append("--enable-auto-image-base");
-    //    }
-    //}
-
-
-    // These are n actual command lines from LINK.EXE UEFI builds (app & driver) to be used as guidance cleaning
-    // up a bit for building the COFF linker args:
-    // /OUT:"J:\coding\nebulae\k\x64\Release\k.efi" /LTCG:incremental /Driver /PDB:"J:\coding\nebulae\k\x64\Release\k.pdb" "UefiApplicationEntryPoint.lib" "UefiRuntimeLib.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\nebulae\k\x64\Release\k.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_APPLICATION /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" 
-    // /OUT:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.efi" /LTCG:incremental /Driver /PDB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.pdb" "UefiDriverEntryPoint.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" 
-    
-    // Sorry for the goto(s) :)
-    switch (g->msvc_subsystem) {
-        case ZigLLVM_MSVC_CONSOLE:
-            lj->args.append("/SUBSYSTEM:console");
-            goto building_nt;
-        case ZigLLVM_MSVC_EFI_APPLICATION:
-            lj->args.append("/SUBSYSTEM:efi_application");
-            goto building_uefi;
-        case ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER:
-            lj->args.append("/SUBSYSTEM:efi_boot_service_driver");
-            goto building_uefi;
-        case ZigLLVM_MSVC_EFI_ROM:
-            lj->args.append("/SUBSYSTEM:efi_rom");
-            goto building_uefi;
-        case ZigLLVM_MSVC_EFI_RUNTIME_DRIVER:
-            lj->args.append("/SUBSYSTEM:efi_runtime_driver");
-            goto building_uefi;
-        case ZigLLVM_MSVC_NATIVE:
-            lj->args.append("/SUBSYSTEM:native");
-            goto building_nt;
-        case ZigLLVM_MSVC_POSIX:
-            lj->args.append("/SUBSYSTEM:posix");
-            goto building_nt;
-        case ZigLLVM_MSVC_WINDOWS:
-            lj->args.append("/SUBSYSTEM:windows");
-            goto building_nt;
-        case ZigLLVM_MSVC_NONE:
-            goto continuing_build;
-    }
+static void add_uefi_link_args(LinkJob *lj) {
+    lj->args.append("/BASE:0");
+    lj->args.append("/ENTRY:EfiMain");
+    lj->args.append("/OPT:REF");
+    lj->args.append("/SAFESEH:NO");
+    lj->args.append("/MERGE:.rdata=.data");
+    lj->args.append("/ALIGN:32");
+    lj->args.append("/NODEFAULTLIB");
+    lj->args.append("/SECTION:.xdata,D");
+}
 
-building_uefi:
-    lj->args.append("/BASE:\"0\" /ENTRY:\"EfiMain\" /OPT:REF /SAFESEH:NO /MERGE:\".rdata=.data\" /ALIGN:32 /NODEFAULTLIB /SECTION:\".xdata,D\"");
-    goto continuing_build;
+static void add_nt_link_args(LinkJob *lj, bool is_library) {
+    CodeGen *g = lj->codegen;
 
-building_nt:
     if (lj->link_in_crt) {
         const char *lib_str = g->is_static ? "lib" : "";
         const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : "";
@@ -557,17 +480,6 @@ building_nt:
         //https://msdn.microsoft.com/en-us/library/bb531344.aspx
         lj->args.append("legacy_stdio_definitions.lib");
 
-        //if (shared || dll) {
-        //    lj->args.append(get_libc_file(g, "dllcrt2.o"));
-        //} else {
-        //    if (g->windows_linker_unicode) {
-        //        lj->args.append(get_libc_file(g, "crt2u.o"));
-        //    } else {
-        //        lj->args.append(get_libc_file(g, "crt2.o"));
-        //    }
-        //}
-        //lj->args.append(get_libc_static_file(g, "crtbegin.o"));
-
         // msvcrt depends on kernel32
         lj->args.append("kernel32.lib");
     } else {
@@ -580,8 +492,156 @@ building_nt:
             }
         }
     }
+}
+
+// These are n actual command lines from LINK.EXE UEFI builds (app & driver) to be used as guidance cleaning
+// up a bit for building the COFF linker args:
+// /OUT:"J:\coding\nebulae\k\x64\Release\k.efi" /LTCG:incremental /Driver /PDB:"J:\coding\nebulae\k\x64\Release\k.pdb" "UefiApplicationEntryPoint.lib" "UefiRuntimeLib.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\nebulae\k\x64\Release\k.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_APPLICATION /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" 
+// /OUT:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.efi" /LTCG:incremental /Driver /PDB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.pdb" "UefiDriverEntryPoint.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" 
+// This commented out stuff is from when we linked with MinGW
+// Now that we're linking with LLD it remains to be determined
+// how to handle --target-environ gnu
+// These comments are a clue
+//bool dll = g->out_type == OutTypeLib;
+//bool shared = !g->is_static && dll;
+//if (g->is_static) {
+//    lj->args.append("-Bstatic");
+//} else {
+//    if (dll) {
+//        lj->args.append("--dll");
+//    } else if (shared) {
+//        lj->args.append("--shared");
+//    }
+//    lj->args.append("-Bdynamic");
+//    if (dll || shared) {
+//        lj->args.append("-e");
+//        if (g->zig_target.arch.arch == ZigLLVM_x86) {
+//            lj->args.append("_DllMainCRTStartup@12");
+//        } else {
+//            lj->args.append("DllMainCRTStartup");
+//        }
+//        lj->args.append("--enable-auto-image-base");
+//    }
+//}
+//if (shared || dll) {
+//    lj->args.append(get_libc_file(g, "dllcrt2.o"));
+//} else {
+//    if (g->windows_linker_unicode) {
+//        lj->args.append(get_libc_file(g, "crt2u.o"));
+//    } else {
+//        lj->args.append(get_libc_file(g, "crt2.o"));
+//    }
+//}
+//lj->args.append(get_libc_static_file(g, "crtbegin.o"));
+//if (g->libc_link_lib != nullptr) {
+//if (g->is_static) {
+//    lj->args.append("--start-group");
+//}
+
+//lj->args.append("-lmingw32");
+
+//lj->args.append("-lgcc");
+//bool is_android = (g->zig_target.env_type == ZigLLVM_Android);
+//bool is_cyg_ming = is_target_cyg_mingw(&g->zig_target);
+//if (!g->is_static && !is_android) {
+//    if (!is_cyg_ming) {
+//        lj->args.append("--as-needed");
+//    }
+//    //lj->args.append("-lgcc_s");
+//    if (!is_cyg_ming) {
+//        lj->args.append("--no-as-needed");
+//    }
+//}
+//if (g->is_static && !is_android) {
+//    //lj->args.append("-lgcc_eh");
+//}
+//if (is_android && !g->is_static) {
+//    lj->args.append("-ldl");
+//}
+
+//lj->args.append("-lmoldname");
+//lj->args.append("-lmingwex");
+//lj->args.append("-lmsvcrt");
+
+
+//if (g->windows_subsystem_windows) {
+//    lj->args.append("-lgdi32");
+//    lj->args.append("-lcomdlg32");
+//}
+//lj->args.append("-ladvapi32");
+//lj->args.append("-lshell32");
+//lj->args.append("-luser32");
+//lj->args.append("-lkernel32");
+
+//if (g->is_static) {
+//    lj->args.append("--end-group");
+//}
+
+//if (lj->link_in_crt) {
+//    lj->args.append(get_libc_static_file(g, "crtend.o"));
+//}
+//}
+
+
+static void construct_linker_job_coff(LinkJob *lj) {
+    CodeGen *g = lj->codegen;
+
+    lj->args.append("/ERRORLIMIT:0");
+
+    if (g->libc_link_lib != nullptr) {
+        find_libc_lib_path(g);
+    }
+
+    lj->args.append("/NOLOGO");
 
-continuing_build:
+    if (!g->strip_debug_symbols) {
+        lj->args.append("/DEBUG");
+    }
+
+    if (g->out_type == OutTypeExe) {
+        // TODO compile time stack upper bound detection
+        lj->args.append("/STACK:16777216");
+    }
+
+    coff_append_machine_arg(g, &lj->args);
+
+    bool is_library = g->out_type == OutTypeLib;
+    switch (g->subsystem) {
+        case TargetSubsystemAuto:
+            break;
+        case TargetSubsystemConsole:
+            lj->args.append("/SUBSYSTEM:console");
+            add_nt_link_args(lj, is_library);
+            break;
+        case TargetSubsystemEfiApplication:
+            lj->args.append("/SUBSYSTEM:efi_application");
+            add_uefi_link_args(lj);
+            break;
+        case TargetSubsystemEfiBootServiceDriver:
+            lj->args.append("/SUBSYSTEM:efi_boot_service_driver");
+            add_uefi_link_args(lj);
+            break;
+        case TargetSubsystemEfiRom:
+            lj->args.append("/SUBSYSTEM:efi_rom");
+            add_uefi_link_args(lj);
+            break;
+        case TargetSubsystemEfiRuntimeDriver:
+            lj->args.append("/SUBSYSTEM:efi_runtime_driver");
+            add_uefi_link_args(lj);
+            break;
+        case TargetSubsystemNative:
+            lj->args.append("/SUBSYSTEM:native");
+            add_nt_link_args(lj, is_library);
+            break;
+        case TargetSubsystemPosix:
+            lj->args.append("/SUBSYSTEM:posix");
+            add_nt_link_args(lj, is_library);
+            break;
+        case TargetSubsystemWindows:
+            lj->args.append("/SUBSYSTEM:windows");
+            add_nt_link_args(lj, is_library);
+            break;
+    }
 
     lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));
 
@@ -665,54 +725,6 @@ continuing_build:
         }
     }
 
-    //if (g->libc_link_lib != nullptr) {
-        //if (g->is_static) {
-        //    lj->args.append("--start-group");
-        //}
-
-        //lj->args.append("-lmingw32");
-
-        //lj->args.append("-lgcc");
-        //bool is_android = (g->zig_target.env_type == ZigLLVM_Android);
-        //bool is_cyg_ming = is_target_cyg_mingw(&g->zig_target);
-        //if (!g->is_static && !is_android) {
-        //    if (!is_cyg_ming) {
-        //        lj->args.append("--as-needed");
-        //    }
-        //    //lj->args.append("-lgcc_s");
-        //    if (!is_cyg_ming) {
-        //        lj->args.append("--no-as-needed");
-        //    }
-        //}
-        //if (g->is_static && !is_android) {
-        //    //lj->args.append("-lgcc_eh");
-        //}
-        //if (is_android && !g->is_static) {
-        //    lj->args.append("-ldl");
-        //}
-
-        //lj->args.append("-lmoldname");
-        //lj->args.append("-lmingwex");
-        //lj->args.append("-lmsvcrt");
-
-
-        //if (g->windows_subsystem_windows) {
-        //    lj->args.append("-lgdi32");
-        //    lj->args.append("-lcomdlg32");
-        //}
-        //lj->args.append("-ladvapi32");
-        //lj->args.append("-lshell32");
-        //lj->args.append("-luser32");
-        //lj->args.append("-lkernel32");
-
-        //if (g->is_static) {
-        //    lj->args.append("--end-group");
-        //}
-
-        //if (lj->link_in_crt) {
-        //    lj->args.append(get_libc_static_file(g, "crtend.o"));
-        //}
-    //}
 }
 
 
src/main.cpp
@@ -16,13 +16,6 @@
 
 #include <stdio.h>
 
-#ifdef __GNUC__
-#include <strings.h>
-#define STRCASECMP strcasecmp
-#else
-#define STRCASECMP stricmp
-#endif
-
 static int print_error_usage(const char *arg0) {
     fprintf(stderr, "See `%s help` for detailed usage information\n", arg0);
     return EXIT_FAILURE;
@@ -97,8 +90,8 @@ static int print_full_usage(const char *arg0) {
         "  -rdynamic                    add all symbols to the dynamic symbol table\n"
         "  -rpath [path]                add directory to the runtime library search path\n"
         "  --no-rosegment               compromise security to workaround valgrind bug\n"
-        "  --msvc-subsystem [subsystem] (windows/uefi) /SUBSYSTEM:<subsystem> to the linker\n"
-		"  -framework [name]            (darwin) link against framework\n"
+        "  --subsystem [subsystem]      (windows) /SUBSYSTEM:<subsystem> to the linker\n"
+        "  -framework [name]            (darwin) link against framework\n"
         "  -mios-version-min [ver]      (darwin) set iOS deployment target\n"
         "  -mmacosx-version-min [ver]   (darwin) set Mac OS X deployment target\n"
         "  --ver-major [ver]            dynamic library semver major version\n"
@@ -377,8 +370,6 @@ int main(int argc, char **argv) {
     const char *target_arch = nullptr;
     const char *target_os = nullptr;
     const char *target_environ = nullptr;
-    bool mwindows = false;
-    bool mconsole = false;
     bool rdynamic = false;
     const char *mmacosx_version_min = nullptr;
     const char *mios_version_min = nullptr;
@@ -401,7 +392,7 @@ int main(int argc, char **argv) {
     int runtime_args_start = -1;
     bool no_rosegment_workaround = false;
     bool system_linker_hack = false;
-    ZigLLVM_MSVCSubsystemType msvc_subsystem_type = ZigLLVM_MSVC_NONE;
+    TargetSubsystem subsystem = TargetSubsystemAuto;
 
     if (argc >= 2 && strcmp(argv[1], "build") == 0) {
         Buf zig_exe_path_buf = BUF_INIT;
@@ -547,36 +538,6 @@ int main(int argc, char **argv) {
                 verbose_llvm_ir = true;
             } else if (strcmp(arg, "--verbose-cimport") == 0) {
                 verbose_cimport = true;
-                       } else if (strcmp(arg, "--msvc-subsystem") == 0) {
-                if (i + 1 >= argc) {
-                    fprintf(stderr, "Expected 1 argument after --msvc-subsystem\n");
-                    return print_error_usage(arg0);
-                }
-                i += 1;
-                if (STRCASECMP(argv[i], "CONSOLE") == 0) {
-                   msvc_subsystem_type = ZigLLVM_MSVC_CONSOLE;
-                } else if (STRCASECMP(argv[i], "WINDOWS") == 0) {
-                    msvc_subsystem_type = ZigLLVM_MSVC_WINDOWS;
-                } else if (STRCASECMP(argv[i], "POSIX") == 0) {
-                    msvc_subsystem_type = ZigLLVM_MSVC_POSIX;
-                } else if (STRCASECMP(argv[i], "NATIVE") == 0) {
-                    msvc_subsystem_type = ZigLLVM_MSVC_NATIVE;
-                } else if (STRCASECMP(argv[i], "EFI_APPLICATION") == 0) {
-                    msvc_subsystem_type = ZigLLVM_MSVC_EFI_APPLICATION;
-                } else if (STRCASECMP(argv[i], "EFI_BOOT_SERVICE_DRIVER") == 0) {
-                    msvc_subsystem_type = ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER;
-                } else if (STRCASECMP(argv[i], "EFI_ROM") == 0) {
-                    msvc_subsystem_type = ZigLLVM_MSVC_EFI_ROM;
-                } else if (STRCASECMP(argv[i], "EFI_RUNTIME_DRIVER") == 0) {
-                    msvc_subsystem_type = ZigLLVM_MSVC_EFI_RUNTIME_DRIVER;
-                } else {
-                    fprintf(stderr, "Unknown format %s for --msvc-subsystem argument\n", argv[i]);
-                    return EXIT_FAILURE;
-                }
-            } else if (strcmp(arg, "-mwindows") == 0) {
-                mwindows = true;
-            } else if (strcmp(arg, "-mconsole") == 0) {
-                mconsole = true;
             } else if (strcmp(arg, "-rdynamic") == 0) {
                 rdynamic = true;
             } else if (strcmp(arg, "--no-rosegment") == 0) {
@@ -720,6 +681,37 @@ int main(int argc, char **argv) {
                     ver_patch = atoi(argv[i]);
                 } else if (strcmp(arg, "--test-cmd") == 0) {
                     test_exec_args.append(argv[i]);
+                } else if (strcmp(arg, "--subsystem") == 0) {
+                    if (strcmp(argv[i], "console") == 0) {
+                        subsystem = TargetSubsystemConsole;
+                    } else if (strcmp(argv[i], "windows") == 0) {
+                        subsystem = TargetSubsystemWindows;
+                    } else if (strcmp(argv[i], "posix") == 0) {
+                        subsystem = TargetSubsystemPosix;
+                    } else if (strcmp(argv[i], "native") == 0) {
+                        subsystem = TargetSubsystemNative;
+                    } else if (strcmp(argv[i], "efi_application") == 0) {
+                        subsystem = TargetSubsystemEfiApplication;
+                    } else if (strcmp(argv[i], "efi_boot_service_driver") == 0) {
+                        subsystem = TargetSubsystemEfiBootServiceDriver;
+                    } else if (strcmp(argv[i], "efi_rom") == 0) {
+                        subsystem = TargetSubsystemEfiRom;
+                    } else if (strcmp(argv[i], "efi_runtime_driver") == 0) {
+                        subsystem = TargetSubsystemEfiRuntimeDriver;
+                    } else {
+                        fprintf(stderr, "invalid: --subsystem %s\n"
+                                "Options are:\n"
+                                "  console\n"
+                                "  windows\n"
+                                "  posix\n"
+                                "  native\n"
+                                "  efi_application\n"
+                                "  efi_boot_service_driver\n"
+                                "  efi_rom\n"
+                                "  efi_runtime_driver\n"
+                            , argv[i]);
+                        return EXIT_FAILURE;
+                    }
                 } else {
                     fprintf(stderr, "Invalid argument: %s\n", arg);
                     return print_error_usage(arg0);
@@ -882,7 +874,7 @@ int main(int argc, char **argv) {
                 buf_out_name = buf_create_from_str("run");
             }
             CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir());
-            g->msvc_subsystem = msvc_subsystem_type;
+            g->subsystem = subsystem;
 
             if (disable_pic) {
                 if (out_type != OutTypeLib || !is_static) {
src/target.cpp
@@ -283,6 +283,7 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) {
         case OsSolaris:
             return ZigLLVM_Solaris;
         case OsWindows:
+        case OsUefi:
             return ZigLLVM_Win32;
         case OsHaiku:
             return ZigLLVM_Haiku;
@@ -316,8 +317,6 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) {
             return ZigLLVM_Contiki;
         case OsAMDPAL:
             return ZigLLVM_AMDPAL;
-        case OsUefi:
-            return ZigLLVM_Uefi;
     }
     zig_unreachable();
 }
@@ -809,7 +808,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
 }
 
 const char *target_o_file_ext(ZigTarget *target) {
-    if (target->env_type == ZigLLVM_MSVC || (target->os == OsWindows || target->os == OsUefi)) {
+    if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) {
         return ".obj";
     } else {
         return ".o";
src/target.hpp
@@ -54,13 +54,24 @@ enum Os {
     OsUefi,
 };
 
+enum TargetSubsystem {
+    TargetSubsystemAuto, // Zig should infer the subsystem
+    TargetSubsystemConsole,
+    TargetSubsystemWindows,
+    TargetSubsystemPosix,
+    TargetSubsystemNative,
+    TargetSubsystemEfiApplication,
+    TargetSubsystemEfiBootServiceDriver,
+    TargetSubsystemEfiRom,
+    TargetSubsystemEfiRuntimeDriver,
+};
+
 struct ZigTarget {
     ArchType arch;
     ZigLLVM_VendorType vendor;
     Os os;
     ZigLLVM_EnvironmentType env_type;
     ZigLLVM_ObjectFormatType oformat;
-    ZigLLVM_MSVCSubsystemType msvc_subsystem = ZigLLVM_MSVC_NONE;
 };
 
 enum CIntType {
src/translate_c.cpp
@@ -4749,7 +4749,7 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const
     clang_argv.append("-isystem");
     clang_argv.append(buf_ptr(codegen->zig_c_headers_dir));
 
-    if (codegen->libc_include_dir) {
+    if (codegen->libc_include_dir != nullptr) {
         clang_argv.append("-isystem");
         clang_argv.append(buf_ptr(codegen->libc_include_dir));
     }
src/zig_llvm.cpp
@@ -690,12 +690,7 @@ const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) {
 }
 
 const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os) {
-    switch (os) {
-	case ZigLLVM_Uefi:
-		return "windows";
-	default:
-		return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin();
-	}
+    return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin();
 }
 
 const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) {
src/zig_llvm.h
@@ -10,7 +10,6 @@
 
 #include <stdbool.h>
 #include <stddef.h>
-#include <stdint.h>
 #include <llvm-c/Core.h>
 #include <llvm-c/Analysis.h>
 #include <llvm-c/Target.h>
@@ -358,8 +357,8 @@ enum ZigLLVM_OSType {
     ZigLLVM_Mesa3D,
     ZigLLVM_Contiki,
     ZigLLVM_AMDPAL,     // AMD PAL Runtime
-    ZigLLVM_Uefi,
-    ZigLLVM_LastOSType = ZigLLVM_Uefi
+
+    ZigLLVM_LastOSType = ZigLLVM_AMDPAL
 };
 
 // Synchronize with target.cpp::environ_list
@@ -398,19 +397,6 @@ enum ZigLLVM_ObjectFormatType {
     ZigLLVM_Wasm,
 };
 
-// For MSVC-supported subsystems
-enum ZigLLVM_MSVCSubsystemType {
-    ZigLLVM_MSVC_NONE,
-    ZigLLVM_MSVC_CONSOLE,
-    ZigLLVM_MSVC_WINDOWS,
-    ZigLLVM_MSVC_POSIX,
-    ZigLLVM_MSVC_NATIVE,
-    ZigLLVM_MSVC_EFI_APPLICATION,
-    ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER,
-    ZigLLVM_MSVC_EFI_ROM,
-    ZigLLVM_MSVC_EFI_RUNTIME_DRIVER,                                         
-};
-
 ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch);
 ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch);
 ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor);
std/os/uefi/index.zig
std/os/index.zig
@@ -18,7 +18,7 @@ test "std.os" {
     _ = @import("test.zig");
     _ = @import("time.zig");
     _ = @import("windows/index.zig");
-    _ = @import("uefi/index.zig");
+    _ = @import("uefi.zig");
     _ = @import("get_app_data_dir.zig");
 }
 
@@ -27,7 +27,7 @@ pub const darwin = @import("darwin.zig");
 pub const linux = @import("linux/index.zig");
 pub const freebsd = @import("freebsd/index.zig");
 pub const zen = @import("zen.zig");
-pub const uefi = @import("uefi/index.zig");
+pub const uefi = @import("uefi.zig");
 
 pub const posix = switch (builtin.os) {
     Os.linux => linux,
@@ -192,6 +192,7 @@ pub fn abort() noreturn {
             windows.ExitProcess(3);
         },
         Os.uefi => {
+            // TODO there's gotta be a better thing to do here than loop forever
             while (true) {}
         },
         else => @compileError("Unsupported OS"),
std/os/uefi.zig
@@ -0,0 +1,2 @@
+// TODO this is where the extern declarations go. For example, see
+// inc/efilib.h in gnu-efi-code
std/special/panic.zig
@@ -10,9 +10,13 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn
     @setCold(true);
     switch (builtin.os) {
         // TODO: fix panic in zen.
-        builtin.Os.freestanding, builtin.Os.zen, builtin.Os.uefi => {
+        builtin.Os.freestanding, builtin.Os.zen => {
             while (true) {}
         },
+        builtin.Os.uefi => {
+            // TODO look into using the debug info and logging helpful messages
+            std.os.abort();
+        },
         else => {
             const first_trace_addr = @ptrToInt(@returnAddress());
             std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg);
CMakeLists.txt
@@ -590,7 +590,7 @@ set(ZIG_STD_FILES
     "os/freebsd/x86_64.zig"
     "os/path.zig"
     "os/time.zig"
-    "os/uefi/index.zig"
+    "os/uefi.zig"
     "os/windows/advapi32.zig"
     "os/windows/error.zig"
     "os/windows/index.zig"
README.md
@@ -87,26 +87,26 @@ clarity.
 
 #### Support Table
 
-|        | freestanding | linux  | macosx | windows | freebsd | other  |
-|--------|--------------|--------|--------|---------|---------|--------|
-|x86_64  | Tier 2       | Tier 1 | Tier 1 | Tier 1  | Tier 2  | Tier 3 |
-|i386    | Tier 2       | Tier 2 | Tier 2 | Tier 2  | Tier 3  | Tier 3 |
-|arm     | Tier 2       | Tier 3 | Tier 3 | Tier 3  | Tier 3  | Tier 3 |
-|arm64   | Tier 2       | Tier 2 | Tier 3 | Tier 3  | Tier 3  | Tier 3 |
-|bpf     | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 |
-|hexagon | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 |
-|mips    | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 |
-|powerpc | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 |
-|r600    | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 |
-|amdgcn  | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 |
-|sparc   | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 |
-|s390x   | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 |
-|spir    | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 |
-|lanai   | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 |
-|wasm32  | Tier 4       | N/A    | N/A    | N/A     | N/A     | N/A    |
-|wasm64  | Tier 4       | N/A    | N/A    | N/A     | N/A     | N/A    |
-|riscv32 | Tier 4       | Tier 4 | N/A    | N/A     | Tier 4  | Tier 4 |
-|riscv64 | Tier 4       | Tier 4 | N/A    | N/A     | Tier 4  | Tier 4 |
+|        | freestanding | linux  | macosx | windows | freebsd | UEFI   | other  |
+|--------|--------------|--------|--------|---------|---------|--------|--------|
+|x86_64  | Tier 2       | Tier 1 | Tier 1 | Tier 1  | Tier 2  | Tier 2 | Tier 3 |
+|i386    | Tier 2       | Tier 2 | Tier 2 | Tier 2  | Tier 3  | Tier 3 | Tier 3 |
+|arm     | Tier 2       | Tier 3 | Tier 3 | Tier 3  | Tier 3  | Tier 3 | Tier 3 |
+|arm64   | Tier 2       | Tier 2 | Tier 3 | Tier 3  | Tier 3  | Tier 3 | Tier 3 |
+|bpf     | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 | Tier 3 |
+|hexagon | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 | Tier 3 |
+|mips    | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 | Tier 3 |
+|powerpc | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 | Tier 3 |
+|r600    | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 | Tier 3 |
+|amdgcn  | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 | Tier 3 |
+|sparc   | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 | Tier 3 |
+|s390x   | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 | Tier 3 |
+|spir    | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 | Tier 3 |
+|lanai   | Tier 3       | Tier 3 | N/A    | N/A     | Tier 3  | Tier 3 | Tier 3 |
+|wasm32  | Tier 4       | N/A    | N/A    | N/A     | N/A     | N/A    | N/A    |
+|wasm64  | Tier 4       | N/A    | N/A    | N/A     | N/A     | N/A    | N/A    |
+|riscv32 | Tier 4       | Tier 4 | N/A    | N/A     | Tier 4  | Tier 4 | Tier 4 |
+|riscv64 | Tier 4       | Tier 4 | N/A    | N/A     | Tier 4  | Tier 4 | Tier 4 |
 
 ## Community