authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-22 11:26:30-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-22 11:26:30-04:00
log87bc97daefc8b5d8b665ea2fb2b6c232b80344bc
treeedf82e24345f0049fb930cdec36aa299b42c3ca5
parente1c47d6fe88bb1d79a4484e07d21f126ca9f1003

unify main entry point regardless of whether linking libc

closes #248

12 files changed, 86 insertions(+), 57 deletions(-)

CMakeLists.txt+1-2
......@@ -202,6 +202,7 @@ install(TARGETS zig DESTINATION bin)
202202install(FILES ${C_HEADERS} DESTINATION ${C_HEADERS_DEST})
203203
204204install(FILES "${CMAKE_SOURCE_DIR}/std/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}")
205install(FILES "${CMAKE_SOURCE_DIR}/std/build.zig" DESTINATION "${ZIG_STD_DEST}")
205206install(FILES "${CMAKE_SOURCE_DIR}/std/builtin.zig" DESTINATION "${ZIG_STD_DEST}")
206207install(FILES "${CMAKE_SOURCE_DIR}/std/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}")
207208install(FILES "${CMAKE_SOURCE_DIR}/std/cstr.zig" DESTINATION "${ZIG_STD_DEST}")
......@@ -230,8 +231,6 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
230231install(FILES "${CMAKE_SOURCE_DIR}/std/rand_test.zig" DESTINATION "${ZIG_STD_DEST}")
231232install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
232233install(FILES "${CMAKE_SOURCE_DIR}/std/test_runner.zig" DESTINATION "${ZIG_STD_DEST}")
233install(FILES "${CMAKE_SOURCE_DIR}/std/test_runner_libc.zig" DESTINATION "${ZIG_STD_DEST}")
234install(FILES "${CMAKE_SOURCE_DIR}/std/test_runner_nolibc.zig" DESTINATION "${ZIG_STD_DEST}")
235234
236235add_executable(run_tests ${TEST_SOURCES})
237236target_link_libraries(run_tests)
src/all_types.hpp+3-2
......@@ -1291,6 +1291,7 @@ struct CodeGen {
12911291 HashMap<GenericFnTypeId *, FnTableEntry *, generic_fn_type_id_hash, generic_fn_type_id_eql> generic_table;
12921292 HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table;
12931293 HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table;
1294 HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> compile_vars;
12941295
12951296 ZigList<ImportTableEntry *> import_queue;
12961297 size_t import_queue_index;
......@@ -1346,8 +1347,8 @@ struct CodeGen {
13461347 bool is_static;
13471348 bool strip_debug_symbols;
13481349 bool want_h_file;
1349 bool have_exported_main;
1350 bool have_exported_panic;
1350 bool have_pub_main;
1351 bool have_pub_panic;
13511352 bool link_libc;
13521353 Buf *libc_lib_dir;
13531354 Buf *libc_static_lib_dir;
src/analyze.cpp+2-2
......@@ -2878,9 +2878,9 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
28782878
28792879 if (is_pub) {
28802880 if (buf_eql_str(proto_name, "main")) {
2881 g->have_exported_main = true;
2881 g->have_pub_main = true;
28822882 } else if (buf_eql_str(proto_name, "panic")) {
2883 g->have_exported_panic = true;
2883 g->have_pub_panic = true;
28842884 }
28852885 }
28862886 }
src/codegen.cpp+36-7
......@@ -66,6 +66,7 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
6666 g->generic_table.init(16);
6767 g->llvm_fn_table.init(16);
6868 g->memoized_fn_eval_table.init(16);
69 g->compile_vars.init(16);
6970 g->is_release_build = false;
7071 g->is_test_build = false;
7172 g->want_h_file = true;
......@@ -191,9 +192,8 @@ void codegen_add_rpath(CodeGen *g, const char *name) {
191192void codegen_add_link_lib(CodeGen *g, const char *lib) {
192193 if (strcmp(lib, "c") == 0) {
193194 g->link_libc = true;
194 } else {
195 g->link_libs.append(buf_create_from_str(lib));
196195 }
196 g->link_libs.append(buf_create_from_str(lib));
197197}
198198
199199void codegen_add_framework(CodeGen *g, const char *framework) {
......@@ -4057,6 +4057,36 @@ static void define_builtin_fns(CodeGen *g) {
40574057 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
40584058}
40594059
4060static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {
4061 g->compile_vars.put_unique(buf_create_from_str(name), value);
4062}
4063
4064static void define_builtin_compile_vars(CodeGen *g) {
4065 add_compile_var(g, "is_big_endian", create_const_bool(g, g->is_big_endian));
4066 add_compile_var(g, "is_release", create_const_bool(g, g->is_release_build));
4067 add_compile_var(g, "is_test", create_const_bool(g, g->is_test_build));
4068 add_compile_var(g, "os", create_const_enum_tag(g->builtin_types.entry_os_enum, g->target_os_index));
4069 add_compile_var(g, "arch", create_const_enum_tag(g->builtin_types.entry_arch_enum, g->target_arch_index));
4070 add_compile_var(g, "environ", create_const_enum_tag(g->builtin_types.entry_environ_enum, g->target_environ_index));
4071 add_compile_var(g, "object_format", create_const_enum_tag(
4072 g->builtin_types.entry_oformat_enum, g->target_oformat_index));
4073
4074 {
4075 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
4076 ConstExprValue *const_val = allocate<ConstExprValue>(1);
4077 const_val->special = ConstValSpecialStatic;
4078 const_val->type = get_array_type(g, str_type, g->link_libs.length);
4079 const_val->data.x_array.elements = allocate<ConstExprValue>(g->link_libs.length);
4080 for (size_t i = 0; i < g->link_libs.length; i += 1) {
4081 Buf *link_lib_buf = g->link_libs.at(i);
4082 ConstExprValue *array_val = create_const_str_lit(g, link_lib_buf);
4083 init_const_slice(g, &const_val->data.x_array.elements[i], array_val, 0, buf_len(link_lib_buf), true);
4084 }
4085
4086 add_compile_var(g, "link_libs", const_val);
4087 }
4088}
4089
40604090static void init(CodeGen *g, Buf *source_path) {
40614091 g->module = LLVMModuleCreateWithName(buf_ptr(source_path));
40624092
......@@ -4120,6 +4150,7 @@ static void init(CodeGen *g, Buf *source_path) {
41204150
41214151 define_builtin_types(g);
41224152 define_builtin_fns(g);
4153 define_builtin_compile_vars(g);
41234154
41244155 g->invalid_instruction = allocate<IrInstruction>(1);
41254156 g->invalid_instruction->value.type = g->builtin_types.entry_invalid;
......@@ -4209,12 +4240,10 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou
42094240 assert(g->root_out_name);
42104241 assert(g->out_type != OutTypeUnknown);
42114242
4212 if (!g->link_libc && !g->is_test_build) {
4213 if (g->have_exported_main && (g->out_type == OutTypeObj || g->out_type == OutTypeExe)) {
4214 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g), "bootstrap.zig");
4215 }
4243 if (!g->is_test_build && g->have_pub_main && (g->out_type == OutTypeObj || g->out_type == OutTypeExe)) {
4244 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g), "bootstrap.zig");
42164245 }
4217 if (!g->have_exported_panic) {
4246 if (!g->have_pub_panic) {
42184247 g->panic_package = create_panic_pkg(g);
42194248 add_special_code(g, g->panic_package, "panic.zig");
42204249 }
src/ir.cpp+4-21
......@@ -9869,27 +9869,10 @@ static TypeTableEntry *ir_analyze_instruction_compile_var(IrAnalyze *ira,
98699869 return ira->codegen->builtin_types.entry_invalid;
98709870
98719871 ConstExprValue *out_val = ir_build_const_from(ira, &compile_var_instruction->base);
9872 if (buf_eql_str(var_name, "is_big_endian")) {
9873 out_val->data.x_bool = ira->codegen->is_big_endian;
9874 return ira->codegen->builtin_types.entry_bool;
9875 } else if (buf_eql_str(var_name, "is_release")) {
9876 out_val->data.x_bool = ira->codegen->is_release_build;
9877 return ira->codegen->builtin_types.entry_bool;
9878 } else if (buf_eql_str(var_name, "is_test")) {
9879 out_val->data.x_bool = ira->codegen->is_test_build;
9880 return ira->codegen->builtin_types.entry_bool;
9881 } else if (buf_eql_str(var_name, "os")) {
9882 out_val->data.x_enum.tag = ira->codegen->target_os_index;
9883 return ira->codegen->builtin_types.entry_os_enum;
9884 } else if (buf_eql_str(var_name, "arch")) {
9885 out_val->data.x_enum.tag = ira->codegen->target_arch_index;
9886 return ira->codegen->builtin_types.entry_arch_enum;
9887 } else if (buf_eql_str(var_name, "environ")) {
9888 out_val->data.x_enum.tag = ira->codegen->target_environ_index;
9889 return ira->codegen->builtin_types.entry_environ_enum;
9890 } else if (buf_eql_str(var_name, "object_format")) {
9891 out_val->data.x_enum.tag = ira->codegen->target_oformat_index;
9892 return ira->codegen->builtin_types.entry_oformat_enum;
9872 auto entry = ira->codegen->compile_vars.maybe_get(var_name);
9873 if (entry) {
9874 *out_val = *entry->value;
9875 return out_val->type;
98939876 } else {
98949877 ir_add_error_node(ira, name_value->source_node,
98959878 buf_sprintf("unrecognized compile variable: '%s'", buf_ptr(var_name)));
src/link.cpp+21-6
......@@ -47,6 +47,12 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
4747 ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target;
4848 CodeGen *child_gen = codegen_create(std_dir_path, child_target);
4949 child_gen->link_libc = parent_gen->link_libc;
50
51 child_gen->link_libs.resize(parent_gen->link_libs.length);
52 for (size_t i = 0; i < parent_gen->link_libs.length; i += 1) {
53 child_gen->link_libs.items[i] = parent_gen->link_libs.items[i];
54 }
55
5056 child_gen->want_h_file = false;
5157
5258 codegen_set_is_release(child_gen, parent_gen->is_release_build);
......@@ -223,6 +229,9 @@ static void construct_linker_job_elf(LinkJob *lj) {
223229 const char *lib_dir = g->lib_dirs.at(i);
224230 for (size_t i = 0; i < g->link_libs.length; i += 1) {
225231 Buf *link_lib = g->link_libs.at(i);
232 if (buf_eql_str(link_lib, "c")) {
233 continue;
234 }
226235 bool does_exist;
227236 Buf *test_path = buf_sprintf("%s/lib%s.so", lib_dir, buf_ptr(link_lib));
228237 if (os_file_exists(test_path, &does_exist) != ErrorNone) {
......@@ -267,8 +276,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
267276 lj->args.append((const char *)buf_ptr(&lj->out_file_o));
268277
269278 if (g->is_test_build) {
270 const char *test_runner_name = g->link_libc ? "test_runner_libc" : "test_runner_nolibc";
271 Buf *test_runner_o_path = build_o(g, test_runner_name);
279 Buf *test_runner_o_path = build_o(g, "test_runner");
272280 lj->args.append(buf_ptr(test_runner_o_path));
273281 }
274282
......@@ -282,6 +290,9 @@ static void construct_linker_job_elf(LinkJob *lj) {
282290
283291 for (size_t i = 0; i < g->link_libs.length; i += 1) {
284292 Buf *link_lib = g->link_libs.at(i);
293 if (buf_eql_str(link_lib, "c")) {
294 continue;
295 }
285296 Buf *arg;
286297 if (buf_starts_with_str(link_lib, "/") || buf_ends_with_str(link_lib, ".a") ||
287298 buf_ends_with_str(link_lib, ".so"))
......@@ -408,8 +419,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
408419 lj->args.append((const char *)buf_ptr(&lj->out_file_o));
409420
410421 if (g->is_test_build) {
411 const char *test_runner_name = g->link_libc ? "test_runner_libc" : "test_runner_nolibc";
412 Buf *test_runner_o_path = build_o(g, test_runner_name);
422 Buf *test_runner_o_path = build_o(g, "test_runner");
413423 lj->args.append(buf_ptr(test_runner_o_path));
414424 }
415425
......@@ -424,6 +434,9 @@ static void construct_linker_job_coff(LinkJob *lj) {
424434
425435 for (size_t i = 0; i < g->link_libs.length; i += 1) {
426436 Buf *link_lib = g->link_libs.at(i);
437 if (buf_eql_str(link_lib, "c")) {
438 continue;
439 }
427440 Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib));
428441 lj->args.append(buf_ptr(arg));
429442 }
......@@ -685,13 +698,15 @@ static void construct_linker_job_macho(LinkJob *lj) {
685698 lj->args.append((const char *)buf_ptr(&lj->out_file_o));
686699
687700 if (g->is_test_build) {
688 const char *test_runner_name = g->link_libc ? "test_runner_libc" : "test_runner_nolibc";
689 Buf *test_runner_o_path = build_o(g, test_runner_name);
701 Buf *test_runner_o_path = build_o(g, "test_runner");
690702 lj->args.append(buf_ptr(test_runner_o_path));
691703 }
692704
693705 for (size_t i = 0; i < g->link_libs.length; i += 1) {
694706 Buf *link_lib = g->link_libs.at(i);
707 if (buf_eql_str(link_lib, "c")) {
708 continue;
709 }
695710 Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib));
696711 lj->args.append(buf_ptr(arg));
697712 }
std/bootstrap.zig+4-5
......@@ -1,17 +1,16 @@
11// This file is in a package which has the root source file exposed as "@root".
2// It is included in the compilation unit when exporting an executable.
23
34const root = @import("@root");
45const std = @import("std");
56
6const want_start_symbol = switch(@compileVar("os")) {
7 Os.linux => true,
8 else => false,
9};
10const want_main_symbol = !want_start_symbol;
7const want_main_symbol = std.build.linkingLibrary("c");
8const want_start_symbol = !want_main_symbol;
119
1210const exit = switch(@compileVar("os")) {
1311 Os.linux => std.linux.exit,
1412 Os.darwin => std.darwin.exit,
13 else => @compileError("Unsupported OS"),
1514};
1615
1716var argc: usize = undefined;
std/build.zig created+13
......@@ -0,0 +1,13 @@
1const mem = @import("mem.zig");
2
3pub fn linkingLibrary(lib_name: []const u8) -> bool {
4 // TODO shouldn't need this if
5 if (@compileVar("link_libs").len != 0) {
6 for (@compileVar("link_libs")) |link_lib| {
7 if (mem.eql(u8, link_lib, lib_name)) {
8 return true;
9 }
10 }
11 }
12 return false;
13}
std/index.zig+1
......@@ -1,3 +1,4 @@
1pub const build = @import("build.zig");
12pub const cstr = @import("cstr.zig");
23pub const debug = @import("debug.zig");
34pub const fmt = @import("fmt.zig");
std/test_runner.zig+1-1
......@@ -7,7 +7,7 @@ const TestFn = struct {
77
88extern var zig_test_fn_list: []TestFn;
99
10pub fn runTests() -> %void {
10pub fn main(args: [][]u8) -> %void {
1111 for (zig_test_fn_list) |testFn, i| {
1212 %%io.stderr.printf("Test {}/{} {}...", i + 1, zig_test_fn_list.len, testFn.name);
1313
std/test_runner_libc.zig deleted-6
......@@ -1,6 +0,0 @@
1const test_runner = @import("test_runner.zig");
2
3export fn main(argc: c_int, argv: &&u8) -> c_int {
4 test_runner.runTests() %% return -1;
5 return 0;
6}
std/test_runner_nolibc.zig deleted-5
......@@ -1,5 +0,0 @@
1const test_runner = @import("test_runner.zig");
2
3pub fn main(args: [][]u8) -> %void {
4 return test_runner.runTests();
5}