mirror of
https://github.com/ziglang/zig.git
synced 2025-12-30 10:03:21 +00:00
This takes the place of `zig builtin`. This is an improvement over the command because now the generated source will correctly show LinkMode and OutputMode, whereas before it was always stuck as Static and Obj, respectively.
145 lines
5.6 KiB
Zig
145 lines
5.6 KiB
Zig
const std = @import("std");
|
|
const path = std.fs.path;
|
|
const assert = std.debug.assert;
|
|
|
|
const target_util = @import("target.zig");
|
|
const Compilation = @import("Compilation.zig");
|
|
const build_options = @import("build_options");
|
|
const trace = @import("tracy.zig").trace;
|
|
|
|
pub fn buildStaticLib(comp: *Compilation) !void {
|
|
const tracy = trace(@src());
|
|
defer tracy.end();
|
|
|
|
if (!build_options.have_llvm) {
|
|
return error.ZigCompilerNotBuiltWithLLVMExtensions;
|
|
}
|
|
|
|
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
|
defer arena_allocator.deinit();
|
|
const arena = &arena_allocator.allocator;
|
|
|
|
const root_name = "unwind";
|
|
const output_mode = .Lib;
|
|
const link_mode = .Static;
|
|
const target = comp.getTarget();
|
|
const basename = try std.zig.binNameAlloc(arena, root_name, target, output_mode, link_mode, null);
|
|
|
|
const emit_bin = Compilation.EmitLoc{
|
|
.directory = null, // Put it in the cache directory.
|
|
.basename = basename,
|
|
};
|
|
|
|
const unwind_src_list = [_][]const u8{
|
|
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "libunwind.cpp",
|
|
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-EHABI.cpp",
|
|
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-seh.cpp",
|
|
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1.c",
|
|
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1-gcc-ext.c",
|
|
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-sjlj.c",
|
|
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S",
|
|
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S",
|
|
};
|
|
|
|
var c_source_files: [unwind_src_list.len]Compilation.CSourceFile = undefined;
|
|
for (unwind_src_list) |unwind_src, i| {
|
|
var cflags = std.ArrayList([]const u8).init(arena);
|
|
|
|
switch (Compilation.classifyFileExt(unwind_src)) {
|
|
.c => {
|
|
try cflags.append("-std=c99");
|
|
},
|
|
.cpp => {
|
|
try cflags.appendSlice(&[_][]const u8{
|
|
"-fno-rtti",
|
|
"-I",
|
|
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" }),
|
|
});
|
|
},
|
|
.assembly => {},
|
|
else => unreachable, // You can see the entire list of files just above.
|
|
}
|
|
try cflags.append("-I");
|
|
try cflags.append(try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libunwind", "include" }));
|
|
if (target_util.supports_fpic(target)) {
|
|
try cflags.append("-fPIC");
|
|
}
|
|
try cflags.append("-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS");
|
|
try cflags.append("-Wa,--noexecstack");
|
|
|
|
// This is intentionally always defined because the macro definition means, should it only
|
|
// build for the target specified by compiler defines. Since we pass -target the compiler
|
|
// defines will be correct.
|
|
try cflags.append("-D_LIBUNWIND_IS_NATIVE_ONLY");
|
|
|
|
if (comp.bin_file.options.optimize_mode == .Debug) {
|
|
try cflags.append("-D_DEBUG");
|
|
}
|
|
if (comp.bin_file.options.single_threaded) {
|
|
try cflags.append("-D_LIBUNWIND_HAS_NO_THREADS");
|
|
}
|
|
try cflags.append("-Wno-bitwise-conditional-parentheses");
|
|
|
|
c_source_files[i] = .{
|
|
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{unwind_src}),
|
|
.extra_flags = cflags.items,
|
|
};
|
|
}
|
|
const sub_compilation = try Compilation.create(comp.gpa, .{
|
|
// TODO use the global cache directory here
|
|
.zig_cache_directory = comp.zig_cache_directory,
|
|
.zig_lib_directory = comp.zig_lib_directory,
|
|
.target = target,
|
|
.root_name = root_name,
|
|
.root_pkg = null,
|
|
.output_mode = output_mode,
|
|
.rand = comp.rand,
|
|
.libc_installation = comp.bin_file.options.libc_installation,
|
|
.emit_bin = emit_bin,
|
|
.optimize_mode = comp.bin_file.options.optimize_mode,
|
|
.link_mode = link_mode,
|
|
.want_sanitize_c = false,
|
|
.want_stack_check = false,
|
|
.want_valgrind = false,
|
|
.want_pic = comp.bin_file.options.pic,
|
|
.emit_h = null,
|
|
.strip = comp.bin_file.options.strip,
|
|
.is_native_os = comp.bin_file.options.is_native_os,
|
|
.self_exe_path = comp.self_exe_path,
|
|
.c_source_files = &c_source_files,
|
|
.verbose_cc = comp.verbose_cc,
|
|
.verbose_link = comp.bin_file.options.verbose_link,
|
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
|
.link_libc = true,
|
|
});
|
|
defer sub_compilation.destroy();
|
|
|
|
try updateSubCompilation(sub_compilation);
|
|
|
|
assert(comp.libunwind_static_lib == null);
|
|
comp.libunwind_static_lib = Compilation.CRTFile{
|
|
.full_object_path = try sub_compilation.bin_file.options.directory.join(comp.gpa, &[_][]const u8{basename}),
|
|
.lock = sub_compilation.bin_file.toOwnedLock(),
|
|
};
|
|
}
|
|
|
|
fn updateSubCompilation(sub_compilation: *Compilation) !void {
|
|
try sub_compilation.update();
|
|
|
|
// Look for compilation errors in this sub_compilation
|
|
var errors = try sub_compilation.getAllErrorsAlloc();
|
|
defer errors.deinit(sub_compilation.gpa);
|
|
|
|
if (errors.list.len != 0) {
|
|
for (errors.list) |full_err_msg| {
|
|
std.log.err("{}:{}:{}: {}\n", .{
|
|
full_err_msg.src_path,
|
|
full_err_msg.line + 1,
|
|
full_err_msg.column + 1,
|
|
full_err_msg.msg,
|
|
});
|
|
}
|
|
return error.BuildingLibCObjectFailed;
|
|
}
|
|
}
|