commit 6dbaae4c461ed4e8d6b087366b6069ba8dba628f (tree)
parent 7017388e9ea9a5b144780c0a5c090bb7a221c9b6
Author: Andrew Kelley <andrew@ziglang.org>
Date: Wed, 29 May 2019 17:14:34 -0400
Merge branch 'emekoi-builtin-subsystem'
Diffstat:
6 files changed, 74 insertions(+), 12 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
@@ -1857,7 +1857,7 @@ struct CodeGen {
BuildMode build_mode;
OutType out_type;
const ZigTarget *zig_target;
- TargetSubsystem subsystem;
+ TargetSubsystem subsystem; // careful using this directly; see detect_subsystem
ValgrindSupport valgrind_support;
bool strip_debug_symbols;
bool is_test_build;
diff --git a/src/analyze.cpp b/src/analyze.cpp
@@ -2722,12 +2722,10 @@ 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->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemConsole : g->subsystem;
} else if (buf_eql_str(symbol_name, "WinMain") &&
g->zig_target->os == OsWindows)
{
g->have_winmain = true;
- g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemWindows : g->subsystem;
} else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&
g->zig_target->os == OsWindows)
{
@@ -3966,7 +3964,6 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
if (is_pub) {
if (buf_eql_str(proto_name, "main")) {
g->have_pub_main = true;
- g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemConsole : g->subsystem;
} else if (buf_eql_str(proto_name, "panic")) {
g->have_pub_panic = true;
}
diff --git a/src/codegen.cpp b/src/codegen.cpp
@@ -100,6 +100,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
codegen_add_time_event(g, "Initialize");
+ g->subsystem = TargetSubsystemAuto;
g->libc = libc;
g->zig_target = target;
g->cache_dir = cache_dir;
@@ -7417,6 +7418,21 @@ static const char *build_mode_to_str(BuildMode build_mode) {
zig_unreachable();
}
+static const char *subsystem_to_str(TargetSubsystem subsystem) {
+ switch (subsystem) {
+ case TargetSubsystemConsole: return "Console";
+ case TargetSubsystemWindows: return "Windows";
+ case TargetSubsystemPosix: return "Posix";
+ case TargetSubsystemNative: return "Native";
+ case TargetSubsystemEfiApplication: return "EfiApplication";
+ case TargetSubsystemEfiBootServiceDriver: return "EfiBootServiceDriver";
+ case TargetSubsystemEfiRom: return "EfiRom";
+ case TargetSubsystemEfiRuntimeDriver: return "EfiRuntimeDriver";
+ case TargetSubsystemAuto: zig_unreachable();
+ }
+ zig_unreachable();
+}
+
static bool detect_dynamic_link(CodeGen *g) {
if (g->is_dynamic)
return true;
@@ -7462,6 +7478,23 @@ static bool detect_stack_probing(CodeGen *g) {
zig_unreachable();
}
+// Returns TargetSubsystemAuto to mean "no subsystem"
+TargetSubsystem detect_subsystem(CodeGen *g) {
+ if (g->subsystem != TargetSubsystemAuto)
+ return g->subsystem;
+ if (g->zig_target->os == OsWindows) {
+ if (g->have_dllmain_crt_startup || (g->out_type == OutTypeLib && g->is_dynamic))
+ return TargetSubsystemAuto;
+ if (g->have_c_main || g->have_pub_main || g->is_test_build)
+ return TargetSubsystemConsole;
+ if (g->have_winmain || g->have_winmain_crt_startup)
+ return TargetSubsystemWindows;
+ } else if (g->zig_target->os == OsUefi) {
+ return TargetSubsystemEfiApplication;
+ }
+ return TargetSubsystemAuto;
+}
+
static bool detect_single_threaded(CodeGen *g) {
if (g->want_single_threaded)
return true;
@@ -7870,6 +7903,28 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
//assert(EndianLittle == 1);
}
{
+ buf_appendf(contents,
+ "pub const SubSystem = enum {\n"
+ " Console,\n"
+ " Windows,\n"
+ " Posix,\n"
+ " Native,\n"
+ " EfiApplication,\n"
+ " EfiBootServiceDriver,\n"
+ " EfiRom,\n"
+ " EfiRuntimeDriver,\n"
+ "};\n\n");
+
+ assert(TargetSubsystemConsole == 0);
+ assert(TargetSubsystemWindows == 1);
+ assert(TargetSubsystemPosix == 2);
+ assert(TargetSubsystemNative == 3);
+ assert(TargetSubsystemEfiApplication == 4);
+ assert(TargetSubsystemEfiBootServiceDriver == 5);
+ assert(TargetSubsystemEfiRom == 6);
+ assert(TargetSubsystemEfiRuntimeDriver == 7);
+ }
+ {
const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";
buf_appendf(contents, "pub const endian = %s;\n", endian_str);
}
@@ -7885,6 +7940,13 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g)));
buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
+ {
+ TargetSubsystem detected_subsystem = detect_subsystem(g);
+ if (detected_subsystem != TargetSubsystemAuto) {
+ buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_to_str(detected_subsystem));
+ }
+ }
+
if (g->is_test_build) {
buf_appendf(contents,
"const TestFn = struct {\n"
@@ -7928,6 +7990,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
cache_bool(&cache_hash, g->have_err_ret_tracing);
cache_bool(&cache_hash, g->libc_link_lib != nullptr);
cache_bool(&cache_hash, g->valgrind_support);
+ cache_int(&cache_hash, detect_subsystem(g));
Buf digest = BUF_INIT;
buf_resize(&digest, 0);
@@ -7995,10 +8058,6 @@ static void init(CodeGen *g) {
g->is_single_threaded = true;
}
- if (g->is_test_build) {
- g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemConsole : g->subsystem;
- }
-
assert(g->root_out_name);
g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name));
@@ -9352,7 +9411,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
cache_int(ch, g->zig_target->vendor);
cache_int(ch, g->zig_target->os);
cache_int(ch, g->zig_target->abi);
- cache_int(ch, g->subsystem);
+ cache_int(ch, detect_subsystem(g));
cache_bool(ch, g->strip_debug_symbols);
cache_bool(ch, g->is_test_build);
if (g->is_test_build) {
diff --git a/src/codegen.hpp b/src/codegen.hpp
@@ -56,4 +56,6 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
Buf *codegen_generate_builtin_source(CodeGen *g);
+TargetSubsystem detect_subsystem(CodeGen *g);
+
#endif
diff --git a/src/link.cpp b/src/link.cpp
@@ -1225,7 +1225,7 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) {
lj->args.append(get_libc_file(g->libc, "libmingwex.a"));
lj->args.append(get_libc_file(g->libc, "libmsvcrt.a"));
- if (g->subsystem == TargetSubsystemWindows) {
+ if (detect_subsystem(g) == TargetSubsystemWindows) {
lj->args.append(get_libc_file(g->libc, "libgdi32.a"));
lj->args.append(get_libc_file(g->libc, "libcomdlg32.a"));
}
@@ -1307,7 +1307,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
}
- switch (g->subsystem) {
+ switch (detect_subsystem(g)) {
case TargetSubsystemAuto:
if (g->zig_target->os == OsUefi) {
add_uefi_link_args(lj);
diff --git a/src/target.hpp b/src/target.hpp
@@ -62,7 +62,6 @@ enum SubArchList {
};
enum TargetSubsystem {
- TargetSubsystemAuto, // Zig should infer the subsystem
TargetSubsystemConsole,
TargetSubsystemWindows,
TargetSubsystemPosix,
@@ -71,6 +70,11 @@ enum TargetSubsystem {
TargetSubsystemEfiBootServiceDriver,
TargetSubsystemEfiRom,
TargetSubsystemEfiRuntimeDriver,
+
+ // This means Zig should infer the subsystem.
+ // It's last so that the indexes of other items can line up
+ // with the enum in builtin.zig.
+ TargetSubsystemAuto
};
struct ZigTarget {