Commit 14cdb01f35
Changed files (4)
src/link.cpp
@@ -776,8 +776,8 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, OutType child_out_type) {
// The Mach-O LLD code is not well maintained, and trips an assertion
- // when we link compiler_rt and builtin as libraries rather than objects.
- // Here we workaround this by having compiler_rt and builtin be objects.
+ // when we link compiler_rt and libc.zig as libraries rather than objects.
+ // Here we workaround this by having compiler_rt and libc.zig be objects.
// TODO write our own linker. https://github.com/ziglang/zig/issues/1535
if (parent_gen->zig_target->os == OsMacOSX) {
child_out_type = OutTypeObj;
@@ -787,7 +787,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,
parent_gen->libc);
codegen_set_out_name(child_gen, buf_create_from_str(aname));
- // This is so that compiler_rt and builtin libraries know whether they
+ // This is so that compiler_rt and libc.zig libraries know whether they
// will eventually be linked with libc. They make different decisions
// about what to export depending on whether libc is linked.
if (parent_gen->libc_link_lib != nullptr) {
@@ -1002,8 +1002,8 @@ 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 *builtin_a_path = build_a(g, "builtin");
- lj->args.append(buf_ptr(builtin_a_path));
+ Buf *libc_a_path = build_a(g, "c");
+ lj->args.append(buf_ptr(libc_a_path));
}
Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
@@ -1092,30 +1092,33 @@ static void construct_linker_job_wasm(LinkJob *lj) {
lj->args.append("-error-limit=0");
- if (g->zig_target->os != OsWASI) {
- lj->args.append("--no-entry"); // So lld doesn't look for _start.
+ if (g->out_type != OutTypeExe) {
+ lj->args.append("--no-entry"); // So lld doesn't look for _start.
+
+ // If there are any C source files we cannot rely on individual exports.
+ if (g->c_source_files.length != 0) {
+ lj->args.append("--export-all");
+ } else {
+ auto export_it = g->exported_symbol_names.entry_iterator();
+ decltype(g->exported_symbol_names)::Entry *curr_entry = nullptr;
+ while ((curr_entry = export_it.next()) != nullptr) {
+ Buf *arg = buf_sprintf("--export=%s", buf_ptr(curr_entry->key));
+ lj->args.append(buf_ptr(arg));
+ }
+ }
}
lj->args.append("--allow-undefined");
lj->args.append("-o");
lj->args.append(buf_ptr(&g->output_file_path));
- auto export_it = g->exported_symbol_names.entry_iterator();
- decltype(g->exported_symbol_names)::Entry *curr_entry = nullptr;
- while ((curr_entry = export_it.next()) != nullptr) {
- Buf *arg = buf_sprintf("--export=%s", buf_ptr(curr_entry->key));
- lj->args.append(buf_ptr(arg));
- }
-
// .o files
for (size_t i = 0; i < g->link_objects.length; i += 1) {
lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
}
- if (g->out_type == OutTypeExe) {
- if (g->libc_link_lib == nullptr) {
- Buf *builtin_a_path = build_a(g, "builtin");
- lj->args.append(buf_ptr(builtin_a_path));
- }
+ if (g->out_type != OutTypeObj) {
+ Buf *libc_a_path = build_a(g, "c");
+ lj->args.append(buf_ptr(libc_a_path));
Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
lj->args.append(buf_ptr(compiler_rt_o_path));
@@ -1356,8 +1359,8 @@ 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 *builtin_a_path = build_a(g, "builtin");
- lj->args.append(buf_ptr(builtin_a_path));
+ Buf *libc_a_path = build_a(g, "c");
+ lj->args.append(buf_ptr(libc_a_path));
}
// msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage
src/target.cpp
@@ -1376,6 +1376,9 @@ bool target_is_single_threaded(const ZigTarget *target) {
}
ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) {
+ if (arch == ZigLLVM_wasm32 || arch == ZigLLVM_wasm64) {
+ return ZigLLVM_Musl;
+ }
switch (os) {
case OsFreestanding:
case OsAnanas:
@@ -1490,6 +1493,7 @@ static const AvailableLibC libcs_available[] = {
{ZigLLVM_systemz, OsLinux, ZigLLVM_Musl},
{ZigLLVM_sparc, OsLinux, ZigLLVM_GNU},
{ZigLLVM_sparcv9, OsLinux, ZigLLVM_GNU},
+ {ZigLLVM_wasm32, OsFreestanding, ZigLLVM_Musl},
{ZigLLVM_x86_64, OsLinux, ZigLLVM_GNU},
{ZigLLVM_x86_64, OsLinux, ZigLLVM_GNUX32},
{ZigLLVM_x86_64, OsLinux, ZigLLVM_Musl},
@@ -1508,7 +1512,6 @@ bool target_can_build_libc(const ZigTarget *target) {
}
const char *target_libc_generic_name(const ZigTarget *target) {
- assert(target->os == OsLinux);
switch (target->abi) {
case ZigLLVM_GNU:
case ZigLLVM_GNUABIN32:
@@ -1520,6 +1523,7 @@ const char *target_libc_generic_name(const ZigTarget *target) {
case ZigLLVM_Musl:
case ZigLLVM_MuslEABI:
case ZigLLVM_MuslEABIHF:
+ case ZigLLVM_UnknownEnvironment:
return "musl";
case ZigLLVM_CODE16:
case ZigLLVM_EABI:
@@ -1530,7 +1534,6 @@ const char *target_libc_generic_name(const ZigTarget *target) {
case ZigLLVM_Cygnus:
case ZigLLVM_CoreCLR:
case ZigLLVM_Simulator:
- case ZigLLVM_UnknownEnvironment:
zig_unreachable();
}
zig_unreachable();
std/special/builtin.zig → std/special/c.zig
@@ -1,10 +1,26 @@
-// These functions are provided when not linking against libc because LLVM
-// sometimes generates code that calls them.
+// This is Zig's multi-target implementation of libc.
+// When builtin.link_libc is true, we need to export all the functions and
+// provide an entire C API.
+// Otherwise, only the functions which LLVM generates calls to need to be generated,
+// such as memcpy, memset, and some math functions.
const std = @import("std");
const builtin = @import("builtin");
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) {
+ @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);
+}
+
// Avoid dragging in the runtime safety mechanisms into this .o file,
// unless we're trying to test this file.
pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
CMakeLists.txt
@@ -643,7 +643,7 @@ set(ZIG_STD_FILES
"special/bootstrap_lib.zig"
"special/bootstrap_windows_tls.zig"
"special/build_runner.zig"
- "special/builtin.zig"
+ "special/c.zig"
"special/compiler_rt.zig"
"special/compiler_rt/stack_probe.zig"
"special/compiler_rt/arm/aeabi_fcmp.zig"