mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
compiler_rt: use single cache for libcompiler_rt.a static lib
This commit is contained in:
parent
80790be309
commit
2259d629d3
8 changed files with 156 additions and 110 deletions
|
|
@ -490,6 +490,7 @@ set(ZIG_STAGE2_SOURCES
|
||||||
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/ceil.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/ceil.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/clear_cache.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/clear_cache.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cmp.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cmp.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/common.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/compareXf2.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/compareXf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cos.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cos.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/count0bits.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/count0bits.zig"
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,7 @@ pub const panic = @import("common.zig").panic;
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
if (builtin.os.tag.isDarwin()) {
|
if (builtin.os.tag.isDarwin()) {
|
||||||
@export(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast, .{
|
@export(__isPlatformVersionAtLeast, .{ .name = "__isPlatformVersionAtLeast", .linkage = linkage });
|
||||||
.name = "__isPlatformVersionAtLeast",
|
|
||||||
.linkage = linkage,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,7 +25,7 @@ comptime {
|
||||||
// the newer codepath, which merely calls out to the Darwin _availability_version_check API which is
|
// the newer codepath, which merely calls out to the Darwin _availability_version_check API which is
|
||||||
// available on macOS 10.15+, iOS 13+, tvOS 13+ and watchOS 6+.
|
// available on macOS 10.15+, iOS 13+, tvOS 13+ and watchOS 6+.
|
||||||
|
|
||||||
const IsPlatformVersionAtLeast = struct {
|
const __isPlatformVersionAtLeast = if (builtin.os.tag.isDarwin()) struct {
|
||||||
inline fn constructVersion(major: u32, minor: u32, subminor: u32) u32 {
|
inline fn constructVersion(major: u32, minor: u32, subminor: u32) u32 {
|
||||||
return ((major & 0xffff) << 16) | ((minor & 0xff) << 8) | (subminor & 0xff);
|
return ((major & 0xffff) << 16) | ((minor & 0xff) << 8) | (subminor & 0xff);
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +47,7 @@ const IsPlatformVersionAtLeast = struct {
|
||||||
};
|
};
|
||||||
// Darwin-only
|
// Darwin-only
|
||||||
extern "c" fn _availability_version_check(count: u32, versions: [*c]const dyld_build_version_t) bool;
|
extern "c" fn _availability_version_check(count: u32, versions: [*c]const dyld_build_version_t) bool;
|
||||||
};
|
}.__isPlatformVersionAtLeast else struct {};
|
||||||
|
|
||||||
test "isPlatformVersionAtLeast" {
|
test "isPlatformVersionAtLeast" {
|
||||||
if (!comptime builtin.os.tag.isDarwin()) return error.SkipZigTest;
|
if (!comptime builtin.os.tag.isDarwin()) return error.SkipZigTest;
|
||||||
|
|
@ -58,6 +55,6 @@ test "isPlatformVersionAtLeast" {
|
||||||
// Note: this test depends on the actual host OS version since it is merely calling into the
|
// Note: this test depends on the actual host OS version since it is merely calling into the
|
||||||
// native Darwin API.
|
// native Darwin API.
|
||||||
const macos_platform_constant = 1;
|
const macos_platform_constant = 1;
|
||||||
try testing.expect(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast(macos_platform_constant, 10, 0, 15) == 1);
|
try testing.expect(__isPlatformVersionAtLeast(macos_platform_constant, 10, 0, 15) == 1);
|
||||||
try testing.expect(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast(macos_platform_constant, 99, 0, 0) == 0);
|
try testing.expect(__isPlatformVersionAtLeast(macos_platform_constant, 99, 0, 0) == 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ libssp_static_lib: ?CRTFile = null,
|
||||||
libc_static_lib: ?CRTFile = null,
|
libc_static_lib: ?CRTFile = null,
|
||||||
/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue
|
/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue
|
||||||
/// and resolved before calling linker.flush().
|
/// and resolved before calling linker.flush().
|
||||||
compiler_rt_static_lib: compiler_rt.CompilerRtLib = .{},
|
compiler_rt_lib: ?CRTFile = null,
|
||||||
/// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue
|
/// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue
|
||||||
/// and resolved before calling linker.flush().
|
/// and resolved before calling linker.flush().
|
||||||
compiler_rt_obj: ?CRTFile = null,
|
compiler_rt_obj: ?CRTFile = null,
|
||||||
|
|
@ -1979,7 +1979,9 @@ pub fn destroy(self: *Compilation) void {
|
||||||
if (self.libcxxabi_static_lib) |*crt_file| {
|
if (self.libcxxabi_static_lib) |*crt_file| {
|
||||||
crt_file.deinit(gpa);
|
crt_file.deinit(gpa);
|
||||||
}
|
}
|
||||||
self.compiler_rt_static_lib.deinit(gpa);
|
if (self.compiler_rt_lib) |*crt_file| {
|
||||||
|
crt_file.deinit(gpa);
|
||||||
|
}
|
||||||
if (self.compiler_rt_obj) |*crt_file| {
|
if (self.compiler_rt_obj) |*crt_file| {
|
||||||
crt_file.deinit(gpa);
|
crt_file.deinit(gpa);
|
||||||
}
|
}
|
||||||
|
|
@ -3139,7 +3141,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
|
||||||
|
|
||||||
compiler_rt.buildCompilerRtLib(
|
compiler_rt.buildCompilerRtLib(
|
||||||
comp,
|
comp,
|
||||||
&comp.compiler_rt_static_lib,
|
&comp.compiler_rt_lib,
|
||||||
) catch |err| switch (err) {
|
) catch |err| switch (err) {
|
||||||
error.OutOfMemory => return error.OutOfMemory,
|
error.OutOfMemory => return error.OutOfMemory,
|
||||||
error.SubCompilationFailed => return, // error reported already
|
error.SubCompilationFailed => return, // error reported already
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,77 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const build_options = @import("build_options");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
const assert = std.debug.assert;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const tracy = @import("tracy.zig");
|
const tracy = @import("tracy.zig");
|
||||||
const trace = tracy.trace;
|
const trace = tracy.trace;
|
||||||
|
|
||||||
|
const Cache = @import("Cache.zig");
|
||||||
const Compilation = @import("Compilation.zig");
|
const Compilation = @import("Compilation.zig");
|
||||||
const CRTFile = Compilation.CRTFile;
|
const CRTFile = Compilation.CRTFile;
|
||||||
const LinkObject = Compilation.LinkObject;
|
const LinkObject = Compilation.LinkObject;
|
||||||
const Package = @import("Package.zig");
|
const Package = @import("Package.zig");
|
||||||
|
|
||||||
pub const CompilerRtLib = struct {
|
pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *?CRTFile) !void {
|
||||||
crt_object_files: [sources.len]?CRTFile = undefined,
|
|
||||||
crt_lib_file: ?CRTFile = null,
|
|
||||||
|
|
||||||
pub fn deinit(crt_lib: *CompilerRtLib, gpa: Allocator) void {
|
|
||||||
for (crt_lib.crt_object_files) |*crt_file| {
|
|
||||||
if (crt_file.*) |*cf| {
|
|
||||||
cf.deinit(gpa);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (crt_lib.crt_lib_file) |*crt_file| {
|
|
||||||
crt_file.deinit(gpa);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *CompilerRtLib) !void {
|
|
||||||
const tracy_trace = trace(@src());
|
const tracy_trace = trace(@src());
|
||||||
defer tracy_trace.end();
|
defer tracy_trace.end();
|
||||||
|
|
||||||
|
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||||
|
defer arena_allocator.deinit();
|
||||||
|
const arena = arena_allocator.allocator();
|
||||||
|
|
||||||
|
const target = comp.getTarget();
|
||||||
|
|
||||||
|
// Use the global cache directory.
|
||||||
|
var cache_parent: Cache = .{
|
||||||
|
.gpa = comp.gpa,
|
||||||
|
.manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}),
|
||||||
|
};
|
||||||
|
defer cache_parent.manifest_dir.close();
|
||||||
|
|
||||||
|
var cache = cache_parent.obtain();
|
||||||
|
defer cache.deinit();
|
||||||
|
|
||||||
|
cache.hash.add(sources.len);
|
||||||
|
for (sources) |source| {
|
||||||
|
const full_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{source});
|
||||||
|
_ = try cache.addFile(full_path, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.hash.addBytes(build_options.version);
|
||||||
|
cache.hash.addBytes(comp.zig_lib_directory.path orelse ".");
|
||||||
|
cache.hash.add(target.cpu.arch);
|
||||||
|
cache.hash.add(target.os.tag);
|
||||||
|
cache.hash.add(target.abi);
|
||||||
|
|
||||||
|
const hit = try cache.hit();
|
||||||
|
const digest = cache.final();
|
||||||
|
const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
|
||||||
|
|
||||||
|
var o_directory: Compilation.Directory = .{
|
||||||
|
.handle = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}),
|
||||||
|
.path = try std.fs.path.join(arena, &[_][]const u8{ comp.global_cache_directory.path.?, o_sub_path }),
|
||||||
|
};
|
||||||
|
defer o_directory.handle.close();
|
||||||
|
|
||||||
|
const ok_basename = "ok";
|
||||||
|
const actual_hit = if (hit) blk: {
|
||||||
|
o_directory.handle.access(ok_basename, .{}) catch |err| switch (err) {
|
||||||
|
error.FileNotFound => break :blk false,
|
||||||
|
else => |e| return e,
|
||||||
|
};
|
||||||
|
break :blk true;
|
||||||
|
} else false;
|
||||||
|
|
||||||
|
const root_name = "compiler_rt";
|
||||||
|
const basename = try std.zig.binNameAlloc(arena, .{
|
||||||
|
.root_name = root_name,
|
||||||
|
.target = target,
|
||||||
|
.output_mode = .Lib,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!actual_hit) {
|
||||||
var progress: std.Progress = .{ .dont_print_on_dumb = true };
|
var progress: std.Progress = .{ .dont_print_on_dumb = true };
|
||||||
var progress_node = progress.start("Compile Compiler-RT", sources.len + 1);
|
var progress_node = progress.start("Compile Compiler-RT", sources.len + 1);
|
||||||
defer progress_node.end();
|
defer progress_node.end();
|
||||||
|
|
@ -43,30 +85,22 @@ pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *CompilerRtLib) !
|
||||||
obj_progress_node.activate();
|
obj_progress_node.activate();
|
||||||
defer obj_progress_node.end();
|
defer obj_progress_node.end();
|
||||||
|
|
||||||
try comp.buildOutputFromZig(source, .Obj, &compiler_rt_lib.crt_object_files[i], .compiler_rt);
|
var tmp_crt_file: ?CRTFile = null;
|
||||||
|
defer if (tmp_crt_file) |*crt| crt.deinit(comp.gpa);
|
||||||
|
try comp.buildOutputFromZig(source, .Obj, &tmp_crt_file, .compiler_rt);
|
||||||
link_objects[i] = .{
|
link_objects[i] = .{
|
||||||
.path = compiler_rt_lib.crt_object_files[i].?.full_object_path,
|
.path = try arena.dupe(u8, tmp_crt_file.?.full_object_path),
|
||||||
.must_link = true,
|
.must_link = true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const root_name = "compiler_rt";
|
|
||||||
|
|
||||||
var lib_progress_node = progress_node.start(root_name, 0);
|
var lib_progress_node = progress_node.start(root_name, 0);
|
||||||
lib_progress_node.activate();
|
lib_progress_node.activate();
|
||||||
defer lib_progress_node.end();
|
defer lib_progress_node.end();
|
||||||
|
|
||||||
const target = comp.getTarget();
|
|
||||||
const basename = try std.zig.binNameAlloc(comp.gpa, .{
|
|
||||||
.root_name = root_name,
|
|
||||||
.target = target,
|
|
||||||
.output_mode = .Lib,
|
|
||||||
});
|
|
||||||
errdefer comp.gpa.free(basename);
|
|
||||||
|
|
||||||
// TODO: This is extracted into a local variable to work around a stage1 miscompilation.
|
// TODO: This is extracted into a local variable to work around a stage1 miscompilation.
|
||||||
const emit_bin = Compilation.EmitLoc{
|
const emit_bin = Compilation.EmitLoc{
|
||||||
.directory = null, // Put it in the cache directory.
|
.directory = o_directory, // Put it in the cache directory.
|
||||||
.basename = basename,
|
.basename = basename,
|
||||||
};
|
};
|
||||||
const sub_compilation = try Compilation.create(comp.gpa, .{
|
const sub_compilation = try Compilation.create(comp.gpa, .{
|
||||||
|
|
@ -113,11 +147,23 @@ pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *CompilerRtLib) !
|
||||||
|
|
||||||
try sub_compilation.updateSubCompilation();
|
try sub_compilation.updateSubCompilation();
|
||||||
|
|
||||||
compiler_rt_lib.crt_lib_file = .{
|
if (o_directory.handle.createFile(ok_basename, .{})) |file| {
|
||||||
.full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
|
file.close();
|
||||||
sub_compilation.bin_file.options.emit.?.sub_path,
|
} else |err| {
|
||||||
|
std.log.warn("compiler-rt lib: failed to mark completion: {s}", .{@errorName(err)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try cache.writeManifest();
|
||||||
|
|
||||||
|
assert(compiler_rt_lib.* == null);
|
||||||
|
compiler_rt_lib.* = .{
|
||||||
|
.full_object_path = try std.fs.path.join(comp.gpa, &[_][]const u8{
|
||||||
|
comp.global_cache_directory.path.?,
|
||||||
|
o_sub_path,
|
||||||
|
basename,
|
||||||
}),
|
}),
|
||||||
.lock = sub_compilation.bin_file.toOwnedLock(),
|
.lock = cache.toOwnedLock(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1354,7 +1354,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
|
||||||
}
|
}
|
||||||
// MSVC compiler_rt is missing some stuff, so we build it unconditionally but
|
// MSVC compiler_rt is missing some stuff, so we build it unconditionally but
|
||||||
// and rely on weak linkage to allow MSVC compiler_rt functions to override ours.
|
// and rely on weak linkage to allow MSVC compiler_rt functions to override ours.
|
||||||
if (comp.compiler_rt_static_lib.crt_lib_file) |lib| {
|
if (comp.compiler_rt_lib) |lib| {
|
||||||
try argv.append(lib.full_object_path);
|
try argv.append(lib.full_object_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1272,7 +1272,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
|
||||||
const stack_size = self.base.options.stack_size_override orelse 16777216;
|
const stack_size = self.base.options.stack_size_override orelse 16777216;
|
||||||
const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
|
const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
|
||||||
const compiler_rt_path: ?[]const u8 = blk: {
|
const compiler_rt_path: ?[]const u8 = blk: {
|
||||||
if (comp.compiler_rt_static_lib.crt_lib_file) |x| break :blk x.full_object_path;
|
if (comp.compiler_rt_lib) |x| break :blk x.full_object_path;
|
||||||
if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
|
if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
|
||||||
break :blk null;
|
break :blk null;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -738,7 +738,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||||
try positionals.append(p);
|
try positionals.append(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comp.compiler_rt_static_lib.crt_lib_file) |lib| {
|
if (comp.compiler_rt_lib) |lib| {
|
||||||
try positionals.append(lib.full_object_path);
|
try positionals.append(lib.full_object_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2255,7 +2255,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
|
||||||
const is_obj = self.base.options.output_mode == .Obj;
|
const is_obj = self.base.options.output_mode == .Obj;
|
||||||
|
|
||||||
const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj)
|
const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj)
|
||||||
comp.compiler_rt_static_lib.crt_lib_file.?.full_object_path
|
comp.compiler_rt_lib.?.full_object_path
|
||||||
else
|
else
|
||||||
null;
|
null;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue