From a7346ea49f4d9b1af2d0babf67354b234a87fe42 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 8 May 2019 22:43:11 -0400 Subject: [PATCH] fix build on macOS Sadly due to a workaround for LLD linker limitations on macOS we cannot put libuserland into an .a file; instead we have to use object files. Again due to linker limitations, bundling compiler_rt.o into another relocatable object also doesn't work. So we're left with disabling stack probing on macOS for the stage1 self-hosted code. These workarounds could all be removed if the macos support in the LLD linker improved, or if Zig project had its own linker that did not have these issues. --- build.zig | 7 ++++++- src/all_types.hpp | 1 + src/codegen.cpp | 8 +++++++- src/codegen.hpp | 1 + src/link.cpp | 10 ++++++---- src/main.cpp | 5 +++++ std/build.zig | 5 +++++ 7 files changed, 31 insertions(+), 6 deletions(-) diff --git a/build.zig b/build.zig index bdaf175945ff7265a5d32ea48f1445b3f66c76ce..274ea51436351307414dd84478057e1e46fa33e1 100644 --- a/build.zig +++ b/build.zig @@ -384,12 +384,17 @@ const Context = struct { }; fn addLibUserlandStep(b: *Builder) void { + // Sadly macOS requires hacks to work around the buggy MACH-O linker code. const artifact = if (builtin.os == .macosx) b.addObject("userland", "src-self-hosted/stage1.zig") else b.addStaticLibrary("userland", "src-self-hosted/stage1.zig"); artifact.disable_gen_h = true; - artifact.bundle_compiler_rt = true; + if (builtin.os == .macosx) { + artifact.disable_stack_probing = true; + } else { + artifact.bundle_compiler_rt = true; + } artifact.setTarget(builtin.arch, builtin.os, builtin.abi); artifact.linkSystemLibrary("c"); const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1"); diff --git a/src/all_types.hpp b/src/all_types.hpp index 3cfb47db646fa50a34d44925d703f4a84f9efc57..ecc0d1a9bb2a87100d84d585df0b5f914367136b 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1862,6 +1862,7 @@ struct CodeGen { bool is_dummy_so; bool disable_gen_h; bool bundle_compiler_rt; + bool disable_stack_probing; Buf *mmacosx_version_min; Buf *mios_version_min; diff --git a/src/codegen.cpp b/src/codegen.cpp index 23d3c5dc5cd1241ade4793089d82cf3bca89ee4e..d21ada1b23a518c8b03c1d8cfca860a38f8349b8 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -401,7 +401,7 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { static void add_probe_stack_attr(CodeGen *g, LLVMValueRef fn_val) { // Windows already emits its own stack probes - if (g->zig_target->os != OsWindows && + if (!g->disable_stack_probing && g->zig_target->os != OsWindows && (g->zig_target->arch == ZigLLVM_x86 || g->zig_target->arch == ZigLLVM_x86_64)) { addLLVMFnAttrStr(fn_val, "probe-stack", "__zig_probe_stack"); @@ -7043,6 +7043,11 @@ static void zig_llvm_emit_output(CodeGen *g) { } validate_inline_fns(g); g->link_objects.append(output_path); + if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || + (g->out_type == OutTypeLib && !g->is_dynamic))) + { + zig_link_add_compiler_rt(g); + } break; case EmitFileTypeAssembly: @@ -9347,6 +9352,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_bool(ch, g->each_lib_rpath); cache_bool(ch, g->disable_gen_h); cache_bool(ch, g->bundle_compiler_rt); + cache_bool(ch, g->disable_stack_probing); cache_bool(ch, want_valgrind_support(g)); cache_bool(ch, g->have_pic); cache_bool(ch, g->have_dynamic_link); diff --git a/src/codegen.hpp b/src/codegen.hpp index 88c7353cad432fdc17fd0c43191bb6e213415e99..47c0097e4baf4d7af81a99eaa53c66ccc472199f 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -44,6 +44,7 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc void codegen_add_time_event(CodeGen *g, const char *name); void codegen_print_timing_report(CodeGen *g, FILE *f); void codegen_link(CodeGen *g); +void zig_link_add_compiler_rt(CodeGen *g); void codegen_build_and_link(CodeGen *g); ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path, diff --git a/src/link.cpp b/src/link.cpp index 810f6072ad52cbaad3a5d85f68dfcb48f9ab0b77..8900d0351bcb069912ca687d72c24d57f4230276 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -25,6 +25,7 @@ static CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, Ou CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type, parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir, libc, get_stage1_cache_path()); child_gen->disable_gen_h = true; + child_gen->disable_stack_probing = true; child_gen->verbose_tokenize = parent_gen->verbose_tokenize; child_gen->verbose_ast = parent_gen->verbose_ast; child_gen->verbose_link = parent_gen->verbose_link; @@ -1653,6 +1654,11 @@ static void construct_linker_job(LinkJob *lj) { } } +void zig_link_add_compiler_rt(CodeGen *g) { + Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj); + g->link_objects.append(compiler_rt_o_path); +} + void codegen_link(CodeGen *g) { codegen_add_time_event(g, "Build Dependencies"); @@ -1681,10 +1687,6 @@ void codegen_link(CodeGen *g) { for (size_t i = 0; i < g->link_objects.length; i += 1) { 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) { diff --git a/src/main.cpp b/src/main.cpp index e9a859eb70591ce629633ec4efd087d9a36c873c..5659624cb7da30b418b95b08bef8fd3555028dde 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -56,6 +56,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " --disable-gen-h do not generate a C header file (.h)\n" " --disable-valgrind omit valgrind client requests in debug builds\n" " --enable-valgrind include valgrind client requests release builds\n" + " --disable-stack-probing workaround for macosx\n" " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" " -fPIC enable Position Independent Code\n" " -fno-PIC disable Position Independent Code\n" @@ -444,6 +445,7 @@ int main(int argc, char **argv) { bool want_single_threaded = false; bool disable_gen_h = false; bool bundle_compiler_rt = false; + bool disable_stack_probing = false; Buf *override_std_dir = nullptr; Buf *override_lib_dir = nullptr; Buf *main_pkg_path = nullptr; @@ -656,6 +658,8 @@ int main(int argc, char **argv) { disable_gen_h = true; } else if (strcmp(arg, "--bundle-compiler-rt") == 0) { bundle_compiler_rt = true; + } else if (strcmp(arg, "--disable-stack-probing") == 0) { + disable_stack_probing = true; } else if (strcmp(arg, "--test-cmd-bin") == 0) { test_exec_args.append(nullptr); } else if (arg[1] == 'L' && arg[2] != 0) { @@ -1075,6 +1079,7 @@ int main(int argc, char **argv) { g->output_dir = output_dir; g->disable_gen_h = disable_gen_h; g->bundle_compiler_rt = bundle_compiler_rt; + g->disable_stack_probing = disable_stack_probing; codegen_set_errmsg_color(g, color); g->system_linker_hack = system_linker_hack; diff --git a/std/build.zig b/std/build.zig index fa3bac83d000e91f4ef2fd7a19c17720fdd0aae5..b5ec97ab5f130f2a0814ac8d93fee6d87e81311f 100644 --- a/std/build.zig +++ b/std/build.zig @@ -942,6 +942,7 @@ pub const LibExeObjStep = struct { verbose_cc: bool, disable_gen_h: bool, bundle_compiler_rt: bool, + disable_stack_probing: bool, c_std: Builder.CStd, override_std_dir: ?[]const u8, override_lib_dir: ?[]const u8, @@ -1052,6 +1053,7 @@ pub const LibExeObjStep = struct { .filter = null, .disable_gen_h = false, .bundle_compiler_rt = false, + .disable_stack_probing = false, .output_dir = null, .need_system_paths = false, .single_threaded = false, @@ -1457,6 +1459,9 @@ pub const LibExeObjStep = struct { if (self.bundle_compiler_rt) { try zig_args.append("--bundle-compiler-rt"); } + if (self.disable_stack_probing) { + try zig_args.append("--disable-stack-probing"); + } switch (self.target) { Target.Native => {}, -- 2.54.0