zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 8468ff0fe1466d8b38aff1d265d953b5cc8fefe6 (tree)
parent 07d0aee11a5725dc22eeaa116fb59c40a1a7c99c
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Thu, 16 May 2019 14:31:54 -0400

Merge pull request #2507 from ziglang/wasm-libs

improvements to build-lib use case of WebAssembly
Diffstat:
Msrc/codegen.cpp | 2+-
Msrc/link.cpp | 25++++++++++++-------------
Msrc/target.cpp | 7++++---
Mstd/special/bootstrap.zig | 23+++++++++++++++--------
Mstd/special/c.zig | 6+++---
5 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/src/codegen.cpp b/src/codegen.cpp @@ -8548,7 +8548,7 @@ static void gen_root_source(CodeGen *g) { } report_errors_and_maybe_exit(g); - if (!g->is_test_build && g->zig_target->os != OsFreestanding && + if (!g->is_test_build && (g->zig_target->os != OsFreestanding || target_is_wasm(g->zig_target)) && g->zig_target->os != OsUefi && !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) diff --git a/src/link.cpp b/src/link.cpp @@ -800,19 +800,18 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, return &child_gen->output_file_path; } -static Buf *build_a(CodeGen *parent_gen, const char *aname) { - Buf *source_basename = buf_sprintf("%s.zig", aname); +static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) { Buf *full_path = buf_alloc(); - os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path); + os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path); - return build_a_raw(parent_gen, aname, full_path, OutTypeLib); + return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type); } -static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) { +static Buf *build_c(CodeGen *parent_gen, OutType child_out_type) { Buf *full_path = buf_alloc(); - os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path); + os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("c.zig"), full_path); - return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type); + return build_a_raw(parent_gen, "c", full_path, child_out_type); } static const char *get_darwin_arch_string(const ZigTarget *t) { @@ -1003,7 +1002,7 @@ static void construct_linker_job_elf(LinkJob *lj) { if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) { if (g->libc_link_lib == nullptr) { - Buf *libc_a_path = build_a(g, "c"); + Buf *libc_a_path = build_c(g, OutTypeLib); lj->args.append(buf_ptr(libc_a_path)); } @@ -1118,10 +1117,10 @@ static void construct_linker_job_wasm(LinkJob *lj) { } if (g->out_type != OutTypeObj) { - Buf *libc_a_path = build_a(g, "c"); - lj->args.append(buf_ptr(libc_a_path)); + Buf *libc_o_path = build_c(g, OutTypeObj); + lj->args.append(buf_ptr(libc_o_path)); - Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib); + Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj); lj->args.append(buf_ptr(compiler_rt_o_path)); } } @@ -1360,7 +1359,7 @@ static void construct_linker_job_coff(LinkJob *lj) { if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) { if (g->libc_link_lib == nullptr && !g->is_dummy_so) { - Buf *libc_a_path = build_a(g, "c"); + Buf *libc_a_path = build_c(g, OutTypeLib); lj->args.append(buf_ptr(libc_a_path)); } @@ -1687,7 +1686,7 @@ void codegen_link(CodeGen *g) { lj.args.append("-r"); } - if (g->out_type == OutTypeLib && !g->is_dynamic) { + if (g->out_type == OutTypeLib && !g->is_dynamic && !target_is_wasm(g->zig_target)) { ZigList<const char *> file_names = {}; for (size_t i = 0; i < g->link_objects.length; i += 1) { file_names.append(buf_ptr(g->link_objects.at(i))); diff --git a/src/target.cpp b/src/target.cpp @@ -947,8 +947,6 @@ bool target_allows_addr_zero(const ZigTarget *target) { const char *target_o_file_ext(const ZigTarget *target) { if (target->abi == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) { return ".obj"; - } else if (target_is_wasm(target)) { - return ".wasm"; } else { return ".o"; } @@ -975,7 +973,7 @@ const char *target_exe_file_ext(const ZigTarget *target) { } const char *target_lib_file_prefix(const ZigTarget *target) { - if (target->os == OsWindows || target->os == OsUefi) { + if (target->os == OsWindows || target->os == OsUefi || target_is_wasm(target)) { return ""; } else { return "lib"; @@ -985,6 +983,9 @@ const char *target_lib_file_prefix(const ZigTarget *target) { const char *target_lib_file_ext(const ZigTarget *target, bool is_static, size_t version_major, size_t version_minor, size_t version_patch) { + if (target_is_wasm(target)) { + return ".wasm"; + } if (target->os == OsWindows || target->os == OsUefi) { if (is_static) { return ".lib"; diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig @@ -8,34 +8,41 @@ const assert = std.debug.assert; var argc_ptr: [*]usize = undefined; +const is_wasm = switch (builtin.arch) { .wasm32, .wasm64 => true, else => false}; + comptime { - const strong_linkage = builtin.GlobalLinkage.Strong; if (builtin.link_libc) { - @export("main", main, strong_linkage); - } else if (builtin.os == builtin.Os.windows) { - @export("WinMainCRTStartup", WinMainCRTStartup, strong_linkage); + @export("main", main, .Strong); + } else if (builtin.os == .windows) { + @export("WinMainCRTStartup", WinMainCRTStartup, .Strong); + } else if (is_wasm and builtin.os == .freestanding) { + @export("_start", wasm_freestanding_start, .Strong); } else { - @export("_start", _start, strong_linkage); + @export("_start", _start, .Strong); } } +extern fn wasm_freestanding_start() void { + _ = callMain(); +} + nakedcc fn _start() noreturn { if (builtin.os == builtin.Os.wasi) { std.os.wasi.proc_exit(callMain()); } switch (builtin.arch) { - builtin.Arch.x86_64 => { + .x86_64 => { argc_ptr = asm ("lea (%%rsp), %[argc]" : [argc] "=r" (-> [*]usize) ); }, - builtin.Arch.i386 => { + .i386 => { argc_ptr = asm ("lea (%%esp), %[argc]" : [argc] "=r" (-> [*]usize) ); }, - builtin.Arch.aarch64, builtin.Arch.aarch64_be => { + .aarch64, .aarch64_be => { argc_ptr = asm ("mov %[argc], sp" : [argc] "=r" (-> [*]usize) ); diff --git a/std/special/c.zig b/std/special/c.zig @@ -11,14 +11,14 @@ const maxInt = std.math.maxInt; const is_wasm = switch (builtin.arch) { .wasm32, .wasm64 => true, else => false}; const is_freestanding = switch (builtin.os) { .freestanding => true, else => false }; comptime { - if (is_freestanding and is_wasm) { + if (is_freestanding and is_wasm and builtin.link_libc) { @export("_start", wasm_start, .Strong); } } extern fn main(argc: c_int, argv: [*][*]u8) c_int; -extern fn wasm_start() c_int { - return main(0, undefined); +extern fn wasm_start() void { + _ = main(0, undefined); } // Avoid dragging in the runtime safety mechanisms into this .o file,