zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

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 };