Skip to content

Commit

Permalink
Merge pull request #2507 from ziglang/wasm-libs
Browse files Browse the repository at this point in the history
improvements to build-lib use case of WebAssembly
  • Loading branch information
andrewrk committed May 16, 2019
2 parents 07d0aee + 978fab8 commit 8468ff0
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
25 changes: 12 additions & 13 deletions src/link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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));
}

Expand Down Expand Up @@ -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));
}
}
Expand Down Expand Up @@ -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));
}

Expand Down Expand Up @@ -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)));
Expand Down
7 changes: 4 additions & 3 deletions src/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Expand All @@ -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";
Expand All @@ -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";
Expand Down
23 changes: 15 additions & 8 deletions std/special/bootstrap.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);
Expand Down
6 changes: 3 additions & 3 deletions std/special/c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 8468ff0

Please sign in to comment.