| ... | ... | @@ -100,6 +100,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget |
| 100 | 100 | |
| 101 | 101 | codegen_add_time_event(g, "Initialize"); |
| 102 | 102 | |
| 103 | g->subsystem = TargetSubsystemAuto; |
| 103 | 104 | g->libc = libc; |
| 104 | 105 | g->zig_target = target; |
| 105 | 106 | g->cache_dir = cache_dir; |
| ... | ... | @@ -7417,6 +7418,21 @@ static const char *build_mode_to_str(BuildMode build_mode) { |
| 7417 | 7418 | zig_unreachable(); |
| 7418 | 7419 | } |
| 7419 | 7420 | |
| 7421 | static const char *subsystem_to_str(TargetSubsystem subsystem) { |
| 7422 | switch (subsystem) { |
| 7423 | case TargetSubsystemConsole: return "Console"; |
| 7424 | case TargetSubsystemWindows: return "Windows"; |
| 7425 | case TargetSubsystemPosix: return "Posix"; |
| 7426 | case TargetSubsystemNative: return "Native"; |
| 7427 | case TargetSubsystemEfiApplication: return "EfiApplication"; |
| 7428 | case TargetSubsystemEfiBootServiceDriver: return "EfiBootServiceDriver"; |
| 7429 | case TargetSubsystemEfiRom: return "EfiRom"; |
| 7430 | case TargetSubsystemEfiRuntimeDriver: return "EfiRuntimeDriver"; |
| 7431 | case TargetSubsystemAuto: zig_unreachable(); |
| 7432 | } |
| 7433 | zig_unreachable(); |
| 7434 | } |
| 7435 | |
| 7420 | 7436 | static bool detect_dynamic_link(CodeGen *g) { |
| 7421 | 7437 | if (g->is_dynamic) |
| 7422 | 7438 | return true; |
| ... | ... | @@ -7462,6 +7478,23 @@ static bool detect_stack_probing(CodeGen *g) { |
| 7462 | 7478 | zig_unreachable(); |
| 7463 | 7479 | } |
| 7464 | 7480 | |
| 7481 | // Returns TargetSubsystemAuto to mean "no subsystem" |
| 7482 | TargetSubsystem detect_subsystem(CodeGen *g) { |
| 7483 | if (g->subsystem != TargetSubsystemAuto) |
| 7484 | return g->subsystem; |
| 7485 | if (g->zig_target->os == OsWindows) { |
| 7486 | if (g->have_dllmain_crt_startup || (g->out_type == OutTypeLib && g->is_dynamic)) |
| 7487 | return TargetSubsystemAuto; |
| 7488 | if (g->have_c_main || g->have_pub_main || g->is_test_build) |
| 7489 | return TargetSubsystemConsole; |
| 7490 | if (g->have_winmain || g->have_winmain_crt_startup) |
| 7491 | return TargetSubsystemWindows; |
| 7492 | } else if (g->zig_target->os == OsUefi) { |
| 7493 | return TargetSubsystemEfiApplication; |
| 7494 | } |
| 7495 | return TargetSubsystemAuto; |
| 7496 | } |
| 7497 | |
| 7465 | 7498 | static bool detect_single_threaded(CodeGen *g) { |
| 7466 | 7499 | if (g->want_single_threaded) |
| 7467 | 7500 | return true; |
| ... | ... | @@ -7869,6 +7902,28 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 7869 | 7902 | //assert(EndianBig == 0); |
| 7870 | 7903 | //assert(EndianLittle == 1); |
| 7871 | 7904 | } |
| 7905 | { |
| 7906 | buf_appendf(contents, |
| 7907 | "pub const SubSystem = enum {\n" |
| 7908 | " Console,\n" |
| 7909 | " Windows,\n" |
| 7910 | " Posix,\n" |
| 7911 | " Native,\n" |
| 7912 | " EfiApplication,\n" |
| 7913 | " EfiBootServiceDriver,\n" |
| 7914 | " EfiRom,\n" |
| 7915 | " EfiRuntimeDriver,\n" |
| 7916 | "};\n\n"); |
| 7917 | |
| 7918 | assert(TargetSubsystemConsole == 0); |
| 7919 | assert(TargetSubsystemWindows == 1); |
| 7920 | assert(TargetSubsystemPosix == 2); |
| 7921 | assert(TargetSubsystemNative == 3); |
| 7922 | assert(TargetSubsystemEfiApplication == 4); |
| 7923 | assert(TargetSubsystemEfiBootServiceDriver == 5); |
| 7924 | assert(TargetSubsystemEfiRom == 6); |
| 7925 | assert(TargetSubsystemEfiRuntimeDriver == 7); |
| 7926 | } |
| 7872 | 7927 | { |
| 7873 | 7928 | const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little"; |
| 7874 | 7929 | buf_appendf(contents, "pub const endian = %s;\n", endian_str); |
| ... | ... | @@ -7885,6 +7940,13 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 7885 | 7940 | buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g))); |
| 7886 | 7941 | buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic)); |
| 7887 | 7942 | |
| 7943 | { |
| 7944 | TargetSubsystem detected_subsystem = detect_subsystem(g); |
| 7945 | if (detected_subsystem != TargetSubsystemAuto) { |
| 7946 | buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_to_str(detected_subsystem)); |
| 7947 | } |
| 7948 | } |
| 7949 | |
| 7888 | 7950 | if (g->is_test_build) { |
| 7889 | 7951 | buf_appendf(contents, |
| 7890 | 7952 | "const TestFn = struct {\n" |
| ... | ... | @@ -7928,6 +7990,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { |
| 7928 | 7990 | cache_bool(&cache_hash, g->have_err_ret_tracing); |
| 7929 | 7991 | cache_bool(&cache_hash, g->libc_link_lib != nullptr); |
| 7930 | 7992 | cache_bool(&cache_hash, g->valgrind_support); |
| 7993 | cache_int(&cache_hash, detect_subsystem(g)); |
| 7931 | 7994 | |
| 7932 | 7995 | Buf digest = BUF_INIT; |
| 7933 | 7996 | buf_resize(&digest, 0); |
| ... | ... | @@ -7995,10 +8058,6 @@ static void init(CodeGen *g) { |
| 7995 | 8058 | g->is_single_threaded = true; |
| 7996 | 8059 | } |
| 7997 | 8060 | |
| 7998 | | if (g->is_test_build) { |
| 7999 | | g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemConsole : g->subsystem; |
| 8000 | | } |
| 8001 | | |
| 8002 | 8061 | assert(g->root_out_name); |
| 8003 | 8062 | g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name)); |
| 8004 | 8063 | |
| ... | ... | @@ -9352,7 +9411,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 9352 | 9411 | cache_int(ch, g->zig_target->vendor); |
| 9353 | 9412 | cache_int(ch, g->zig_target->os); |
| 9354 | 9413 | cache_int(ch, g->zig_target->abi); |
| 9355 | | cache_int(ch, g->subsystem); |
| 9414 | cache_int(ch, detect_subsystem(g)); |
| 9356 | 9415 | cache_bool(ch, g->strip_debug_symbols); |
| 9357 | 9416 | cache_bool(ch, g->is_test_build); |
| 9358 | 9417 | if (g->is_test_build) { |