| author | |
| committer | |
| log | 81e960eb748fdb37d1d61da262ec343e2fdb2511 |
| tree | ed4059af1ce6181457887bbfbf98a17b3bbfcf44 |
| parent | 07d0aee11a5725dc22eeaa116fb59c40a1a7c99c |
| signature | Commit is signed but in an unrecognized format. |
* build-exe does include the startup code that supplies _start for the
wasm32-freestanding target. Previously this did not occur because
of logic excluding "freestanding".
* build-lib for wasm32-freestanding target gets linked by LLD. To avoid
infinite recursion, compiler_rt and zig libc are built as objects
rather than libraries.
- no "lib" prefix and ".wasm" extension instead of ".a". Rather than
build-lib foo.zig producing "libfoo.a", now it produces "foo.wasm".
* go back to using `.o` extension for webassembly objects
* zig libc only provides _start symbol for wasm when linking libc.5 files changed, 25 insertions(+), 21 deletions(-)
src/codegen.cpp+1-1| ... | @@ -8548,7 +8548,7 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -8548,7 +8548,7 @@ static void gen_root_source(CodeGen *g) { |
| 8548 | } | 8548 | } |
| 8549 | report_errors_and_maybe_exit(g); | 8549 | report_errors_and_maybe_exit(g); |
| 8550 | 8550 | ||
| 8551 | if (!g->is_test_build && g->zig_target->os != OsFreestanding && | 8551 | if (!g->is_test_build && (g->zig_target->os != OsFreestanding || target_is_wasm(g->zig_target)) && |
| 8552 | g->zig_target->os != OsUefi && | 8552 | g->zig_target->os != OsUefi && |
| 8553 | !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && | 8553 | !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && |
| 8554 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) | 8554 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) |
src/link.cpp+12-13| ... | @@ -800,19 +800,18 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, | ... | @@ -800,19 +800,18 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, |
| 800 | return &child_gen->output_file_path; | 800 | return &child_gen->output_file_path; |
| 801 | } | 801 | } |
| 802 | 802 | ||
| 803 | static Buf *build_a(CodeGen *parent_gen, const char *aname) { | 803 | static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) { |
| 804 | Buf *source_basename = buf_sprintf("%s.zig", aname); | ||
| 805 | Buf *full_path = buf_alloc(); | 804 | Buf *full_path = buf_alloc(); |
| 806 | os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path); | 805 | os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path); |
| 807 | 806 | ||
| 808 | return build_a_raw(parent_gen, aname, full_path, OutTypeLib); | 807 | return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type); |
| 809 | } | 808 | } |
| 810 | 809 | ||
| 811 | static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) { | 810 | static Buf *build_c(CodeGen *parent_gen, OutType child_out_type) { |
| 812 | Buf *full_path = buf_alloc(); | 811 | Buf *full_path = buf_alloc(); |
| 813 | os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path); | 812 | os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("c.zig"), full_path); |
| 814 | 813 | ||
| 815 | return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type); | 814 | return build_a_raw(parent_gen, "c", full_path, child_out_type); |
| 816 | } | 815 | } |
| 817 | 816 | ||
| 818 | static const char *get_darwin_arch_string(const ZigTarget *t) { | 817 | static const char *get_darwin_arch_string(const ZigTarget *t) { |
| ... | @@ -1003,7 +1002,7 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -1003,7 +1002,7 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1003 | 1002 | ||
| 1004 | if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) { | 1003 | if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) { |
| 1005 | if (g->libc_link_lib == nullptr) { | 1004 | if (g->libc_link_lib == nullptr) { |
| 1006 | Buf *libc_a_path = build_a(g, "c"); | 1005 | Buf *libc_a_path = build_c(g, OutTypeLib); |
| 1007 | lj->args.append(buf_ptr(libc_a_path)); | 1006 | lj->args.append(buf_ptr(libc_a_path)); |
| 1008 | } | 1007 | } |
| 1009 | 1008 | ||
| ... | @@ -1118,10 +1117,10 @@ static void construct_linker_job_wasm(LinkJob *lj) { | ... | @@ -1118,10 +1117,10 @@ static void construct_linker_job_wasm(LinkJob *lj) { |
| 1118 | } | 1117 | } |
| 1119 | 1118 | ||
| 1120 | if (g->out_type != OutTypeObj) { | 1119 | if (g->out_type != OutTypeObj) { |
| 1121 | Buf *libc_a_path = build_a(g, "c"); | 1120 | Buf *libc_o_path = build_c(g, OutTypeObj); |
| 1122 | lj->args.append(buf_ptr(libc_a_path)); | 1121 | lj->args.append(buf_ptr(libc_o_path)); |
| 1123 | 1122 | ||
| 1124 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib); | 1123 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj); |
| 1125 | lj->args.append(buf_ptr(compiler_rt_o_path)); | 1124 | lj->args.append(buf_ptr(compiler_rt_o_path)); |
| 1126 | } | 1125 | } |
| 1127 | } | 1126 | } |
| ... | @@ -1360,7 +1359,7 @@ static void construct_linker_job_coff(LinkJob *lj) { | ... | @@ -1360,7 +1359,7 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 1360 | 1359 | ||
| 1361 | if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) { | 1360 | if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) { |
| 1362 | if (g->libc_link_lib == nullptr && !g->is_dummy_so) { | 1361 | if (g->libc_link_lib == nullptr && !g->is_dummy_so) { |
| 1363 | Buf *libc_a_path = build_a(g, "c"); | 1362 | Buf *libc_a_path = build_c(g, OutTypeLib); |
| 1364 | lj->args.append(buf_ptr(libc_a_path)); | 1363 | lj->args.append(buf_ptr(libc_a_path)); |
| 1365 | } | 1364 | } |
| 1366 | 1365 | ||
| ... | @@ -1687,7 +1686,7 @@ void codegen_link(CodeGen *g) { | ... | @@ -1687,7 +1686,7 @@ void codegen_link(CodeGen *g) { |
| 1687 | lj.args.append("-r"); | 1686 | lj.args.append("-r"); |
| 1688 | } | 1687 | } |
| 1689 | 1688 | ||
| 1690 | if (g->out_type == OutTypeLib && !g->is_dynamic) { | 1689 | if (g->out_type == OutTypeLib && !g->is_dynamic && !target_is_wasm(g->zig_target)) { |
| 1691 | ZigList<const char *> file_names = {}; | 1690 | ZigList<const char *> file_names = {}; |
| 1692 | for (size_t i = 0; i < g->link_objects.length; i += 1) { | 1691 | for (size_t i = 0; i < g->link_objects.length; i += 1) { |
| 1693 | file_names.append(buf_ptr(g->link_objects.at(i))); | 1692 | file_names.append(buf_ptr(g->link_objects.at(i))); |
src/target.cpp+4-3| ... | @@ -947,8 +947,6 @@ bool target_allows_addr_zero(const ZigTarget *target) { | ... | @@ -947,8 +947,6 @@ bool target_allows_addr_zero(const ZigTarget *target) { |
| 947 | const char *target_o_file_ext(const ZigTarget *target) { | 947 | const char *target_o_file_ext(const ZigTarget *target) { |
| 948 | if (target->abi == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) { | 948 | if (target->abi == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) { |
| 949 | return ".obj"; | 949 | return ".obj"; |
| 950 | } else if (target_is_wasm(target)) { | ||
| 951 | return ".wasm"; | ||
| 952 | } else { | 950 | } else { |
| 953 | return ".o"; | 951 | return ".o"; |
| 954 | } | 952 | } |
| ... | @@ -975,7 +973,7 @@ const char *target_exe_file_ext(const ZigTarget *target) { | ... | @@ -975,7 +973,7 @@ const char *target_exe_file_ext(const ZigTarget *target) { |
| 975 | } | 973 | } |
| 976 | 974 | ||
| 977 | const char *target_lib_file_prefix(const ZigTarget *target) { | 975 | const char *target_lib_file_prefix(const ZigTarget *target) { |
| 978 | if (target->os == OsWindows || target->os == OsUefi) { | 976 | if (target->os == OsWindows || target->os == OsUefi || target_is_wasm(target)) { |
| 979 | return ""; | 977 | return ""; |
| 980 | } else { | 978 | } else { |
| 981 | return "lib"; | 979 | return "lib"; |
| ... | @@ -985,6 +983,9 @@ const char *target_lib_file_prefix(const ZigTarget *target) { | ... | @@ -985,6 +983,9 @@ const char *target_lib_file_prefix(const ZigTarget *target) { |
| 985 | const char *target_lib_file_ext(const ZigTarget *target, bool is_static, | 983 | const char *target_lib_file_ext(const ZigTarget *target, bool is_static, |
| 986 | size_t version_major, size_t version_minor, size_t version_patch) | 984 | size_t version_major, size_t version_minor, size_t version_patch) |
| 987 | { | 985 | { |
| 986 | if (target_is_wasm(target)) { | ||
| 987 | return ".wasm"; | ||
| 988 | } | ||
| 988 | if (target->os == OsWindows || target->os == OsUefi) { | 989 | if (target->os == OsWindows || target->os == OsUefi) { |
| 989 | if (is_static) { | 990 | if (is_static) { |
| 990 | return ".lib"; | 991 | return ".lib"; |
std/special/bootstrap.zig+7-3| ... | @@ -25,21 +25,25 @@ nakedcc fn _start() noreturn { | ... | @@ -25,21 +25,25 @@ nakedcc fn _start() noreturn { |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | switch (builtin.arch) { | 27 | switch (builtin.arch) { |
| 28 | builtin.Arch.x86_64 => { | 28 | .x86_64 => { |
| 29 | argc_ptr = asm ("lea (%%rsp), %[argc]" | 29 | argc_ptr = asm ("lea (%%rsp), %[argc]" |
| 30 | : [argc] "=r" (-> [*]usize) | 30 | : [argc] "=r" (-> [*]usize) |
| 31 | ); | 31 | ); |
| 32 | }, | 32 | }, |
| 33 | builtin.Arch.i386 => { | 33 | .i386 => { |
| 34 | argc_ptr = asm ("lea (%%esp), %[argc]" | 34 | argc_ptr = asm ("lea (%%esp), %[argc]" |
| 35 | : [argc] "=r" (-> [*]usize) | 35 | : [argc] "=r" (-> [*]usize) |
| 36 | ); | 36 | ); |
| 37 | }, | 37 | }, |
| 38 | builtin.Arch.aarch64, builtin.Arch.aarch64_be => { | 38 | .aarch64, .aarch64_be => { |
| 39 | argc_ptr = asm ("mov %[argc], sp" | 39 | argc_ptr = asm ("mov %[argc], sp" |
| 40 | : [argc] "=r" (-> [*]usize) | 40 | : [argc] "=r" (-> [*]usize) |
| 41 | ); | 41 | ); |
| 42 | }, | 42 | }, |
| 43 | .wasm32, .wasm64 => { | ||
| 44 | _ = callMain(); | ||
| 45 | while (true) {} | ||
| 46 | }, | ||
| 43 | else => @compileError("unsupported arch"), | 47 | else => @compileError("unsupported arch"), |
| 44 | } | 48 | } |
| 45 | // If LLVM inlines stack variables into _start, they will overwrite | 49 | // If LLVM inlines stack variables into _start, they will overwrite |
std/special/c.zig+1-1| ... | @@ -11,7 +11,7 @@ const maxInt = std.math.maxInt; | ... | @@ -11,7 +11,7 @@ const maxInt = std.math.maxInt; |
| 11 | const is_wasm = switch (builtin.arch) { .wasm32, .wasm64 => true, else => false}; | 11 | const is_wasm = switch (builtin.arch) { .wasm32, .wasm64 => true, else => false}; |
| 12 | const is_freestanding = switch (builtin.os) { .freestanding => true, else => false }; | 12 | const is_freestanding = switch (builtin.os) { .freestanding => true, else => false }; |
| 13 | comptime { | 13 | comptime { |
| 14 | if (is_freestanding and is_wasm) { | 14 | if (is_freestanding and is_wasm and builtin.link_libc) { |
| 15 | @export("_start", wasm_start, .Strong); | 15 | @export("_start", wasm_start, .Strong); |
| 16 | } | 16 | } |
| 17 | } | 17 | } |