authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-16 13:56:56-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-16 13:56:56-04:00
log81e960eb748fdb37d1d61da262ec343e2fdb2511
treeed4059af1ce6181457887bbfbf98a17b3bbfcf44
parent07d0aee11a5725dc22eeaa116fb59c40a1a7c99c
signaturelock-open Commit is signed but in an unrecognized format.

improvements to build-lib use case of WebAssembly

* 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) {
85488548 }
85498549 report_errors_and_maybe_exit(g);
85508550
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)) &&
85528552 g->zig_target->os != OsUefi &&
85538553 !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup &&
85548554 ((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,
800800 return &child_gen->output_file_path;
801801}
802802
803static Buf *build_a(CodeGen *parent_gen, const char *aname) {
804 Buf *source_basename = buf_sprintf("%s.zig", aname);
803static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) {
805804 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);
807806
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);
809808}
810809
811static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) {
810static Buf *build_c(CodeGen *parent_gen, OutType child_out_type) {
812811 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);
814813
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);
816815}
817816
818817static const char *get_darwin_arch_string(const ZigTarget *t) {
......@@ -1003,7 +1002,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
10031002
10041003 if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) {
10051004 if (g->libc_link_lib == nullptr) {
1006 Buf *libc_a_path = build_a(g, "c");
1005 Buf *libc_a_path = build_c(g, OutTypeLib);
10071006 lj->args.append(buf_ptr(libc_a_path));
10081007 }
10091008
......@@ -1118,10 +1117,10 @@ static void construct_linker_job_wasm(LinkJob *lj) {
11181117 }
11191118
11201119 if (g->out_type != OutTypeObj) {
1121 Buf *libc_a_path = build_a(g, "c");
1122 lj->args.append(buf_ptr(libc_a_path));
1120 Buf *libc_o_path = build_c(g, OutTypeObj);
1121 lj->args.append(buf_ptr(libc_o_path));
11231122
1124 Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
1123 Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj);
11251124 lj->args.append(buf_ptr(compiler_rt_o_path));
11261125 }
11271126}
......@@ -1360,7 +1359,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
13601359
13611360 if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) {
13621361 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);
13641363 lj->args.append(buf_ptr(libc_a_path));
13651364 }
13661365
......@@ -1687,7 +1686,7 @@ void codegen_link(CodeGen *g) {
16871686 lj.args.append("-r");
16881687 }
16891688
1690 if (g->out_type == OutTypeLib && !g->is_dynamic) {
1689 if (g->out_type == OutTypeLib && !g->is_dynamic && !target_is_wasm(g->zig_target)) {
16911690 ZigList<const char *> file_names = {};
16921691 for (size_t i = 0; i < g->link_objects.length; i += 1) {
16931692 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) {
947947const char *target_o_file_ext(const ZigTarget *target) {
948948 if (target->abi == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) {
949949 return ".obj";
950 } else if (target_is_wasm(target)) {
951 return ".wasm";
952950 } else {
953951 return ".o";
954952 }
......@@ -975,7 +973,7 @@ const char *target_exe_file_ext(const ZigTarget *target) {
975973}
976974
977975const 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)) {
979977 return "";
980978 } else {
981979 return "lib";
......@@ -985,6 +983,9 @@ const char *target_lib_file_prefix(const ZigTarget *target) {
985983const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
986984 size_t version_major, size_t version_minor, size_t version_patch)
987985{
986 if (target_is_wasm(target)) {
987 return ".wasm";
988 }
988989 if (target->os == OsWindows || target->os == OsUefi) {
989990 if (is_static) {
990991 return ".lib";
std/special/bootstrap.zig+7-3
......@@ -25,21 +25,25 @@ nakedcc fn _start() noreturn {
2525 }
2626
2727 switch (builtin.arch) {
28 builtin.Arch.x86_64 => {
28 .x86_64 => {
2929 argc_ptr = asm ("lea (%%rsp), %[argc]"
3030 : [argc] "=r" (-> [*]usize)
3131 );
3232 },
33 builtin.Arch.i386 => {
33 .i386 => {
3434 argc_ptr = asm ("lea (%%esp), %[argc]"
3535 : [argc] "=r" (-> [*]usize)
3636 );
3737 },
38 builtin.Arch.aarch64, builtin.Arch.aarch64_be => {
38 .aarch64, .aarch64_be => {
3939 argc_ptr = asm ("mov %[argc], sp"
4040 : [argc] "=r" (-> [*]usize)
4141 );
4242 },
43 .wasm32, .wasm64 => {
44 _ = callMain();
45 while (true) {}
46 },
4347 else => @compileError("unsupported arch"),
4448 }
4549 // 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;
1111const is_wasm = switch (builtin.arch) { .wasm32, .wasm64 => true, else => false};
1212const is_freestanding = switch (builtin.os) { .freestanding => true, else => false };
1313comptime {
14 if (is_freestanding and is_wasm) {
14 if (is_freestanding and is_wasm and builtin.link_libc) {
1515 @export("_start", wasm_start, .Strong);
1616 }
1717}