aboutsummaryrefslogtreecommitdiff
path: root/src/Compilation.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-12-14 18:47:58 -0700
committerAndrew Kelley <andrew@ziglang.org>2024-01-01 17:51:19 -0700
commitc49957dbe82d7f0db555160b50306335bfa03165 (patch)
tree529e84e430b27c3e6f13cb7a2c956b0ee445339c /src/Compilation.zig
parentf54471b54c471bb6f8e51a1383be09d01c24d0c3 (diff)
downloadzig-c49957dbe82d7f0db555160b50306335bfa03165.tar.gz
zig-c49957dbe82d7f0db555160b50306335bfa03165.zip
fix a round of compile errors caused by this branch
Diffstat (limited to 'src/Compilation.zig')
-rw-r--r--src/Compilation.zig153
1 files changed, 95 insertions, 58 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 35ee243617..693e46c07c 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -884,12 +884,32 @@ const CacheUse = union(CacheMode) {
docs_sub_path: ?[]u8,
lf_open_opts: link.File.OpenOptions,
tmp_artifact_directory: ?Cache.Directory,
+ /// Prevents other processes from clobbering files in the output directory.
+ lock: ?Cache.Lock,
+
+ fn releaseLock(whole: *Whole) void {
+ if (whole.lock) |*lock| {
+ lock.release();
+ whole.lock = null;
+ }
+ }
};
const Incremental = struct {
/// Where build artifacts and incremental compilation metadata serialization go.
artifact_directory: Compilation.Directory,
};
+
+ fn deinit(cu: CacheUse) void {
+ switch (cu) {
+ .incremental => |incremental| {
+ incremental.artifact_directory.handle.close();
+ },
+ .whole => |whole| {
+ whole.releaseLock();
+ },
+ }
+ }
};
pub const LinkObject = struct {
@@ -916,7 +936,7 @@ pub const InitOptions = struct {
/// Normally, `main_mod` and `root_mod` are the same. The exception is `zig
/// test`, in which `root_mod` is the test runner, and `main_mod` is the
/// user's source file which has the tests.
- main_mod: ?*Package.Module,
+ main_mod: ?*Package.Module = null,
/// This is provided so that the API user has a chance to tweak the
/// per-module settings of the standard library.
std_mod: *Package.Module,
@@ -1615,6 +1635,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.implib_sub_path = try prepareWholeEmitSubPath(arena, options.emit_implib),
.docs_sub_path = try prepareWholeEmitSubPath(arena, options.emit_docs),
.tmp_artifact_directory = null,
+ .lock = null,
};
comp.cache_use = .{ .whole = whole };
},
@@ -1822,13 +1843,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
pub fn destroy(self: *Compilation) void {
if (self.bin_file) |lf| lf.destroy();
if (self.module) |zcu| zcu.deinit();
- switch (self.cache_use) {
- .incremental => |incremental| {
- incremental.artifact_directory.handle.close();
- },
- .whole => {},
- }
-
+ self.cache_use.deinit();
self.work_queue.deinit();
self.anon_work_queue.deinit();
self.c_object_work_queue.deinit();
@@ -1922,11 +1937,17 @@ pub fn getTarget(self: Compilation) Target {
return self.root_mod.resolved_target.result;
}
-pub fn hotCodeSwap(comp: *Compilation, prog_node: *std.Progress.Node, pid: std.ChildProcess.Id) !void {
- comp.bin_file.child_pid = pid;
- try comp.makeBinFileWritable();
+/// Only legal to call when cache mode is incremental and a link file is present.
+pub fn hotCodeSwap(
+ comp: *Compilation,
+ prog_node: *std.Progress.Node,
+ pid: std.ChildProcess.Id,
+) !void {
+ const lf = comp.bin_file.?;
+ lf.child_pid = pid;
+ try lf.makeWritable();
try comp.update(prog_node);
- try comp.makeBinFileExecutable();
+ try lf.makeExecutable();
}
fn cleanupAfterUpdate(comp: *Compilation) void {
@@ -1941,7 +1962,7 @@ fn cleanupAfterUpdate(comp: *Compilation) void {
lf.destroy();
comp.bin_file = null;
}
- if (whole.tmp_artifact_directory) |directory| {
+ if (whole.tmp_artifact_directory) |*directory| {
directory.handle.close();
if (directory.path) |p| comp.gpa.free(p);
whole.tmp_artifact_directory = null;
@@ -1967,8 +1988,9 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
// C source files.
switch (comp.cache_use) {
.whole => |whole| {
- // We are about to obtain this lock, so here we give other processes a chance first.
assert(comp.bin_file == null);
+ // We are about to obtain this lock, so here we give other processes a chance first.
+ whole.releaseLock();
man = comp.cache_parent.obtain();
whole.cache_manifest = &man;
@@ -1989,8 +2011,8 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
comp.wholeCacheModeSetBinFilePath(whole, &digest);
- assert(comp.bin_file.lock == null);
- comp.bin_file.lock = man.toOwnedLock();
+ assert(whole.lock == null);
+ whole.lock = man.toOwnedLock();
return;
}
log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});
@@ -2158,7 +2180,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
// Rename the temporary directory into place.
// Close tmp dir and link.File to avoid open handle during rename.
- if (whole.tmp_artifact_directory) |tmp_directory| {
+ if (whole.tmp_artifact_directory) |*tmp_directory| {
tmp_directory.handle.close();
if (tmp_directory.path) |p| comp.gpa.free(p);
whole.tmp_artifact_directory = null;
@@ -2181,8 +2203,8 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
log.warn("failed to write cache manifest: {s}", .{@errorName(err)});
};
- assert(comp.bin_file.lock == null);
- comp.bin_file.lock = man.toOwnedLock();
+ assert(whole.lock == null);
+ whole.lock = man.toOwnedLock();
},
.incremental => {},
}
@@ -2263,13 +2285,15 @@ fn maybeGenerateAutodocs(comp: *Compilation, prog_node: *std.Progress.Node) !voi
}
fn flush(comp: *Compilation, prog_node: *std.Progress.Node) !void {
- // This is needed before reading the error flags.
- comp.bin_file.flush(comp, prog_node) catch |err| switch (err) {
- error.FlushFailure => {}, // error reported through link_error_flags
- error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr
- else => |e| return e,
- };
- comp.link_error_flags = comp.bin_file.errorFlags();
+ if (comp.bin_file) |lf| {
+ // This is needed before reading the error flags.
+ lf.flush(comp, prog_node) catch |err| switch (err) {
+ error.FlushFailure => {}, // error reported through link_error_flags
+ error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr
+ else => |e| return e,
+ };
+ comp.link_error_flags = lf.error_flags;
+ }
if (comp.module) |module| {
try link.File.C.flushEmitH(module);
@@ -2445,9 +2469,9 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
.wasm => {
const wasm = lf.cast(link.File.Wasm).?;
man.hash.add(wasm.rdynamic);
- man.hash.add(wasm.initial_memory);
- man.hash.add(wasm.max_memory);
- man.hash.add(wasm.global_base);
+ man.hash.addOptional(wasm.initial_memory);
+ man.hash.addOptional(wasm.max_memory);
+ man.hash.addOptional(wasm.global_base);
},
.macho => {
const macho = lf.cast(link.File.MachO).?;
@@ -2626,12 +2650,14 @@ fn reportMultiModuleErrors(mod: *Module) !void {
/// binary is concerned. This will remove the write flag, or close the file,
/// or whatever is needed so that it can be executed.
/// After this, one must call` makeFileWritable` before calling `update`.
-pub fn makeBinFileExecutable(self: *Compilation) !void {
- return self.bin_file.makeExecutable();
+pub fn makeBinFileExecutable(comp: *Compilation) !void {
+ const lf = comp.bin_file orelse return;
+ return lf.makeExecutable();
}
-pub fn makeBinFileWritable(self: *Compilation) !void {
- return self.bin_file.makeWritable();
+pub fn makeBinFileWritable(comp: *Compilation) !void {
+ const lf = comp.bin_file orelse return;
+ return lf.makeWritable();
}
const Header = extern struct {
@@ -2764,8 +2790,9 @@ pub fn totalErrorCount(self: *Compilation) u32 {
}
total += @intFromBool(self.link_error_flags.missing_libc);
- // Misc linker errors
- total += self.bin_file.miscErrors().len;
+ if (self.bin_file) |lf| {
+ total += lf.misc_errors.items.len;
+ }
// Compile log errors only count if there are no other errors.
if (total == 0) {
@@ -2914,7 +2941,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
}));
}
- for (self.bin_file.miscErrors()) |link_err| {
+ if (self.bin_file) |lf| for (lf.misc_errors.items) |link_err| {
try bundle.addRootErrorMessage(.{
.msg = try bundle.addString(link_err.msg),
.notes_len = @intCast(link_err.notes.len),
@@ -2925,7 +2952,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
.msg = try bundle.addString(note.msg),
}));
}
- }
+ };
if (self.module) |module| {
if (bundle.root_list.items.len == 0 and module.compile_log_decls.count() != 0) {
@@ -3246,12 +3273,12 @@ pub fn performAllTheWork(
// TODO put all the modules in a flat array to make them easy to iterate.
var seen: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .{};
defer seen.deinit(comp.gpa);
- try seen.put(comp.gpa, comp.root_mod);
+ try seen.put(comp.gpa, comp.root_mod, {});
var i: usize = 0;
while (i < seen.count()) : (i += 1) {
const mod = seen.keys()[i];
for (mod.deps.values()) |dep|
- try seen.put(comp.gpa, dep);
+ try seen.put(comp.gpa, dep, {});
const file = mod.builtin_file orelse continue;
@@ -3459,7 +3486,8 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
const gpa = comp.gpa;
const module = comp.module.?;
const decl = module.declPtr(decl_index);
- comp.bin_file.updateDeclLineNumber(module, decl_index) catch |err| {
+ const lf = comp.bin_file.?;
+ lf.updateDeclLineNumber(module, decl_index) catch |err| {
try module.failed_decls.ensureUnusedCapacity(gpa, 1);
module.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
gpa,
@@ -3782,7 +3810,7 @@ pub fn obtainCObjectCacheManifest(
// that apply both to @cImport and compiling C objects. No linking stuff here!
// Also nothing that applies only to compiling .zig code.
man.hash.add(owner_mod.sanitize_c);
- man.hash.addListOfBytes(owner_mod.clang_argv);
+ man.hash.addListOfBytes(owner_mod.cc_argv);
man.hash.add(comp.config.link_libcpp);
// When libc_installation is null it means that Zig generated this dir list
@@ -6099,7 +6127,8 @@ fn buildOutputFromZig(
const tracy_trace = trace(@src());
defer tracy_trace.end();
- var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
+ const gpa = comp.gpa;
+ var arena_allocator = std.heap.ArenaAllocator.init(gpa);
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
@@ -6110,6 +6139,7 @@ fn buildOutputFromZig(
const config = try Config.resolve(.{
.output_mode = output_mode,
+ .link_mode = .Static,
.resolved_target = comp.root_mod.resolved_target,
.is_test = false,
.have_zcu = true,
@@ -6120,7 +6150,8 @@ fn buildOutputFromZig(
.any_unwind_tables = unwind_tables,
});
- const root_mod = Package.Module.create(.{
+ const root_mod = try Package.Module.create(arena, .{
+ .global_cache_directory = comp.global_cache_directory,
.paths = .{
.root = .{ .root_dir = comp.zig_lib_directory },
.root_src_path = src_basename,
@@ -6139,6 +6170,8 @@ fn buildOutputFromZig(
},
.global = config,
.cc_argv = &.{},
+ .parent = null,
+ .builtin_mod = null,
});
const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
const target = comp.getTarget();
@@ -6148,23 +6181,21 @@ fn buildOutputFromZig(
.output_mode = output_mode,
});
- const emit_bin = Compilation.EmitLoc{
- .directory = null, // Put it in the cache directory.
- .basename = bin_basename,
- };
- const sub_compilation = try Compilation.create(comp.gpa, .{
+ const sub_compilation = try Compilation.create(gpa, .{
.global_cache_directory = comp.global_cache_directory,
.local_cache_directory = comp.global_cache_directory,
.zig_lib_directory = comp.zig_lib_directory,
.self_exe_path = comp.self_exe_path,
- .resolved = config,
+ .config = config,
.root_mod = root_mod,
.cache_mode = .whole,
.root_name = root_name,
.thread_pool = comp.thread_pool,
.libc_installation = comp.libc_installation,
- .emit_bin = emit_bin,
- .link_mode = .Static,
+ .emit_bin = .{
+ .directory = null, // Put it in the cache directory.
+ .basename = bin_basename,
+ },
.function_sections = true,
.data_sections = true,
.no_builtin = true,
@@ -6186,8 +6217,8 @@ fn buildOutputFromZig(
try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
assert(out.* == null);
- out.* = Compilation.CRTFile{
- .full_object_path = try sub_compilation.bin_file.?.emit.directory.join(comp.gpa, &[_][]const u8{
+ out.* = .{
+ .full_object_path = try sub_compilation.bin_file.?.emit.directory.join(gpa, &.{
sub_compilation.bin_file.?.emit.sub_path,
}),
.lock = sub_compilation.bin_file.toOwnedLock(),
@@ -6206,12 +6237,15 @@ pub fn build_crt_file(
defer tracy_trace.end();
const gpa = comp.gpa;
- const basename = try std.zig.binNameAlloc(gpa, .{
+ var arena_allocator = std.heap.ArenaAllocator.init(gpa);
+ defer arena_allocator.deinit();
+ const arena = arena_allocator.allocator();
+
+ const basename = try std.zig.binNameAlloc(arena, .{
.root_name = root_name,
.target = comp.root_mod.resolved_target.result,
.output_mode = output_mode,
});
- errdefer gpa.free(basename);
const config = try Config.resolve(.{
.output_mode = output_mode,
@@ -6227,7 +6261,8 @@ pub fn build_crt_file(
.Obj, .Exe => false,
},
});
- const root_mod = Package.Module.create(.{
+ const root_mod = try Package.Module.create(arena, .{
+ .global_cache_directory = comp.global_cache_directory,
.paths = .{
.root = .{ .root_dir = comp.zig_lib_directory },
.root_src_path = "",
@@ -6249,6 +6284,8 @@ pub fn build_crt_file(
},
.global = config,
.cc_argv = &.{},
+ .parent = null,
+ .builtin_mod = null,
});
const sub_compilation = try Compilation.create(gpa, .{
@@ -6257,7 +6294,7 @@ pub fn build_crt_file(
.zig_lib_directory = comp.zig_lib_directory,
.self_exe_path = comp.self_exe_path,
.cache_mode = .whole,
- .resolved = config,
+ .config = config,
.root_mod = root_mod,
.root_name = root_name,
.thread_pool = comp.thread_pool,
@@ -6287,7 +6324,7 @@ pub fn build_crt_file(
try comp.crt_files.ensureUnusedCapacity(gpa, 1);
comp.crt_files.putAssumeCapacityNoClobber(basename, .{
- .full_object_path = try sub_compilation.bin_file.?.emit.directory.join(gpa, &[_][]const u8{
+ .full_object_path = try sub_compilation.bin_file.?.emit.directory.join(gpa, &.{
sub_compilation.bin_file.?.emit.sub_path,
}),
.lock = sub_compilation.bin_file.toOwnedLock(),