Commit 237dfdbdc6
Changed files (5)
src/all_types.hpp
@@ -1362,6 +1362,7 @@ struct CodeGen {
bool strip_debug_symbols;
bool want_h_file;
bool have_pub_main;
+ bool have_c_main;
bool have_pub_panic;
bool link_libc;
Buf *libc_lib_dir;
src/analyze.cpp
@@ -2911,7 +2911,12 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
} else if (buf_eql_str(proto_name, "panic")) {
g->have_pub_panic = true;
}
+ } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "main") &&
+ g->link_libc)
+ {
+ g->have_c_main = true;
}
+
}
}
src/codegen.cpp
@@ -4726,7 +4726,9 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou
assert(g->root_out_name);
assert(g->out_type != OutTypeUnknown);
- if (!g->is_test_build && g->have_pub_main && (g->out_type == OutTypeObj || g->out_type == OutTypeExe)) {
+ if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && !g->have_c_main &&
+ ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe))
+ {
g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g), "bootstrap.zig");
}
if (!g->omit_zigrt) {
std/special/bootstrap.zig
@@ -12,8 +12,8 @@ const exit = std.os.posix.exit;
var argc_ptr: &usize = undefined;
export nakedcc fn _start() -> noreturn {
- @setGlobalLinkage(_start, if (want_start_symbol) GlobalLinkage.Strong else GlobalLinkage.Internal);
if (!want_start_symbol) {
+ @setGlobalLinkage(_start, GlobalLinkage.Internal);
unreachable;
}
@@ -48,8 +48,8 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void {
}
export fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 {
- @setGlobalLinkage(main, if (want_main_symbol) GlobalLinkage.Strong else GlobalLinkage.Internal);
if (!want_main_symbol) {
+ @setGlobalLinkage(main, GlobalLinkage.Internal);
unreachable;
}
test/run_tests.cpp
@@ -161,6 +161,38 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source
return test_case;
}
+static TestCase *add_compile_fail_case_exe(const char *case_name, const char *source, size_t count, ...) {
+ va_list ap;
+ va_start(ap, count);
+
+ TestCase *test_case = allocate<TestCase>(1);
+ test_case->case_name = case_name;
+ test_case->source_files.resize(1);
+ test_case->source_files.at(0).relative_path = tmp_source_path;
+ test_case->source_files.at(0).source_code = source;
+
+ for (size_t i = 0; i < count; i += 1) {
+ const char *arg = va_arg(ap, const char *);
+ test_case->compile_errors.append(arg);
+ }
+
+ test_case->compiler_args.append("build_exe");
+ test_case->compiler_args.append(tmp_source_path);
+
+ test_case->compiler_args.append("--name");
+ test_case->compiler_args.append("test");
+
+ test_case->compiler_args.append("--output");
+ test_case->compiler_args.append(tmp_exe_path);
+
+ test_case->compiler_args.append("--release");
+ test_case->compiler_args.append("--strip");
+
+ test_cases.append(test_case);
+
+ return test_case;
+}
+
static void add_debug_safety_case(const char *case_name, const char *source) {
TestCase *test_case = allocate<TestCase>(1);
test_case->is_debug_safety = true;
@@ -220,6 +252,11 @@ static TestCase *add_example_compile_extra(const char *root_source_file, bool li
test_case->compiler_args.append("build_exe");
test_case->compiler_args.append(buf_ptr(buf_sprintf("../%s", root_source_file)));
+ if (libc) {
+ test_case->compiler_args.append("--library");
+ test_case->compiler_args.append("c");
+ }
+
test_cases.append(test_case);
return test_case;
@@ -1952,6 +1989,16 @@ comptime {
const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a);
}
)SOURCE", 1, ".tmp_source.zig:9:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'");
+
+ add_compile_fail_case_exe("missing main fn in executable", R"SOURCE(
+ )SOURCE", 1, "error: no member named 'main' in '");
+
+ add_compile_fail_case_exe("private main fn", R"SOURCE(
+fn main() {}
+ )SOURCE", 2,
+ "error: 'main' is private",
+ ".tmp_source.zig:2:1: note: declared here");
+
}
//////////////////////////////////////////////////////////////////////////////