add --bundle-compiler-rt function to link options

and use it when building libuserland.a

The self-hosted part of stage1 relies on zig's compiler-rt, and so we
include it in libuserland.a.

This should potentially be the default, but for now it's behind a linker
option.

self-hosted translate-c: small progress on translating functions.
This commit is contained in:
Andrew Kelley
2019-05-08 20:49:07 -04:00
parent 3bd5c16f39
commit 9bbd71c9ab
8 changed files with 246 additions and 212 deletions

View File

@@ -772,17 +772,15 @@ 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) {
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.
// TODO write our own linker. https://github.com/ziglang/zig/issues/1535
OutType child_out_type = OutTypeLib;
if (parent_gen->zig_target->os == OsMacOSX) {
child_out_type = OutTypeObj;
}
CodeGen *child_gen = create_child_codegen(parent_gen, full_path, child_out_type,
parent_gen->libc);
codegen_set_out_name(child_gen, buf_create_from_str(aname));
@@ -804,14 +802,14 @@ static Buf *build_a(CodeGen *parent_gen, const char *aname) {
Buf *full_path = buf_alloc();
os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path);
return build_a_raw(parent_gen, aname, full_path);
return build_a_raw(parent_gen, aname, full_path, OutTypeLib);
}
static Buf *build_compiler_rt(CodeGen *parent_gen) {
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, buf_create_from_str("compiler_rt.zig"), full_path);
return build_a_raw(parent_gen, "compiler_rt", full_path);
return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type);
}
static const char *get_darwin_arch_string(const ZigTarget *t) {
@@ -1006,7 +1004,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
lj->args.append(buf_ptr(builtin_a_path));
}
Buf *compiler_rt_o_path = build_compiler_rt(g);
Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
lj->args.append(buf_ptr(compiler_rt_o_path));
}
@@ -1117,7 +1115,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {
lj->args.append(buf_ptr(builtin_a_path));
}
Buf *compiler_rt_o_path = build_compiler_rt(g);
Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
lj->args.append(buf_ptr(compiler_rt_o_path));
}
}
@@ -1361,7 +1359,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
}
// msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage
Buf *compiler_rt_o_path = build_compiler_rt(g);
Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
lj->args.append(buf_ptr(compiler_rt_o_path));
}
@@ -1604,7 +1602,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
// compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce
if (g->out_type == OutTypeExe || is_dyn_lib) {
Buf *compiler_rt_o_path = build_compiler_rt(g);
Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
lj->args.append(buf_ptr(compiler_rt_o_path));
}
@@ -1681,14 +1679,18 @@ void codegen_link(CodeGen *g) {
if (g->out_type == OutTypeLib && !g->is_dynamic) {
ZigList<const char *> file_names = {};
for (size_t i = 0; i < g->link_objects.length; i += 1) {
file_names.append((const char *)buf_ptr(g->link_objects.at(i)));
file_names.append(buf_ptr(g->link_objects.at(i)));
}
if (g->bundle_compiler_rt) {
Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj);
file_names.append(buf_ptr(compiler_rt_o_path));
}
ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os);
codegen_add_time_event(g, "LLVM Link");
if (g->verbose_link) {
fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));
for (size_t i = 0; i < g->link_objects.length; i += 1) {
fprintf(stderr, " %s", (const char *)buf_ptr(g->link_objects.at(i)));
for (size_t i = 0; i < file_names.length; i += 1) {
fprintf(stderr, " %s", file_names.at(i));
}
fprintf(stderr, "\n");
}