blob 1e101da2 (8659B) - Raw
1 const std = @import("std"); 2 const path = std.fs.path; 3 const assert = std.debug.assert; 4 5 const target_util = @import("target.zig"); 6 const Compilation = @import("Compilation.zig"); 7 const Module = @import("Package/Module.zig"); 8 const build_options = @import("build_options"); 9 const trace = @import("tracy.zig").trace; 10 11 pub const BuildError = error{ 12 OutOfMemory, 13 SubCompilationFailed, 14 ZigCompilerNotBuiltWithLLVMExtensions, 15 }; 16 17 pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void { 18 if (!build_options.have_llvm) { 19 return error.ZigCompilerNotBuiltWithLLVMExtensions; 20 } 21 22 const tracy = trace(@src()); 23 defer tracy.end(); 24 25 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); 26 defer arena_allocator.deinit(); 27 const arena = arena_allocator.allocator(); 28 29 const output_mode = .Lib; 30 const config = Compilation.Config.resolve(.{ 31 .output_mode = .Lib, 32 .resolved_target = comp.root_mod.resolved_target, 33 .is_test = false, 34 .have_zcu = false, 35 .emit_bin = true, 36 .root_optimize_mode = comp.compilerRtOptMode(), 37 .root_strip = comp.compilerRtStrip(), 38 .link_libc = true, 39 // Disable LTO to avoid https://github.com/llvm/llvm-project/issues/56825 40 .lto = false, 41 }) catch |err| { 42 comp.setMiscFailure( 43 .libunwind, 44 "unable to build libunwind: resolving configuration failed: {s}", 45 .{@errorName(err)}, 46 ); 47 return error.SubCompilationFailed; 48 }; 49 const target = comp.root_mod.resolved_target.result; 50 const root_mod = Module.create(arena, .{ 51 .global_cache_directory = comp.global_cache_directory, 52 .paths = .{ 53 .root = .{ .root_dir = comp.zig_lib_directory }, 54 .root_src_path = "", 55 }, 56 .fully_qualified_name = "root", 57 .inherited = .{ 58 .resolved_target = comp.root_mod.resolved_target, 59 .strip = comp.compilerRtStrip(), 60 .stack_check = false, 61 .stack_protector = 0, 62 .red_zone = comp.root_mod.red_zone, 63 .omit_frame_pointer = comp.root_mod.omit_frame_pointer, 64 .valgrind = false, 65 .sanitize_c = false, 66 .sanitize_thread = false, 67 // necessary so that libunwind can unwind through its own stack frames 68 .unwind_tables = true, 69 .pic = if (target_util.supports_fpic(target)) true else null, 70 .optimize_mode = comp.compilerRtOptMode(), 71 }, 72 .global = config, 73 .cc_argv = &.{}, 74 .parent = null, 75 .builtin_mod = null, 76 .builtin_modules = null, // there is only one module in this compilation 77 }) catch |err| { 78 comp.setMiscFailure( 79 .libunwind, 80 "unable to build libunwind: creating module failed: {s}", 81 .{@errorName(err)}, 82 ); 83 return error.SubCompilationFailed; 84 }; 85 86 const root_name = "unwind"; 87 const link_mode = .static; 88 const basename = try std.zig.binNameAlloc(arena, .{ 89 .root_name = root_name, 90 .target = target, 91 .output_mode = output_mode, 92 .link_mode = link_mode, 93 }); 94 const emit_bin = Compilation.EmitLoc{ 95 .directory = null, // Put it in the cache directory. 96 .basename = basename, 97 }; 98 var c_source_files: [unwind_src_list.len]Compilation.CSourceFile = undefined; 99 for (unwind_src_list, 0..) |unwind_src, i| { 100 var cflags = std.ArrayList([]const u8).init(arena); 101 102 switch (Compilation.classifyFileExt(unwind_src)) { 103 .c => { 104 try cflags.append("-std=c17"); 105 }, 106 .cpp => { 107 try cflags.appendSlice(&[_][]const u8{ 108 "-std=c++17", 109 "-fno-rtti", 110 }); 111 }, 112 .assembly_with_cpp => {}, 113 else => unreachable, // You can see the entire list of files just above. 114 } 115 try cflags.append("-fno-exceptions"); 116 try cflags.append("-I"); 117 try cflags.append(try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libunwind", "include" })); 118 try cflags.append("-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS"); 119 try cflags.append("-Wa,--noexecstack"); 120 try cflags.append("-fvisibility=hidden"); 121 try cflags.append("-fvisibility-inlines-hidden"); 122 try cflags.append("-fvisibility-global-new-delete=force-hidden"); 123 124 // This is intentionally always defined because the macro definition means, should it only 125 // build for the target specified by compiler defines. Since we pass -target the compiler 126 // defines will be correct. 127 try cflags.append("-D_LIBUNWIND_IS_NATIVE_ONLY"); 128 129 if (comp.root_mod.optimize_mode == .Debug) { 130 try cflags.append("-D_DEBUG"); 131 } 132 if (!comp.config.any_non_single_threaded) { 133 try cflags.append("-D_LIBUNWIND_HAS_NO_THREADS"); 134 } 135 if (target.cpu.arch.isArm() and target.abi.floatAbi() == .hard) { 136 try cflags.append("-DCOMPILER_RT_ARMHF_TARGET"); 137 } 138 try cflags.append("-Wno-bitwise-conditional-parentheses"); 139 try cflags.append("-Wno-visibility"); 140 try cflags.append("-Wno-incompatible-pointer-types"); 141 142 if (target.os.tag == .windows) { 143 try cflags.append("-Wno-dll-attribute-on-redeclaration"); 144 } 145 146 c_source_files[i] = .{ 147 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{unwind_src}), 148 .extra_flags = cflags.items, 149 .owner = root_mod, 150 }; 151 } 152 const sub_compilation = Compilation.create(comp.gpa, arena, .{ 153 .self_exe_path = comp.self_exe_path, 154 .local_cache_directory = comp.global_cache_directory, 155 .global_cache_directory = comp.global_cache_directory, 156 .zig_lib_directory = comp.zig_lib_directory, 157 .config = config, 158 .root_mod = root_mod, 159 .cache_mode = .whole, 160 .root_name = root_name, 161 .main_mod = null, 162 .thread_pool = comp.thread_pool, 163 .libc_installation = comp.libc_installation, 164 .emit_bin = emit_bin, 165 .function_sections = comp.function_sections, 166 .c_source_files = &c_source_files, 167 .verbose_cc = comp.verbose_cc, 168 .verbose_link = comp.verbose_link, 169 .verbose_air = comp.verbose_air, 170 .verbose_llvm_ir = comp.verbose_llvm_ir, 171 .verbose_llvm_bc = comp.verbose_llvm_bc, 172 .verbose_cimport = comp.verbose_cimport, 173 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, 174 .clang_passthrough_mode = comp.clang_passthrough_mode, 175 .skip_linker_dependencies = true, 176 }) catch |err| { 177 comp.setMiscFailure( 178 .libunwind, 179 "unable to build libunwind: create compilation failed: {s}", 180 .{@errorName(err)}, 181 ); 182 return error.SubCompilationFailed; 183 }; 184 defer sub_compilation.destroy(); 185 186 comp.updateSubCompilation(sub_compilation, .libunwind, prog_node) catch |err| switch (err) { 187 error.SubCompilationFailed => return error.SubCompilationFailed, 188 else => |e| { 189 comp.setMiscFailure( 190 .libunwind, 191 "unable to build libunwind: compilation failed: {s}", 192 .{@errorName(e)}, 193 ); 194 return error.SubCompilationFailed; 195 }, 196 }; 197 198 const crt_file = try sub_compilation.toCrtFile(); 199 comp.queueLinkTaskMode(crt_file.full_object_path, output_mode); 200 assert(comp.libunwind_static_lib == null); 201 comp.libunwind_static_lib = crt_file; 202 } 203 204 const unwind_src_list = [_][]const u8{ 205 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "libunwind.cpp", 206 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-EHABI.cpp", 207 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-seh.cpp", 208 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1.c", 209 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1-gcc-ext.c", 210 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-sjlj.c", 211 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-wasm.c", 212 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S", 213 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S", 214 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind_AIXExtras.cpp", 215 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "gcc_personality_v0.c", 216 };