Commit a9082b4ec5

Andrew Kelley <andrew@ziglang.org>
2020-09-27 07:37:19
stage2: add CLI support for --subsystem
1 parent 4b403c7
src/Compilation.zig
@@ -377,6 +377,7 @@ pub const InitOptions = struct {
     color: @import("main.zig").Color = .Auto,
     test_filter: ?[]const u8 = null,
     test_name_prefix: ?[]const u8 = null,
+    subsystem: ?std.Target.SubSystem = null,
 };
 
 pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
@@ -767,6 +768,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
             .is_compiler_rt_or_libc = options.is_compiler_rt_or_libc,
             .each_lib_rpath = options.each_lib_rpath orelse false,
             .disable_lld_caching = options.disable_lld_caching,
+            .subsystem = options.subsystem,
         });
         errdefer bin_file.destroy();
         comp.* = .{
@@ -2557,6 +2559,10 @@ fn updateStage1Module(comp: *Compilation) !void {
     const stage1_pkg = try createStage1Pkg(arena, "root", mod.root_pkg, null);
     const test_filter = comp.test_filter orelse ""[0..0];
     const test_name_prefix = comp.test_name_prefix orelse ""[0..0];
+    const subsystem = if (comp.bin_file.options.subsystem) |s|
+        @intToEnum(stage1.TargetSubsystem, @enumToInt(s))
+    else
+        stage1.TargetSubsystem.Auto;
     stage1_module.* = .{
         .root_name_ptr = comp.bin_file.options.root_name.ptr,
         .root_name_len = comp.bin_file.options.root_name.len,
@@ -2581,7 +2587,7 @@ fn updateStage1Module(comp: *Compilation) !void {
         .userdata = @ptrToInt(comp),
         .root_pkg = stage1_pkg,
         .code_model = @enumToInt(comp.bin_file.options.machine_code_model),
-        .subsystem = stage1.TargetSubsystem.Auto,
+        .subsystem = subsystem,
         .err_color = @enumToInt(comp.color),
         .pic = comp.bin_file.options.pic,
         .link_libc = comp.bin_file.options.link_libc,
src/link.zig
@@ -77,6 +77,7 @@ pub const Options = struct {
     disable_lld_caching: bool,
     gc_sections: ?bool = null,
     allow_shlib_undefined: ?bool = null,
+    subsystem: ?std.Target.SubSystem = null,
     linker_script: ?[]const u8 = null,
     version_script: ?[]const u8 = null,
     override_soname: ?[]const u8 = null,
src/main.zig
@@ -273,6 +273,7 @@ const usage_build_generic =
     \\  --eh-frame-hdr                 Enable C++ exception handling by passing --eh-frame-hdr to linker
     \\  -dynamic                       Force output to be dynamically linked
     \\  -static                        Force output to be statically linked
+    \\  --subsystem [subsystem]        (windows) /SUBSYSTEM:<subsystem> to the linker\n"
     \\
     \\Test Options:
     \\  --test-filter [text]           Skip tests that do not match filter
@@ -439,6 +440,7 @@ fn buildOutputType(
     var override_lib_dir: ?[]const u8 = null;
     var main_pkg_path: ?[]const u8 = null;
     var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;
+    var subsystem: ?std.Target.SubSystem = null;
 
     var system_libs = std.ArrayList([]const u8).init(gpa);
     defer system_libs.deinit();
@@ -575,6 +577,39 @@ fn buildOutputType(
                         } else {
                             fatal("expected [auto|on|off] after --color, found '{}'", .{next_arg});
                         }
+                    } else if (mem.eql(u8, arg, "--subsystem")) {
+                        if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
+                        i += 1;
+                        if (mem.eql(u8, args[i], "console")) {
+                            subsystem = .Console;
+                        } else if (mem.eql(u8, args[i], "windows")) {
+                            subsystem = .Windows;
+                        } else if (mem.eql(u8, args[i], "posix")) {
+                            subsystem = .Posix;
+                        } else if (mem.eql(u8, args[i], "native")) {
+                            subsystem = .Native;
+                        } else if (mem.eql(u8, args[i], "efi_application")) {
+                            subsystem = .EfiApplication;
+                        } else if (mem.eql(u8, args[i], "efi_boot_service_driver")) {
+                            subsystem = .EfiBootServiceDriver;
+                        } else if (mem.eql(u8, args[i], "efi_rom")) {
+                            subsystem = .EfiRom;
+                        } else if (mem.eql(u8, args[i], "efi_runtime_driver")) {
+                            subsystem = .EfiRuntimeDriver;
+                        } else {
+                            fatal("invalid: --subsystem: '{s}'. Options are:\n{s}", .{
+                                args[i],
+                                \\  console
+                                \\  windows
+                                \\  posix
+                                \\  native
+                                \\  efi_application
+                                \\  efi_boot_service_driver
+                                \\  efi_rom
+                                \\  efi_runtime_driver
+                                \\
+                            });
+                        }
                     } else if (mem.eql(u8, arg, "-O")) {
                         if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
                         i += 1;
@@ -1539,6 +1574,7 @@ fn buildOutputType(
         .test_filter = test_filter,
         .test_name_prefix = test_name_prefix,
         .disable_lld_caching = !have_enable_cache,
+        .subsystem = subsystem,
     }) catch |err| {
         fatal("unable to create compilation: {}", .{@errorName(err)});
     };
BRANCH_TODO
@@ -1,4 +1,3 @@
- * subsystem
  * COFF LLD linking
  * mingw-w64
  * MachO LLD linking