Merge pull request #23836 from mlugg/incr-fixes

Incremental fixes, refactor `Zcu.File`
This commit is contained in:
Matthew Lugg 2025-05-20 03:25:19 +01:00 committed by GitHub
commit 23c817548b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
53 changed files with 2805 additions and 2403 deletions

View file

@ -508,11 +508,9 @@ pub fn build(b: *std.Build) !void {
test_step.dependOn(unit_tests_step);
const unit_tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.root_module = addCompilerMod(b, .{
.optimize = optimize,
.target = target,
.link_libc = link_libc,
.single_threaded = single_threaded,
}),
.filters = test_filters,
@ -520,6 +518,9 @@ pub fn build(b: *std.Build) !void {
.use_lld = use_llvm,
.zig_lib_dir = b.path("lib"),
});
if (link_libc) {
unit_tests.root_module.link_libc = true;
}
unit_tests.root_module.addOptions("build_options", exe_options);
unit_tests_step.dependOn(&b.addRunArtifact(unit_tests).step);
@ -650,7 +651,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
update_zig1_step.dependOn(&copy_zig_h.step);
}
const AddCompilerStepOptions = struct {
const AddCompilerModOptions = struct {
optimize: std.builtin.OptimizeMode,
target: std.Build.ResolvedTarget,
strip: ?bool = null,
@ -659,7 +660,7 @@ const AddCompilerStepOptions = struct {
single_threaded: ?bool = null,
};
fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.Step.Compile {
fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Module {
const compiler_mod = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = options.target,
@ -682,10 +683,14 @@ fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.St
compiler_mod.addImport("aro", aro_mod);
compiler_mod.addImport("aro_translate_c", aro_translate_c_mod);
return compiler_mod;
}
fn addCompilerStep(b: *std.Build, options: AddCompilerModOptions) *std.Build.Step.Compile {
const exe = b.addExecutable(.{
.name = "zig",
.max_rss = 7_800_000_000,
.root_module = compiler_mod,
.root_module = addCompilerMod(b, options),
});
exe.stack_size = stack_size;

View file

@ -1011,17 +1011,16 @@ pub const Manifest = struct {
}
/// Like `addFilePost` but when the file contents have already been loaded from disk.
/// On success, cache takes ownership of `resolved_path`.
pub fn addFilePostContents(
self: *Manifest,
resolved_path: []u8,
file_path: []const u8,
bytes: []const u8,
stat: File.Stat,
) !void {
assert(self.manifest_file != null);
const gpa = self.cache.gpa;
const prefixed_path = try self.cache.findPrefixResolved(resolved_path);
const prefixed_path = try self.cache.findPrefix(file_path);
errdefer gpa.free(prefixed_path.sub_path);
const gop = try self.files.getOrPutAdapted(gpa, prefixed_path, FilesAdapter{});

View file

@ -19,6 +19,26 @@ code_model: std.builtin.CodeModel,
omit_frame_pointer: bool,
wasi_exec_model: std.builtin.WasiExecModel,
/// Compute an abstract hash representing this `Builtin`. This is *not* a hash
/// of the resulting file contents.
pub fn hash(opts: @This()) [std.Build.Cache.bin_digest_len]u8 {
var h: Cache.Hasher = Cache.hasher_init;
inline for (@typeInfo(@This()).@"struct".fields) |f| {
if (comptime std.mem.eql(u8, f.name, "target")) {
// This needs special handling.
std.hash.autoHash(&h, opts.target.cpu);
std.hash.autoHash(&h, opts.target.os.tag);
std.hash.autoHash(&h, opts.target.os.versionRange());
std.hash.autoHash(&h, opts.target.abi);
std.hash.autoHash(&h, opts.target.ofmt);
std.hash.autoHash(&h, opts.target.dynamic_linker);
} else {
std.hash.autoHash(&h, @field(opts, f.name));
}
}
return h.finalResult();
}
pub fn generate(opts: @This(), allocator: Allocator) Allocator.Error![:0]u8 {
var buffer = std.ArrayList(u8).init(allocator);
try append(opts, &buffer);
@ -263,50 +283,66 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
}
}
pub fn populateFile(comp: *Compilation, mod: *Module, file: *File) !void {
if (mod.root.statFile(mod.root_src_path)) |stat| {
/// This essentially takes the place of `Zcu.PerThread.updateFile`, but for 'builtin' modules.
/// Instead of reading the file from disk, its contents are generated in-memory.
pub fn populateFile(opts: @This(), gpa: Allocator, file: *File) Allocator.Error!void {
assert(file.is_builtin);
assert(file.status == .never_loaded);
assert(file.source == null);
assert(file.tree == null);
assert(file.zir == null);
file.source = try opts.generate(gpa);
log.debug("parsing and generating 'builtin.zig'", .{});
file.tree = try std.zig.Ast.parse(gpa, file.source.?, .zig);
assert(file.tree.?.errors.len == 0); // builtin.zig must parse
file.zir = try AstGen.generate(gpa, file.tree.?);
assert(!file.zir.?.hasCompileErrors()); // builtin.zig must not have astgen errors
file.status = .success;
}
/// After `populateFile` succeeds, call this function to write the generated file out to disk
/// if necessary. This is useful for external tooling such as debuggers.
/// Assumes that `file.mod` is correctly set to the builtin module.
pub fn updateFileOnDisk(file: *File, comp: *Compilation) !void {
assert(file.is_builtin);
assert(file.status == .success);
assert(file.source != null);
const root_dir, const sub_path = file.path.openInfo(comp.dirs);
if (root_dir.statFile(sub_path)) |stat| {
if (stat.size != file.source.?.len) {
std.log.warn(
"the cached file '{}{s}' had the wrong size. Expected {d}, found {d}. " ++
"the cached file '{}' had the wrong size. Expected {d}, found {d}. " ++
"Overwriting with correct file contents now",
.{ mod.root, mod.root_src_path, file.source.?.len, stat.size },
.{ file.path.fmt(comp), file.source.?.len, stat.size },
);
try writeFile(file, mod);
} else {
file.stat = .{
.size = stat.size,
.inode = stat.inode,
.mtime = stat.mtime,
};
return;
}
} else |err| switch (err) {
error.BadPathName => unreachable, // it's always "builtin.zig"
error.NameTooLong => unreachable, // it's always "builtin.zig"
error.PipeBusy => unreachable, // it's not a pipe
error.NoDevice => unreachable, // it's not a pipe
error.FileNotFound => {},
error.WouldBlock => unreachable, // not asking for non-blocking I/O
error.BadPathName => unreachable, // it's always "o/digest/builtin.zig"
error.NameTooLong => unreachable, // it's always "o/digest/builtin.zig"
error.FileNotFound => try writeFile(file, mod),
// We don't expect the file to be a pipe, but can't mark `error.PipeBusy` as `unreachable`,
// because the user could always replace the file on disk.
else => |e| return e,
}
log.debug("parsing and generating '{s}'", .{mod.root_src_path});
file.tree = try std.zig.Ast.parse(comp.gpa, file.source.?, .zig);
assert(file.tree.?.errors.len == 0); // builtin.zig must parse
file.zir = try AstGen.generate(comp.gpa, file.tree.?);
assert(!file.zir.?.hasCompileErrors()); // builtin.zig must not have astgen errors
file.status = .success;
// Note that whilst we set `zir` here, we populated `path_digest`
// all the way back in `Package.Module.create`.
}
fn writeFile(file: *File, mod: *Module) !void {
var buf: [std.fs.max_path_bytes]u8 = undefined;
var af = try mod.root.atomicFile(mod.root_src_path, .{ .make_path = true }, &buf);
// `make_path` matters because the dir hasn't actually been created yet.
var af = try root_dir.atomicFile(sub_path, .{ .make_path = true });
defer af.deinit();
try af.file.writeAll(file.source.?);
af.finish() catch |err| switch (err) {
@ -331,6 +367,7 @@ fn writeFile(file: *File, mod: *Module) !void {
const builtin = @import("builtin");
const std = @import("std");
const Allocator = std.mem.Allocator;
const Cache = std.Build.Cache;
const build_options = @import("build_options");
const Module = @import("Package/Module.zig");
const assert = std.debug.assert;

File diff suppressed because it is too large Load diff

View file

@ -1723,6 +1723,19 @@ pub const FileIndex = enum(u32) {
.index = @intFromEnum(file_index) & ip.getIndexMask(u32),
};
}
pub fn toOptional(i: FileIndex) Optional {
return @enumFromInt(@intFromEnum(i));
}
pub const Optional = enum(u32) {
none = std.math.maxInt(u32),
_,
pub fn unwrap(opt: Optional) ?FileIndex {
return switch (opt) {
.none => null,
_ => @enumFromInt(@intFromEnum(opt)),
};
}
};
};
const File = struct {

View file

@ -1,15 +1,17 @@
//! Corresponds to something that Zig source code can `@import`.
/// Only files inside this directory can be imported.
root: Cache.Path,
/// Relative to `root`. May contain path separators.
/// The root directory of the module. Only files inside this directory can be imported.
root: Compilation.Path,
/// Path to the root source file of this module. Relative to `root`. May contain path separators.
root_src_path: []const u8,
/// Name used in compile errors. Looks like "root.foo.bar".
fully_qualified_name: []const u8,
/// The dependency table of this module. Shared dependencies such as 'std',
/// 'builtin', and 'root' are not specified in every dependency table, but
/// instead only in the table of `main_mod`. `Module.importFile` is
/// responsible for detecting these names and using the correct package.
/// The dependency table of this module. The shared dependencies 'std' and
/// 'root' are not specified in every module dependency table, but are stored
/// separately in `Zcu`. 'builtin' is also not stored here, although it is
/// not necessarily the same between all modules. Handling of `@import` in
/// the rest of the compiler must detect these special names and use the
/// correct module instead of consulting `deps`.
deps: Deps = .{},
resolved_target: ResolvedTarget,
@ -33,25 +35,14 @@ cc_argv: []const []const u8,
structured_cfg: bool,
no_builtin: bool,
/// If the module is an `@import("builtin")` module, this is the `File` that
/// is preallocated for it. Otherwise this field is null.
builtin_file: ?*File,
pub const Deps = std.StringArrayHashMapUnmanaged(*Module);
pub fn isBuiltin(m: Module) bool {
return m.builtin_file != null;
}
pub const Tree = struct {
/// Each `Package` exposes a `Module` with build.zig as its root source file.
build_module_table: std.AutoArrayHashMapUnmanaged(MultiHashHexDigest, *Module),
};
pub const CreateOptions = struct {
/// Where to store builtin.zig. The global cache directory is used because
/// it is a pure function based on CLI flags.
global_cache_directory: Cache.Directory,
paths: Paths,
fully_qualified_name: []const u8,
@ -61,15 +52,8 @@ pub const CreateOptions = struct {
/// If this is null then `resolved_target` must be non-null.
parent: ?*Package.Module,
builtin_mod: ?*Package.Module,
/// Allocated into the given `arena`. Should be shared across all module creations in a Compilation.
/// Ignored if `builtin_mod` is passed or if `!have_zcu`.
/// Otherwise, may be `null` only if this Compilation consists of a single module.
builtin_modules: ?*std.StringHashMapUnmanaged(*Module),
pub const Paths = struct {
root: Cache.Path,
root: Compilation.Path,
/// Relative to `root`. May contain path separators.
root_src_path: []const u8,
};
@ -401,126 +385,13 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
.cc_argv = options.cc_argv,
.structured_cfg = structured_cfg,
.no_builtin = no_builtin,
.builtin_file = null,
};
const opt_builtin_mod = options.builtin_mod orelse b: {
if (!options.global.have_zcu) break :b null;
const generated_builtin_source = try Builtin.generate(.{
.target = target,
.zig_backend = zig_backend,
.output_mode = options.global.output_mode,
.link_mode = options.global.link_mode,
.unwind_tables = unwind_tables,
.is_test = options.global.is_test,
.single_threaded = single_threaded,
.link_libc = options.global.link_libc,
.link_libcpp = options.global.link_libcpp,
.optimize_mode = optimize_mode,
.error_tracing = error_tracing,
.valgrind = valgrind,
.sanitize_thread = sanitize_thread,
.fuzz = fuzz,
.pic = pic,
.pie = options.global.pie,
.strip = strip,
.code_model = code_model,
.omit_frame_pointer = omit_frame_pointer,
.wasi_exec_model = options.global.wasi_exec_model,
}, arena);
const new = if (options.builtin_modules) |builtins| new: {
const gop = try builtins.getOrPut(arena, generated_builtin_source);
if (gop.found_existing) break :b gop.value_ptr.*;
errdefer builtins.removeByPtr(gop.key_ptr);
const new = try arena.create(Module);
gop.value_ptr.* = new;
break :new new;
} else try arena.create(Module);
errdefer if (options.builtin_modules) |builtins| assert(builtins.remove(generated_builtin_source));
const new_file = try arena.create(File);
const hex_digest = digest: {
var hasher: Cache.Hasher = Cache.hasher_init;
hasher.update(generated_builtin_source);
var bin_digest: Cache.BinDigest = undefined;
hasher.final(&bin_digest);
var hex_digest: Cache.HexDigest = undefined;
_ = std.fmt.bufPrint(
&hex_digest,
"{s}",
.{std.fmt.fmtSliceHexLower(&bin_digest)},
) catch unreachable;
break :digest hex_digest;
};
const builtin_sub_path = try arena.dupe(u8, "b" ++ std.fs.path.sep_str ++ hex_digest);
new.* = .{
.root = .{
.root_dir = options.global_cache_directory,
.sub_path = builtin_sub_path,
},
.root_src_path = "builtin.zig",
.fully_qualified_name = if (options.parent == null)
"builtin"
else
try std.fmt.allocPrint(arena, "{s}.builtin", .{options.fully_qualified_name}),
.resolved_target = .{
.result = target,
.is_native_os = resolved_target.is_native_os,
.is_native_abi = resolved_target.is_native_abi,
.llvm_cpu_features = llvm_cpu_features,
},
.optimize_mode = optimize_mode,
.single_threaded = single_threaded,
.error_tracing = error_tracing,
.valgrind = valgrind,
.pic = pic,
.strip = strip,
.omit_frame_pointer = omit_frame_pointer,
.stack_check = stack_check,
.stack_protector = stack_protector,
.code_model = code_model,
.red_zone = red_zone,
.sanitize_c = sanitize_c,
.sanitize_thread = sanitize_thread,
.fuzz = fuzz,
.unwind_tables = unwind_tables,
.cc_argv = &.{},
.structured_cfg = structured_cfg,
.no_builtin = no_builtin,
.builtin_file = new_file,
};
new_file.* = .{
.sub_file_path = "builtin.zig",
.stat = undefined,
.source = generated_builtin_source,
.tree = null,
.zir = null,
.zoir = null,
.status = .never_loaded,
.mod = new,
};
break :b new;
};
if (opt_builtin_mod) |builtin_mod| {
try mod.deps.ensureUnusedCapacity(arena, 1);
mod.deps.putAssumeCapacityNoClobber("builtin", builtin_mod);
}
return mod;
}
/// All fields correspond to `CreateOptions`.
pub const LimitedOptions = struct {
root: Cache.Path,
root: Compilation.Path,
root_src_path: []const u8,
fully_qualified_name: []const u8,
};
@ -553,18 +424,73 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*P
.cc_argv = undefined,
.structured_cfg = undefined,
.no_builtin = undefined,
.builtin_file = null,
};
return mod;
}
/// Asserts that the module has a builtin module, which is not true for non-zig
/// modules such as ones only used for `@embedFile`, or the root module when
/// there is no Zig Compilation Unit.
pub fn getBuiltinDependency(m: Module) *Module {
const result = m.deps.values()[0];
assert(result.isBuiltin());
return result;
/// Does not ensure that the module's root directory exists on-disk; see `Builtin.updateFileOnDisk` for that task.
pub fn createBuiltin(arena: Allocator, opts: Builtin, dirs: Compilation.Directories) Allocator.Error!*Module {
const sub_path = "b" ++ Cache.binToHex(opts.hash());
const new = try arena.create(Module);
new.* = .{
.root = try .fromRoot(arena, dirs, .global_cache, sub_path),
.root_src_path = "builtin.zig",
.fully_qualified_name = "builtin",
.resolved_target = .{
.result = opts.target,
// These values are not in `opts`, but do not matter because `builtin.zig` contains no runtime code.
.is_native_os = false,
.is_native_abi = false,
.llvm_cpu_features = null,
},
.optimize_mode = opts.optimize_mode,
.single_threaded = opts.single_threaded,
.error_tracing = opts.error_tracing,
.valgrind = opts.valgrind,
.pic = opts.pic,
.strip = opts.strip,
.omit_frame_pointer = opts.omit_frame_pointer,
.code_model = opts.code_model,
.sanitize_thread = opts.sanitize_thread,
.fuzz = opts.fuzz,
.unwind_tables = opts.unwind_tables,
.cc_argv = &.{},
// These values are not in `opts`, but do not matter because `builtin.zig` contains no runtime code.
.stack_check = false,
.stack_protector = 0,
.red_zone = false,
.sanitize_c = .off,
.structured_cfg = false,
.no_builtin = false,
};
return new;
}
/// Returns the `Builtin` which forms the contents of `@import("builtin")` for this module.
pub fn getBuiltinOptions(m: Module, global: Compilation.Config) Builtin {
assert(global.have_zcu);
return .{
.target = m.resolved_target.result,
.zig_backend = target_util.zigBackend(m.resolved_target.result, global.use_llvm),
.output_mode = global.output_mode,
.link_mode = global.link_mode,
.unwind_tables = m.unwind_tables,
.is_test = global.is_test,
.single_threaded = m.single_threaded,
.link_libc = global.link_libc,
.link_libcpp = global.link_libcpp,
.optimize_mode = m.optimize_mode,
.error_tracing = m.error_tracing,
.valgrind = m.valgrind,
.sanitize_thread = m.sanitize_thread,
.fuzz = m.fuzz,
.pic = m.pic,
.pie = global.pie,
.strip = m.strip,
.code_model = m.code_model,
.omit_frame_pointer = m.omit_frame_pointer,
.wasi_exec_model = global.wasi_exec_model,
};
}
const Module = @This();

View file

@ -829,7 +829,7 @@ pub const Block = struct {
pub fn ownerModule(block: Block) *Package.Module {
const zcu = block.sema.pt.zcu;
return zcu.namespacePtr(block.namespace).fileScope(zcu).mod;
return zcu.namespacePtr(block.namespace).fileScope(zcu).mod.?;
}
fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index {
@ -1127,10 +1127,10 @@ fn analyzeBodyInner(
// The hashmap lookup in here is a little expensive, and LLVM fails to optimize it away.
if (build_options.enable_logging) {
std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ sub_file_path: {
std.log.scoped(.sema_zir).debug("sema ZIR {} %{d}", .{ path: {
const file_index = block.src_base_inst.resolveFile(&zcu.intern_pool);
const file = zcu.fileByIndex(file_index);
break :sub_file_path file.sub_file_path;
break :path file.path.fmt(zcu.comp);
}, inst });
}
@ -6162,50 +6162,67 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
}
const parent_mod = parent_block.ownerModule();
const digest = Cache.binToHex(c_import_res.digest);
const c_import_zig_path = try comp.arena.dupe(u8, "o" ++ std.fs.path.sep_str ++ digest);
const c_import_mod = Package.Module.create(comp.arena, .{
.global_cache_directory = comp.global_cache_directory,
.paths = .{
.root = .{
.root_dir = comp.local_cache_directory,
.sub_path = c_import_zig_path,
const new_file_index = file: {
const c_import_zig_path = try comp.arena.dupe(u8, "o" ++ std.fs.path.sep_str ++ digest);
const c_import_mod = Package.Module.create(comp.arena, .{
.paths = .{
.root = try .fromRoot(comp.arena, comp.dirs, .local_cache, c_import_zig_path),
.root_src_path = "cimport.zig",
},
.root_src_path = "cimport.zig",
},
.fully_qualified_name = c_import_zig_path,
.cc_argv = parent_mod.cc_argv,
.inherited = .{},
.global = comp.config,
.parent = parent_mod,
.builtin_mod = parent_mod.getBuiltinDependency(),
.builtin_modules = null, // `builtin_mod` is set
}) catch |err| switch (err) {
// None of these are possible because we are creating a package with
// the exact same configuration as the parent package, which already
// passed these checks.
error.ValgrindUnsupportedOnTarget => unreachable,
error.TargetRequiresSingleThreaded => unreachable,
error.BackendRequiresSingleThreaded => unreachable,
error.TargetRequiresPic => unreachable,
error.PieRequiresPic => unreachable,
error.DynamicLinkingRequiresPic => unreachable,
error.TargetHasNoRedZone => unreachable,
error.StackCheckUnsupportedByTarget => unreachable,
error.StackProtectorUnsupportedByTarget => unreachable,
error.StackProtectorUnavailableWithoutLibC => unreachable,
.fully_qualified_name = c_import_zig_path,
.cc_argv = parent_mod.cc_argv,
.inherited = .{},
.global = comp.config,
.parent = parent_mod,
}) catch |err| switch (err) {
// None of these are possible because we are creating a package with
// the exact same configuration as the parent package, which already
// passed these checks.
error.ValgrindUnsupportedOnTarget => unreachable,
error.TargetRequiresSingleThreaded => unreachable,
error.BackendRequiresSingleThreaded => unreachable,
error.TargetRequiresPic => unreachable,
error.PieRequiresPic => unreachable,
error.DynamicLinkingRequiresPic => unreachable,
error.TargetHasNoRedZone => unreachable,
error.StackCheckUnsupportedByTarget => unreachable,
error.StackProtectorUnsupportedByTarget => unreachable,
error.StackProtectorUnavailableWithoutLibC => unreachable,
else => |e| return e,
else => |e| return e,
};
const c_import_file_path: Compilation.Path = try c_import_mod.root.join(gpa, comp.dirs, "cimport.zig");
errdefer c_import_file_path.deinit(gpa);
const c_import_file = try gpa.create(Zcu.File);
errdefer gpa.destroy(c_import_file);
const c_import_file_index = try zcu.intern_pool.createFile(gpa, pt.tid, .{
.bin_digest = c_import_file_path.digest(),
.file = c_import_file,
.root_type = .none,
});
c_import_file.* = .{
.status = .never_loaded,
.stat = undefined,
.is_builtin = false,
.path = c_import_file_path,
.source = null,
.tree = null,
.zir = null,
.zoir = null,
.mod = c_import_mod,
.sub_file_path = "cimport.zig",
.module_changed = false,
.prev_zir = null,
.zoir_invalidated = false,
};
break :file c_import_file_index;
};
const result = pt.importPkg(c_import_mod) catch |err|
pt.updateFile(new_file_index, zcu.fileByIndex(new_file_index)) catch |err|
return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
const path_digest = zcu.filePathDigest(result.file_index);
pt.updateFile(result.file, path_digest) catch |err|
return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
try pt.ensureFileAnalyzed(result.file_index);
const ty = zcu.fileRootType(result.file_index);
try pt.ensureFileAnalyzed(new_file_index);
const ty = zcu.fileRootType(new_file_index);
try sema.declareDependency(.{ .interned = ty });
try sema.addTypeReferenceEntry(src, ty);
return Air.internedToRef(ty);
@ -14097,25 +14114,19 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
const operand_src = block.tokenOffset(inst_data.src_tok);
const operand = sema.code.nullTerminatedString(extra.path);
const result = pt.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) {
error.ImportOutsideModulePath => {
return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand});
},
error.ModuleNotFound => {
return sema.fail(block, operand_src, "no module named '{s}' available within module {s}", .{
operand, block.getFileScope(zcu).mod.fully_qualified_name,
});
},
else => {
// TODO: these errors are file system errors; make sure an update() will
// retry this and not cache the file system error, which may be transient.
return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) });
},
const result = pt.doImport(block.getFileScope(zcu), operand) catch |err| switch (err) {
error.ModuleNotFound => return sema.fail(block, operand_src, "no module named '{s}' available within module '{s}'", .{
operand, block.getFileScope(zcu).mod.?.fully_qualified_name,
}),
error.IllegalZigImport => unreachable, // caught before semantic analysis
error.OutOfMemory => |e| return e,
};
switch (result.file.getMode()) {
const file_index = result.file;
const file = zcu.fileByIndex(file_index);
switch (file.getMode()) {
.zig => {
try pt.ensureFileAnalyzed(result.file_index);
const ty = zcu.fileRootType(result.file_index);
try pt.ensureFileAnalyzed(file_index);
const ty = zcu.fileRootType(file_index);
try sema.declareDependency(.{ .interned = ty });
try sema.addTypeReferenceEntry(operand_src, ty);
return Air.internedToRef(ty);
@ -14129,11 +14140,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
break :b res_ty.toIntern();
};
try sema.declareDependency(.{ .zon_file = result.file_index });
try sema.declareDependency(.{ .zon_file = file_index });
const interned = try LowerZon.run(
sema,
result.file,
result.file_index,
file,
file_index,
res_ty,
operand_src,
block,
@ -17308,10 +17319,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
const name = name: {
// TODO: we should probably store this name in the ZIR to avoid this complexity.
const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?;
const tree = file.getTree(sema.gpa) catch |err| {
const tree = file.getTree(zcu) catch |err| {
// In this case we emit a warning + a less precise source location.
log.warn("unable to load {s}: {s}", .{
file.sub_file_path, @errorName(err),
log.warn("unable to load {}: {s}", .{
file.path.fmt(zcu.comp), @errorName(err),
});
break :name null;
};
@ -17336,10 +17347,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
const msg = msg: {
const name = name: {
const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?;
const tree = file.getTree(sema.gpa) catch |err| {
const tree = file.getTree(zcu) catch |err| {
// In this case we emit a warning + a less precise source location.
log.warn("unable to load {s}: {s}", .{
file.sub_file_path, @errorName(err),
log.warn("unable to load {}: {s}", .{
file.path.fmt(zcu.comp), @errorName(err),
});
break :name null;
};
@ -17433,7 +17444,7 @@ fn zirBuiltinSrc(
};
const module_name_val = v: {
const module_name = file_scope.mod.fully_qualified_name;
const module_name = file_scope.mod.?.fully_qualified_name;
const array_ty = try pt.intern(.{ .array_type = .{
.len = module_name.len,
.sentinel = .zero_u8,

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -333,7 +333,7 @@ pub fn generate(
const func = zcu.funcInfo(func_index);
const fn_type = Type.fromInterned(func.ty);
const file_scope = zcu.navFileScope(func.owner_nav);
const target = &file_scope.mod.resolved_target.result;
const target = &file_scope.mod.?.resolved_target.result;
var branch_stack = std.ArrayList(Branch).init(gpa);
defer {

View file

@ -342,7 +342,7 @@ pub fn generate(
const func = zcu.funcInfo(func_index);
const func_ty = Type.fromInterned(func.ty);
const file_scope = zcu.navFileScope(func.owner_nav);
const target = &file_scope.mod.resolved_target.result;
const target = &file_scope.mod.?.resolved_target.result;
var branch_stack = std.ArrayList(Branch).init(gpa);
defer {

View file

@ -767,7 +767,7 @@ pub fn generate(
const ip = &zcu.intern_pool;
const func = zcu.funcInfo(func_index);
const fn_type = Type.fromInterned(func.ty);
const mod = zcu.navFileScope(func.owner_nav).mod;
const mod = zcu.navFileScope(func.owner_nav).mod.?;
var branch_stack = std.ArrayList(Branch).init(gpa);
defer {

View file

@ -275,7 +275,7 @@ pub fn generate(
const func = zcu.funcInfo(func_index);
const func_ty = Type.fromInterned(func.ty);
const file_scope = zcu.navFileScope(func.owner_nav);
const target = &file_scope.mod.resolved_target.result;
const target = &file_scope.mod.?.resolved_target.result;
var branch_stack = std.ArrayList(Branch).init(gpa);
defer {

View file

@ -1268,7 +1268,7 @@ pub fn function(
const gpa = zcu.gpa;
const cg = zcu.funcInfo(func_index);
const file_scope = zcu.navFileScope(cg.owner_nav);
const target = &file_scope.mod.resolved_target.result;
const target = &file_scope.mod.?.resolved_target.result;
const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu);
const fn_info = zcu.typeToFunc(fn_ty).?;
const ip = &zcu.intern_pool;

View file

@ -888,7 +888,7 @@ pub fn generate(
const ip = &zcu.intern_pool;
const func = zcu.funcInfo(func_index);
const fn_type: Type = .fromInterned(func.ty);
const mod = zcu.navFileScope(func.owner_nav).mod;
const mod = zcu.navFileScope(func.owner_nav).mod.?;
var function: CodeGen = .{
.gpa = gpa,

View file

@ -56,7 +56,7 @@ pub fn generateFunction(
) CodeGenError!void {
const zcu = pt.zcu;
const func = zcu.funcInfo(func_index);
const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result;
const target = zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
switch (target_util.zigBackend(target, false)) {
else => unreachable,
inline .stage2_aarch64,
@ -81,7 +81,7 @@ pub fn generateLazyFunction(
) CodeGenError!void {
const zcu = pt.zcu;
const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index|
zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.resolved_target.result
zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result
else
zcu.getTarget();
switch (target_util.zigBackend(target, false)) {
@ -722,7 +722,7 @@ fn lowerNavRef(
const zcu = pt.zcu;
const gpa = zcu.gpa;
const ip = &zcu.intern_pool;
const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result;
const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
const is_obj = lf.comp.config.output_mode == .Obj;
const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip));
@ -884,7 +884,7 @@ fn genNavRef(
else
.{ false, .none, nav.isThreadlocal(ip) };
const single_threaded = zcu.navFileScope(nav_index).mod.single_threaded;
const single_threaded = zcu.navFileScope(nav_index).mod.?.single_threaded;
const name = nav.name;
if (lf.cast(.elf)) |elf_file| {
const zo = elf_file.zigObjectPtr().?;

View file

@ -2670,7 +2670,7 @@ pub fn genTypeDecl(
_ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});
try writer.writeByte(';');
const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip);
if (!zcu.fileByIndex(file_scope).mod.strip) try writer.print(" /* {} */", .{
if (!zcu.fileByIndex(file_scope).mod.?.strip) try writer.print(" /* {} */", .{
ty.containerTypeName(ip).fmt(ip),
});
try writer.writeByte('\n');

View file

@ -587,13 +587,8 @@ pub const Object = struct {
// into the garbage can by converting into absolute paths. What
// a terrible tragedy.
const compile_unit_dir = blk: {
if (comp.zcu) |zcu| m: {
const d = try zcu.main_mod.root.joinString(arena, "");
if (d.len == 0) break :m;
if (std.fs.path.isAbsolute(d)) break :blk d;
break :blk std.fs.realpathAlloc(arena, d) catch break :blk d;
}
break :blk try std.process.getCwdAlloc(arena);
const zcu = comp.zcu orelse break :blk comp.dirs.cwd;
break :blk try zcu.main_mod.root.toAbsolute(comp.dirs, arena);
};
const debug_file = try builder.debugFile(
@ -1135,7 +1130,7 @@ pub const Object = struct {
const func = zcu.funcInfo(func_index);
const nav = ip.getNav(func.owner_nav);
const file_scope = zcu.navFileScopeIndex(func.owner_nav);
const owner_mod = zcu.fileByIndex(file_scope).mod;
const owner_mod = zcu.fileByIndex(file_scope).mod.?;
const fn_ty = Type.fromInterned(func.ty);
const fn_info = zcu.typeToFunc(fn_ty).?;
const target = owner_mod.resolved_target.result;
@ -1735,20 +1730,14 @@ pub const Object = struct {
const gop = try o.debug_file_map.getOrPut(gpa, file_index);
errdefer assert(o.debug_file_map.remove(file_index));
if (gop.found_existing) return gop.value_ptr.*;
const file = o.pt.zcu.fileByIndex(file_index);
const zcu = o.pt.zcu;
const path = zcu.fileByIndex(file_index).path;
const abs_path = try path.toAbsolute(zcu.comp.dirs, gpa);
defer gpa.free(abs_path);
gop.value_ptr.* = try o.builder.debugFile(
try o.builder.metadataString(std.fs.path.basename(file.sub_file_path)),
dir_path: {
const sub_path = std.fs.path.dirname(file.sub_file_path) orelse "";
const dir_path = try file.mod.root.joinString(gpa, sub_path);
defer gpa.free(dir_path);
if (std.fs.path.isAbsolute(dir_path))
break :dir_path try o.builder.metadataString(dir_path);
var abs_buffer: [std.fs.max_path_bytes]u8 = undefined;
const abs_path = std.fs.realpath(dir_path, &abs_buffer) catch
break :dir_path try o.builder.metadataString(dir_path);
break :dir_path try o.builder.metadataString(abs_path);
},
try o.builder.metadataString(std.fs.path.basename(abs_path)),
try o.builder.metadataString(std.fs.path.dirname(abs_path) orelse ""),
);
return gop.value_ptr.*;
}
@ -2646,11 +2635,9 @@ pub const Object = struct {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
const std_mod = zcu.std_mod;
const std_file_imported = pt.importPkg(std_mod) catch unreachable;
const std_file_index = zcu.module_roots.get(zcu.std_mod).?.unwrap().?;
const builtin_str = try ip.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);
const std_file_root_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
const std_file_root_type = Type.fromInterned(zcu.fileRootType(std_file_index));
const std_namespace = ip.namespacePtr(std_file_root_type.getNamespaceIndex(zcu));
const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }).?;
@ -2683,7 +2670,7 @@ pub const Object = struct {
const ip = &zcu.intern_pool;
const gpa = o.gpa;
const nav = ip.getNav(nav_index);
const owner_mod = zcu.navFileScope(nav_index).mod;
const owner_mod = zcu.navFileScope(nav_index).mod.?;
const ty: Type = .fromInterned(nav.typeOf(ip));
const gop = try o.nav_map.getOrPut(gpa, nav_index);
if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function;
@ -3013,7 +3000,7 @@ pub const Object = struct {
if (is_extern) {
variable_index.setLinkage(.external, &o.builder);
variable_index.setUnnamedAddr(.default, &o.builder);
if (is_threadlocal and !zcu.navFileScope(nav_index).mod.single_threaded)
if (is_threadlocal and !zcu.navFileScope(nav_index).mod.?.single_threaded)
variable_index.setThreadLocal(.generaldynamic, &o.builder);
if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder);
if (is_dll_import) variable_index.setDllStorageClass(.dllimport, &o.builder);
@ -4514,7 +4501,7 @@ pub const NavGen = struct {
err_msg: ?*Zcu.ErrorMsg,
fn ownerModule(ng: NavGen) *Package.Module {
return ng.object.pt.zcu.navFileScope(ng.nav_index).mod;
return ng.object.pt.zcu.navFileScope(ng.nav_index).mod.?;
}
fn todo(ng: *NavGen, comptime format: []const u8, args: anytype) Error {
@ -4557,7 +4544,7 @@ pub const NavGen = struct {
}, &o.builder);
const file_scope = zcu.navFileScopeIndex(nav_index);
const mod = zcu.fileByIndex(file_scope).mod;
const mod = zcu.fileByIndex(file_scope).mod.?;
if (is_threadlocal and !mod.single_threaded)
variable_index.setThreadLocal(.generaldynamic, &o.builder);
@ -5121,7 +5108,7 @@ pub const FuncGen = struct {
const func = zcu.funcInfo(inline_func);
const nav = ip.getNav(func.owner_nav);
const file_scope = zcu.navFileScopeIndex(func.owner_nav);
const mod = zcu.fileByIndex(file_scope).mod;
const mod = zcu.fileByIndex(file_scope).mod.?;
self.file = try o.getDebugFile(file_scope);

View file

@ -201,7 +201,7 @@ pub const Object = struct {
) !void {
const zcu = pt.zcu;
const gpa = zcu.gpa;
const structured_cfg = zcu.navFileScope(nav_index).mod.structured_cfg;
const structured_cfg = zcu.navFileScope(nav_index).mod.?.structured_cfg;
var nav_gen = NavGen{
.gpa = gpa,

View file

@ -86,15 +86,12 @@ fn dumpStatusReport() !void {
const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu) orelse {
const file = zcu.fileByIndex(block.src_base_inst.resolveFile(&zcu.intern_pool));
try stderr.writeAll("Analyzing lost instruction in file '");
try writeFilePath(file, stderr);
try stderr.writeAll("'. This should not happen!\n\n");
try stderr.print("Analyzing lost instruction in file '{}'. This should not happen!\n\n", .{file.path.fmt(zcu.comp)});
return;
};
try stderr.writeAll("Analyzing ");
try writeFilePath(file, stderr);
try stderr.writeAll("\n");
try stderr.print("Analyzing '{}'\n", .{file.path.fmt(zcu.comp)});
print_zir.renderInstructionContext(
allocator,
@ -108,23 +105,24 @@ fn dumpStatusReport() !void {
error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"),
else => |e| return e,
};
try stderr.writeAll(" For full context, use the command\n zig ast-check -t ");
try writeFilePath(file, stderr);
try stderr.writeAll("\n\n");
try stderr.print(
\\ For full context, use the command
\\ zig ast-check -t {}
\\
\\
, .{file.path.fmt(zcu.comp)});
var parent = anal.parent;
while (parent) |curr| {
fba.reset();
try stderr.writeAll(" in ");
const cur_block_file, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse {
const cur_block_file = zcu.fileByIndex(curr.block.src_base_inst.resolveFile(&zcu.intern_pool));
try writeFilePath(cur_block_file, stderr);
try stderr.writeAll("\n > [lost instruction; this should not happen]\n");
const cur_block_file = zcu.fileByIndex(curr.block.src_base_inst.resolveFile(&zcu.intern_pool));
try stderr.print(" in {}\n", .{cur_block_file.path.fmt(zcu.comp)});
_, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse {
try stderr.writeAll(" > [lost instruction; this should not happen]\n");
parent = curr.parent;
continue;
};
try writeFilePath(cur_block_file, stderr);
try stderr.writeAll("\n > ");
try stderr.writeAll(" > ");
print_zir.renderSingleInstruction(
allocator,
curr.body[curr.body_index],
@ -146,18 +144,6 @@ fn dumpStatusReport() !void {
var crash_heap: [16 * 4096]u8 = undefined;
fn writeFilePath(file: *Zcu.File, writer: anytype) !void {
if (file.mod.root.root_dir.path) |path| {
try writer.writeAll(path);
try writer.writeAll(std.fs.path.sep_str);
}
if (file.mod.root.sub_path.len > 0) {
try writer.writeAll(file.mod.root.sub_path);
try writer.writeAll(std.fs.path.sep_str);
}
try writer.writeAll(file.sub_file_path);
}
pub fn compilerPanic(msg: []const u8, maybe_ret_addr: ?usize) noreturn {
@branchHint(.cold);
PanicSwitch.preDispatch();

View file

@ -1,15 +1,18 @@
const std = @import("std");
const builtin = @import("builtin");
const mem = std.mem;
const Allocator = mem.Allocator;
const os = std.os;
const fs = std.fs;
const Cache = std.Build.Cache;
const Compilation = @import("Compilation.zig");
const Package = @import("Package.zig");
const build_options = @import("build_options");
/// Returns the sub_path that worked, or `null` if none did.
/// The path of the returned Directory is relative to `base`.
/// The handle of the returned Directory is open.
fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory {
fn testZigInstallPrefix(base_dir: fs.Dir) ?Cache.Directory {
const test_index_file = "std" ++ fs.path.sep_str ++ "std.zig";
zig_dir: {
@ -21,7 +24,7 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory {
break :zig_dir;
};
file.close();
return Compilation.Directory{ .handle = test_zig_dir, .path = lib_zig };
return .{ .handle = test_zig_dir, .path = lib_zig };
}
// Try lib/std/std.zig
@ -31,37 +34,50 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory {
return null;
};
file.close();
return Compilation.Directory{ .handle = test_zig_dir, .path = "lib" };
}
/// This is a small wrapper around selfExePathAlloc that adds support for WASI
/// based on a hard-coded Preopen directory ("/zig")
pub fn findZigExePath(allocator: mem.Allocator) ![]u8 {
if (builtin.os.tag == .wasi) {
@compileError("this function is unsupported on WASI");
}
return fs.selfExePathAlloc(allocator);
return .{ .handle = test_zig_dir, .path = "lib" };
}
/// Both the directory handle and the path are newly allocated resources which the caller now owns.
pub fn findZigLibDir(gpa: mem.Allocator) !Compilation.Directory {
const self_exe_path = try findZigExePath(gpa);
pub fn findZigLibDir(gpa: Allocator) !Cache.Directory {
const cwd_path = try getResolvedCwd(gpa);
defer gpa.free(cwd_path);
const self_exe_path = try fs.selfExePathAlloc(gpa);
defer gpa.free(self_exe_path);
return findZigLibDirFromSelfExe(gpa, self_exe_path);
return findZigLibDirFromSelfExe(gpa, cwd_path, self_exe_path);
}
/// Like `std.process.getCwdAlloc`, but also resolves the path with `std.fs.path.resolve`. This
/// means the path has no repeated separators, no "." or ".." components, and no trailing separator.
/// On WASI, "" is returned instead of ".".
pub fn getResolvedCwd(gpa: Allocator) error{
OutOfMemory,
CurrentWorkingDirectoryUnlinked,
Unexpected,
}![]u8 {
if (builtin.target.os.tag == .wasi) {
if (std.debug.runtime_safety) {
const cwd = try std.process.getCwdAlloc(gpa);
defer gpa.free(cwd);
std.debug.assert(mem.eql(u8, cwd, "."));
}
return "";
}
const cwd = try std.process.getCwdAlloc(gpa);
defer gpa.free(cwd);
const resolved = try fs.path.resolve(gpa, &.{cwd});
std.debug.assert(fs.path.isAbsolute(resolved));
return resolved;
}
/// Both the directory handle and the path are newly allocated resources which the caller now owns.
pub fn findZigLibDirFromSelfExe(
allocator: mem.Allocator,
allocator: Allocator,
/// The return value of `getResolvedCwd`.
/// Passed as an argument to avoid pointlessly repeating the call.
cwd_path: []const u8,
self_exe_path: []const u8,
) error{
OutOfMemory,
FileNotFound,
CurrentWorkingDirectoryUnlinked,
Unexpected,
}!Compilation.Directory {
) error{ OutOfMemory, FileNotFound }!Cache.Directory {
const cwd = fs.cwd();
var cur_path: []const u8 = self_exe_path;
while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) {
@ -69,18 +85,20 @@ pub fn findZigLibDirFromSelfExe(
defer base_dir.close();
const sub_directory = testZigInstallPrefix(base_dir) orelse continue;
const p = try fs.path.join(allocator, &[_][]const u8{ dirname, sub_directory.path.? });
const p = try fs.path.join(allocator, &.{ dirname, sub_directory.path.? });
defer allocator.free(p);
return Compilation.Directory{
const resolved = try resolvePath(allocator, cwd_path, &.{p});
return .{
.handle = sub_directory.handle,
.path = try resolvePath(allocator, p),
.path = if (resolved.len == 0) null else resolved,
};
}
return error.FileNotFound;
}
/// Caller owns returned memory.
pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 {
pub fn resolveGlobalCacheDir(allocator: Allocator) ![]u8 {
if (builtin.os.tag == .wasi)
@compileError("on WASI the global cache dir must be resolved with preopens");
@ -91,56 +109,107 @@ pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 {
if (builtin.os.tag != .windows) {
if (std.zig.EnvVar.XDG_CACHE_HOME.getPosix()) |cache_root| {
if (cache_root.len > 0) {
return fs.path.join(allocator, &[_][]const u8{ cache_root, appname });
return fs.path.join(allocator, &.{ cache_root, appname });
}
}
if (std.zig.EnvVar.HOME.getPosix()) |home| {
return fs.path.join(allocator, &[_][]const u8{ home, ".cache", appname });
return fs.path.join(allocator, &.{ home, ".cache", appname });
}
}
return fs.getAppDataDir(allocator, appname);
}
/// Similar to std.fs.path.resolve, with a few important differences:
/// * If the input is an absolute path, check it against the cwd and try to
/// convert it to a relative path.
/// * If the resulting path would start with a relative up-dir ("../"), instead
/// return an absolute path based on the cwd.
/// * When targeting WASI, fail with an error message if an absolute path is
/// used.
/// Similar to `fs.path.resolve`, but converts to a cwd-relative path, or, if that would
/// start with a relative up-dir (".."), an absolute path based on the cwd. Also, the cwd
/// returns the empty string ("") instead of ".".
pub fn resolvePath(
ally: mem.Allocator,
p: []const u8,
) error{
OutOfMemory,
CurrentWorkingDirectoryUnlinked,
Unexpected,
}![]u8 {
if (fs.path.isAbsolute(p)) {
const cwd_path = try std.process.getCwdAlloc(ally);
defer ally.free(cwd_path);
const relative = try fs.path.relative(ally, cwd_path, p);
if (isUpDir(relative)) {
ally.free(relative);
return ally.dupe(u8, p);
} else {
return relative;
}
} else {
const resolved = try fs.path.resolve(ally, &.{p});
if (isUpDir(resolved)) {
ally.free(resolved);
const cwd_path = try std.process.getCwdAlloc(ally);
defer ally.free(cwd_path);
return fs.path.resolve(ally, &.{ cwd_path, p });
} else {
return resolved;
gpa: Allocator,
/// The return value of `getResolvedCwd`.
/// Passed as an argument to avoid pointlessly repeating the call.
cwd_resolved: []const u8,
paths: []const []const u8,
) Allocator.Error![]u8 {
if (builtin.target.os.tag == .wasi) {
std.debug.assert(mem.eql(u8, cwd_resolved, ""));
const res = try fs.path.resolve(gpa, paths);
if (mem.eql(u8, res, ".")) {
gpa.free(res);
return "";
}
return res;
}
// Heuristic for a fast path: if no component is absolute and ".." never appears, we just need to resolve `paths`.
for (paths) |p| {
if (fs.path.isAbsolute(p)) break; // absolute path
if (mem.indexOf(u8, p, "..") != null) break; // may contain up-dir
} else {
// no absolute path, no "..".
const res = try fs.path.resolve(gpa, paths);
if (mem.eql(u8, res, ".")) {
gpa.free(res);
return "";
}
std.debug.assert(!fs.path.isAbsolute(res));
std.debug.assert(!isUpDir(res));
return res;
}
// The fast path failed; resolve the whole thing.
// Optimization: `paths` often has just one element.
const path_resolved = switch (paths.len) {
0 => unreachable,
1 => try fs.path.resolve(gpa, &.{ cwd_resolved, paths[0] }),
else => r: {
const all_paths = try gpa.alloc([]const u8, paths.len + 1);
defer gpa.free(all_paths);
all_paths[0] = cwd_resolved;
@memcpy(all_paths[1..], paths);
break :r try fs.path.resolve(gpa, all_paths);
},
};
errdefer gpa.free(path_resolved);
std.debug.assert(fs.path.isAbsolute(path_resolved));
std.debug.assert(fs.path.isAbsolute(cwd_resolved));
if (!std.mem.startsWith(u8, path_resolved, cwd_resolved)) return path_resolved; // not in cwd
if (path_resolved.len == cwd_resolved.len) {
// equal to cwd
gpa.free(path_resolved);
return "";
}
if (path_resolved[cwd_resolved.len] != std.fs.path.sep) return path_resolved; // not in cwd (last component differs)
// in cwd; extract sub path
const sub_path = try gpa.dupe(u8, path_resolved[cwd_resolved.len + 1 ..]);
gpa.free(path_resolved);
return sub_path;
}
/// TODO move this to std.fs.path
pub fn isUpDir(p: []const u8) bool {
return mem.startsWith(u8, p, "..") and (p.len == 2 or p[2] == fs.path.sep);
}
pub const default_local_zig_cache_basename = ".zig-cache";
/// Searches upwards from `cwd` for a directory containing a `build.zig` file.
/// If such a directory is found, returns the path to it joined to the `.zig_cache` name.
/// Otherwise, returns `null`, indicating no suitable local cache location.
pub fn resolveSuitableLocalCacheDir(arena: Allocator, cwd: []const u8) Allocator.Error!?[]u8 {
var cur_dir = cwd;
while (true) {
const joined = try fs.path.join(arena, &.{ cur_dir, Package.build_zig_basename });
if (fs.cwd().access(joined, .{})) |_| {
return try fs.path.join(arena, &.{ cur_dir, default_local_zig_cache_basename });
} else |err| switch (err) {
error.FileNotFound => {
cur_dir = fs.path.dirname(cur_dir) orelse return null;
continue;
},
else => return null,
}
}
}

View file

@ -34,7 +34,7 @@ pub fn needsCrt0(output_mode: std.builtin.OutputMode) ?CrtFile {
fn includePath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 {
return path.join(arena, &.{
comp.zig_lib_directory.path.?,
comp.dirs.zig_lib.path.?,
"libc" ++ path.sep_str ++ "include",
sub_path,
});
@ -42,7 +42,7 @@ fn includePath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]co
fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 {
return path.join(arena, &.{
comp.zig_lib_directory.path.?,
comp.dirs.zig_lib.path.?,
"libc" ++ path.sep_str ++ "freebsd" ++ path.sep_str ++ "lib" ++ path.sep_str ++ "csu",
sub_path,
});
@ -50,7 +50,7 @@ fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const
fn libcPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 {
return path.join(arena, &.{
comp.zig_lib_directory.path.?,
comp.dirs.zig_lib.path.?,
"libc" ++ path.sep_str ++ "freebsd" ++ path.sep_str ++ "lib" ++ path.sep_str ++ "libc",
sub_path,
});
@ -438,11 +438,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
// Use the global cache directory.
var cache: Cache = .{
.gpa = gpa,
.manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}),
.manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}),
};
cache.addPrefix(.{ .path = null, .handle = fs.cwd() });
cache.addPrefix(comp.zig_lib_directory);
cache.addPrefix(comp.global_cache_directory);
cache.addPrefix(comp.dirs.zig_lib);
cache.addPrefix(comp.dirs.global_cache);
defer cache.manifest_dir.close();
var man = cache.obtain();
@ -452,7 +452,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
man.hash.add(target.abi);
man.hash.add(target_version);
const full_abilists_path = try comp.zig_lib_directory.join(arena, &.{abilists_path});
const full_abilists_path = try comp.dirs.zig_lib.join(arena, &.{abilists_path});
const abilists_index = try man.addFile(full_abilists_path, abilists_max_size);
if (try man.hit()) {
@ -461,7 +461,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
return queueSharedObjects(comp, .{
.lock = man.toOwnedLock(),
.dir_path = .{
.root_dir = comp.global_cache_directory,
.root_dir = comp.dirs.global_cache,
.sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest),
},
});
@ -470,9 +470,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
const digest = man.final();
const o_sub_path = try 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 comp.global_cache_directory.join(arena, &.{o_sub_path}),
var o_directory: Cache.Directory = .{
.handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}),
.path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}),
};
defer o_directory.handle.close();
@ -974,7 +974,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "stdthreads", etc.
const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable;
try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items });
try buildSharedLib(comp, arena, comp.global_cache_directory, o_directory, asm_file_basename, lib, prog_node);
try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node);
}
man.writeManifest() catch |err| {
@ -984,7 +984,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
return queueSharedObjects(comp, .{
.lock = man.toOwnedLock(),
.dir_path = .{
.root_dir = comp.global_cache_directory,
.root_dir = comp.dirs.global_cache,
.sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest),
},
});
@ -1023,8 +1023,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
fn buildSharedLib(
comp: *Compilation,
arena: Allocator,
zig_cache_directory: Compilation.Directory,
bin_directory: Compilation.Directory,
bin_directory: Cache.Directory,
asm_file_basename: []const u8,
lib: Lib,
prog_node: std.Progress.Node,
@ -1057,9 +1056,8 @@ fn buildSharedLib(
});
const root_mod = try Module.create(arena, .{
.global_cache_directory = comp.global_cache_directory,
.paths = .{
.root = .{ .root_dir = comp.zig_lib_directory },
.root = .zig_lib_root,
.root_src_path = "",
},
.fully_qualified_name = "root",
@ -1079,8 +1077,6 @@ fn buildSharedLib(
.global = config,
.cc_argv = &.{},
.parent = null,
.builtin_mod = null,
.builtin_modules = null, // there is only one module in this compilation
});
const c_source_files = [1]Compilation.CSourceFile{
@ -1091,9 +1087,7 @@ fn buildSharedLib(
};
const sub_compilation = try Compilation.create(comp.gpa, arena, .{
.local_cache_directory = zig_cache_directory,
.global_cache_directory = comp.global_cache_directory,
.zig_lib_directory = comp.zig_lib_directory,
.dirs = comp.dirs.withoutLocalCache(),
.thread_pool = comp.thread_pool,
.self_exe_path = comp.self_exe_path,
.cache_mode = .incremental,

View file

@ -365,7 +365,7 @@ fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![
const s = path.sep_str;
var result = std.ArrayList(u8).init(arena);
try result.appendSlice(comp.zig_lib_directory.path.?);
try result.appendSlice(comp.dirs.zig_lib.path orelse ".");
try result.appendSlice(s ++ "libc" ++ s ++ "glibc" ++ s ++ "sysdeps" ++ s);
if (is_sparc) {
if (is_64) {
@ -439,7 +439,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([
}
if (opt_nptl) |nptl| {
try args.append("-I");
try args.append(try path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, lib_libc_glibc ++ "sysdeps", nptl }));
try args.append(try path.join(arena, &.{ comp.dirs.zig_lib.path orelse ".", lib_libc_glibc ++ "sysdeps", nptl }));
}
try args.append("-I");
@ -459,11 +459,11 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([
try args.append(try lib_path(comp, arena, lib_libc_glibc ++ "sysdeps" ++ s ++ "generic"));
try args.append("-I");
try args.append(try path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, lib_libc ++ "glibc" }));
try args.append(try path.join(arena, &[_][]const u8{ comp.dirs.zig_lib.path orelse ".", lib_libc ++ "glibc" }));
try args.append("-I");
try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}", .{
comp.zig_lib_directory.path.?, @tagName(target.cpu.arch), @tagName(target.os.tag), @tagName(target.abi),
comp.dirs.zig_lib.path orelse ".", @tagName(target.cpu.arch), @tagName(target.os.tag), @tagName(target.abi),
}));
try args.append("-I");
@ -472,7 +472,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([
const arch_name = std.zig.target.osArchName(target);
try args.append("-I");
try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-linux-any", .{
comp.zig_lib_directory.path.?, arch_name,
comp.dirs.zig_lib.path orelse ".", arch_name,
}));
try args.append("-I");
@ -626,15 +626,11 @@ fn add_include_dirs_arch(
}
}
fn path_from_lib(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 {
return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path });
}
const lib_libc = "libc" ++ path.sep_str;
const lib_libc_glibc = lib_libc ++ "glibc" ++ path.sep_str;
fn lib_path(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 {
return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path });
return path.join(arena, &.{ comp.dirs.zig_lib.path orelse ".", sub_path });
}
pub const BuiltSharedObjects = struct {
@ -678,11 +674,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
// Use the global cache directory.
var cache: Cache = .{
.gpa = gpa,
.manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}),
.manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}),
};
cache.addPrefix(.{ .path = null, .handle = fs.cwd() });
cache.addPrefix(comp.zig_lib_directory);
cache.addPrefix(comp.global_cache_directory);
cache.addPrefix(comp.dirs.zig_lib);
cache.addPrefix(comp.dirs.global_cache);
defer cache.manifest_dir.close();
var man = cache.obtain();
@ -692,7 +688,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
man.hash.add(target.abi);
man.hash.add(target_version);
const full_abilists_path = try comp.zig_lib_directory.join(arena, &.{abilists_path});
const full_abilists_path = try comp.dirs.zig_lib.join(arena, &.{abilists_path});
const abilists_index = try man.addFile(full_abilists_path, abilists_max_size);
if (try man.hit()) {
@ -701,7 +697,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
return queueSharedObjects(comp, .{
.lock = man.toOwnedLock(),
.dir_path = .{
.root_dir = comp.global_cache_directory,
.root_dir = comp.dirs.global_cache,
.sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest),
},
});
@ -710,9 +706,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
const digest = man.final();
const o_sub_path = try 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 comp.global_cache_directory.join(arena, &.{o_sub_path}),
var o_directory: Cache.Directory = .{
.handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}),
.path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}),
};
defer o_directory.handle.close();
@ -1112,7 +1108,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "pthread", etc.
const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable;
try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items });
try buildSharedLib(comp, arena, comp.global_cache_directory, o_directory, asm_file_basename, lib, prog_node);
try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node);
}
man.writeManifest() catch |err| {
@ -1122,7 +1118,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
return queueSharedObjects(comp, .{
.lock = man.toOwnedLock(),
.dir_path = .{
.root_dir = comp.global_cache_directory,
.root_dir = comp.dirs.global_cache,
.sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest),
},
});
@ -1174,8 +1170,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
fn buildSharedLib(
comp: *Compilation,
arena: Allocator,
zig_cache_directory: Compilation.Directory,
bin_directory: Compilation.Directory,
bin_directory: Cache.Directory,
asm_file_basename: []const u8,
lib: Lib,
prog_node: std.Progress.Node,
@ -1208,9 +1203,8 @@ fn buildSharedLib(
});
const root_mod = try Module.create(arena, .{
.global_cache_directory = comp.global_cache_directory,
.paths = .{
.root = .{ .root_dir = comp.zig_lib_directory },
.root = .zig_lib_root,
.root_src_path = "",
},
.fully_qualified_name = "root",
@ -1230,8 +1224,6 @@ fn buildSharedLib(
.global = config,
.cc_argv = &.{},
.parent = null,
.builtin_mod = null,
.builtin_modules = null, // there is only one module in this compilation
});
const c_source_files = [1]Compilation.CSourceFile{
@ -1242,9 +1234,7 @@ fn buildSharedLib(
};
const sub_compilation = try Compilation.create(comp.gpa, arena, .{
.local_cache_directory = zig_cache_directory,
.global_cache_directory = comp.global_cache_directory,
.zig_lib_directory = comp.zig_lib_directory,
.dirs = comp.dirs.withoutLocalCache(),
.thread_pool = comp.thread_pool,
.self_exe_path = comp.self_exe_path,
.cache_mode = .incremental,

View file

@ -134,10 +134,10 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
.basename = basename,
};
const cxxabi_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", "include" });
const cxx_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" });
const cxx_src_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "src" });
const cxx_libc_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "libc" });
const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" });
const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" });
const cxx_src_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "src" });
const cxx_libc_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "libc" });
const optimize_mode = comp.compilerRtOptMode();
const strip = comp.compilerRtStrip();
@ -164,9 +164,8 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
};
const root_mod = Module.create(arena, .{
.global_cache_directory = comp.global_cache_directory,
.paths = .{
.root = .{ .root_dir = comp.zig_lib_directory },
.root = .zig_lib_root,
.root_src_path = "",
},
.fully_qualified_name = "root",
@ -188,8 +187,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
.global = config,
.cc_argv = &.{},
.parent = null,
.builtin_mod = null,
.builtin_modules = null, // there is only one module in this compilation
}) catch |err| {
comp.setMiscFailure(
.libcxx,
@ -258,7 +255,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
try cache_exempt_flags.append(cxx_libc_include_path);
c_source_files.appendAssumeCapacity(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", cxx_src }),
.src_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", cxx_src }),
.extra_flags = cflags.items,
.cache_exempt_flags = cache_exempt_flags.items,
.owner = root_mod,
@ -266,9 +263,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
}
const sub_compilation = Compilation.create(comp.gpa, arena, .{
.local_cache_directory = comp.global_cache_directory,
.global_cache_directory = comp.global_cache_directory,
.zig_lib_directory = comp.zig_lib_directory,
.dirs = comp.dirs.withoutLocalCache(),
.self_exe_path = comp.self_exe_path,
.cache_mode = .whole,
.config = config,
@ -344,9 +339,9 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
.basename = basename,
};
const cxxabi_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", "include" });
const cxx_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" });
const cxx_src_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "src" });
const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" });
const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" });
const cxx_src_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "src" });
const optimize_mode = comp.compilerRtOptMode();
const strip = comp.compilerRtStrip();
@ -378,9 +373,8 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
};
const root_mod = Module.create(arena, .{
.global_cache_directory = comp.global_cache_directory,
.paths = .{
.root = .{ .root_dir = comp.zig_lib_directory },
.root = .zig_lib_root,
.root_src_path = "",
},
.fully_qualified_name = "root",
@ -403,8 +397,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
.global = config,
.cc_argv = &.{},
.parent = null,
.builtin_mod = null,
.builtin_modules = null, // there is only one module in this compilation
}) catch |err| {
comp.setMiscFailure(
.libcxxabi,
@ -459,7 +451,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
try cache_exempt_flags.append(cxx_src_include_path);
c_source_files.appendAssumeCapacity(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", cxxabi_src }),
.src_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", cxxabi_src }),
.extra_flags = cflags.items,
.cache_exempt_flags = cache_exempt_flags.items,
.owner = root_mod,
@ -467,9 +459,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
}
const sub_compilation = Compilation.create(comp.gpa, arena, .{
.local_cache_directory = comp.global_cache_directory,
.global_cache_directory = comp.global_cache_directory,
.zig_lib_directory = comp.zig_lib_directory,
.dirs = comp.dirs.withoutLocalCache(),
.self_exe_path = comp.self_exe_path,
.cache_mode = .whole,
.config = config,

View file

@ -84,9 +84,8 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
};
const root_mod = Module.create(arena, .{
.global_cache_directory = comp.global_cache_directory,
.paths = .{
.root = .{ .root_dir = comp.zig_lib_directory },
.root = .zig_lib_root,
.root_src_path = "",
},
.fully_qualified_name = "root",
@ -110,8 +109,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
.global = config,
.cc_argv = &common_flags,
.parent = null,
.builtin_mod = null,
.builtin_modules = null, // there is only one module in this compilation
}) catch |err| {
comp.setMiscFailure(
.libtsan,
@ -124,7 +121,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena);
try c_source_files.ensureUnusedCapacity(tsan_sources.len);
const tsan_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"libtsan"});
const tsan_include_path = try comp.dirs.zig_lib.join(arena, &.{"libtsan"});
for (tsan_sources) |tsan_src| {
var cflags = std.ArrayList([]const u8).init(arena);
@ -134,7 +131,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
try addCcArgs(target, &cflags);
c_source_files.appendAssumeCapacity(.{
.src_path = try comp.zig_lib_directory.join(arena, &.{ "libtsan", tsan_src }),
.src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", tsan_src }),
.extra_flags = cflags.items,
.owner = root_mod,
});
@ -155,7 +152,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
try addCcArgs(target, &cflags);
c_source_files.appendAssumeCapacity(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libtsan", tsan_src }),
.src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", tsan_src }),
.extra_flags = cflags.items,
.owner = root_mod,
});
@ -179,14 +176,14 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
try cflags.append("-DNDEBUG");
c_source_files.appendAssumeCapacity(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libtsan", asm_source }),
.src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", asm_source }),
.extra_flags = cflags.items,
.owner = root_mod,
});
}
try c_source_files.ensureUnusedCapacity(sanitizer_common_sources.len);
const sanitizer_common_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
const sanitizer_common_include_path = try comp.dirs.zig_lib.join(arena, &.{
"libtsan", "sanitizer_common",
});
for (sanitizer_common_sources) |common_src| {
@ -200,7 +197,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
try addCcArgs(target, &cflags);
c_source_files.appendAssumeCapacity(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libtsan", "sanitizer_common", common_src,
}),
.extra_flags = cflags.items,
@ -224,7 +221,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
try addCcArgs(target, &cflags);
c_source_files.appendAssumeCapacity(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libtsan", "sanitizer_common", c_src,
}),
.extra_flags = cflags.items,
@ -242,7 +239,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
try addCcArgs(target, &cflags);
c_source_files.appendAssumeCapacity(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libtsan", "sanitizer_common", c_src,
}),
.extra_flags = cflags.items,
@ -250,10 +247,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
});
}
const interception_include_path = try comp.zig_lib_directory.join(
arena,
&[_][]const u8{"interception"},
);
const interception_include_path = try comp.dirs.zig_lib.join(arena, &.{"interception"});
try c_source_files.ensureUnusedCapacity(interception_sources.len);
for (interception_sources) |c_src| {
@ -268,7 +262,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
try addCcArgs(target, &cflags);
c_source_files.appendAssumeCapacity(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libtsan", "interception", c_src,
}),
.extra_flags = cflags.items,
@ -285,9 +279,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
// Workaround for https://github.com/llvm/llvm-project/issues/97627
const headerpad_size: ?u32 = if (target.os.tag.isDarwin()) 32 else null;
const sub_compilation = Compilation.create(comp.gpa, arena, .{
.local_cache_directory = comp.global_cache_directory,
.global_cache_directory = comp.global_cache_directory,
.zig_lib_directory = comp.zig_lib_directory,
.dirs = comp.dirs.withoutLocalCache(),
.thread_pool = comp.thread_pool,
.self_exe_path = comp.self_exe_path,
.cache_mode = .whole,

View file

@ -50,9 +50,8 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
return error.SubCompilationFailed;
};
const root_mod = Module.create(arena, .{
.global_cache_directory = comp.global_cache_directory,
.paths = .{
.root = .{ .root_dir = comp.zig_lib_directory },
.root = .zig_lib_root,
.root_src_path = "",
},
.fully_qualified_name = "root",
@ -76,8 +75,6 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
.global = config,
.cc_argv = &.{},
.parent = null,
.builtin_mod = null,
.builtin_modules = null, // there is only one module in this compilation
}) catch |err| {
comp.setMiscFailure(
.libunwind,
@ -118,7 +115,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
else => unreachable, // See `unwind_src_list`.
}
try cflags.append("-I");
try cflags.append(try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libunwind", "include" }));
try cflags.append(try comp.dirs.zig_lib.join(arena, &.{ "libunwind", "include" }));
try cflags.append("-D_LIBUNWIND_HIDE_SYMBOLS");
try cflags.append("-Wa,--noexecstack");
try cflags.append("-fvisibility=hidden");
@ -148,16 +145,14 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
}
c_source_files[i] = .{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{unwind_src}),
.src_path = try comp.dirs.zig_lib.join(arena, &.{unwind_src}),
.extra_flags = cflags.items,
.owner = root_mod,
};
}
const sub_compilation = Compilation.create(comp.gpa, arena, .{
.dirs = comp.dirs.withoutLocalCache(),
.self_exe_path = comp.self_exe_path,
.local_cache_directory = comp.global_cache_directory,
.global_cache_directory = comp.global_cache_directory,
.zig_lib_directory = comp.zig_lib_directory,
.config = config,
.root_mod = root_mod,
.cache_mode = .whole,

View file

@ -40,7 +40,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
}
var files = [_]Compilation.CSourceFile{
.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "mingw", "crt", "crtexe.c",
}),
.extra_flags = args.items,
@ -57,7 +57,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
try addCrtCcArgs(comp, arena, &args);
var files = [_]Compilation.CSourceFile{
.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "mingw", "crt", "crtdll.c",
}),
.extra_flags = args.items,
@ -78,7 +78,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
for (mingw32_generic_src) |dep| {
try c_source_files.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "mingw", dep,
}),
.extra_flags = crt_args.items,
@ -88,7 +88,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
if (target.cpu.arch.isX86()) {
for (mingw32_x86_src) |dep| {
try c_source_files.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "mingw", dep,
}),
.extra_flags = crt_args.items,
@ -98,7 +98,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
if (target.cpu.arch == .x86) {
for (mingw32_x86_32_src) |dep| {
try c_source_files.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "mingw", dep,
}),
.extra_flags = crt_args.items,
@ -109,7 +109,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
} else if (target.cpu.arch == .thumb) {
for (mingw32_arm_src) |dep| {
try c_source_files.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "mingw", dep,
}),
.extra_flags = crt_args.items,
@ -118,7 +118,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
}
for (mingw32_arm32_src) |dep| {
try c_source_files.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "mingw", dep,
}),
.extra_flags = crt_args.items,
@ -128,7 +128,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
} else if (target.cpu.arch == .aarch64) {
for (mingw32_arm_src) |dep| {
try c_source_files.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "mingw", dep,
}),
.extra_flags = crt_args.items,
@ -137,7 +137,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
}
for (mingw32_arm64_src) |dep| {
try c_source_files.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "mingw", dep,
}),
.extra_flags = crt_args.items,
@ -164,7 +164,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
for (mingw32_winpthreads_src) |dep| {
try c_source_files.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "mingw", dep,
}),
.extra_flags = winpthreads_args.items,
@ -192,7 +192,7 @@ fn addCcArgs(
"-D__USE_MINGW_ANSI_STDIO=0",
"-isystem",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "any-windows-any" }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "any-windows-any" }),
});
}
@ -219,7 +219,7 @@ fn addCrtCcArgs(
"-DHAVE_CONFIG_H",
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "include" }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "include" }),
});
}
@ -232,7 +232,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
const def_file_path = findDef(arena, comp.getTarget(), comp.zig_lib_directory, lib_name) catch |err| switch (err) {
const def_file_path = findDef(arena, comp.getTarget(), comp.dirs.zig_lib, lib_name) catch |err| switch (err) {
error.FileNotFound => {
log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name });
// In this case we will end up putting foo.lib onto the linker line and letting the linker
@ -247,15 +247,15 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
// Use the global cache directory.
var cache: Cache = .{
.gpa = gpa,
.manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}),
.manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}),
};
cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() });
cache.addPrefix(comp.zig_lib_directory);
cache.addPrefix(comp.global_cache_directory);
cache.addPrefix(comp.dirs.zig_lib);
cache.addPrefix(comp.dirs.global_cache);
defer cache.manifest_dir.close();
cache.hash.addBytes(build_options.version);
cache.hash.addOptionalBytes(comp.zig_lib_directory.path);
cache.hash.addOptionalBytes(comp.dirs.zig_lib.path);
cache.hash.add(target.cpu.arch);
var man = cache.obtain();
@ -276,7 +276,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
try comp.crt_files.ensureUnusedCapacity(gpa, 1);
comp.crt_files.putAssumeCapacityNoClobber(final_lib_basename, .{
.full_object_path = .{
.root_dir = comp.global_cache_directory,
.root_dir = comp.dirs.global_cache,
.sub_path = sub_path,
},
.lock = man.toOwnedLock(),
@ -286,11 +286,11 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
const digest = man.final();
const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
var o_dir = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{});
var o_dir = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{});
defer o_dir.close();
const final_def_basename = try std.fmt.allocPrint(arena, "{s}.def", .{lib_name});
const def_final_path = try comp.global_cache_directory.join(arena, &[_][]const u8{
const def_final_path = try comp.dirs.global_cache.join(arena, &[_][]const u8{
"o", &digest, final_def_basename,
});
@ -306,7 +306,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
var aro_comp = aro.Compilation.init(gpa, std.fs.cwd());
defer aro_comp.deinit();
const include_dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "def-include" });
const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" });
if (comp.verbose_cc) print: {
std.debug.lockStdErr();
@ -350,7 +350,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions;
const llvm_bindings = @import("../codegen/llvm/bindings.zig");
const def_final_path_z = try arena.dupeZ(u8, def_final_path);
const lib_final_path_z = try comp.global_cache_directory.joinZ(arena, &.{lib_final_path});
const lib_final_path_z = try comp.dirs.global_cache.joinZ(arena, &.{lib_final_path});
if (llvm_bindings.WriteImportLibrary(
def_final_path_z.ptr,
@intFromEnum(target.toCoffMachine()),
@ -370,7 +370,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
defer comp.mutex.unlock();
try comp.crt_files.putNoClobber(gpa, final_lib_basename, .{
.full_object_path = .{
.root_dir = comp.global_cache_directory,
.root_dir = comp.dirs.global_cache,
.sub_path = lib_final_path,
},
.lock = man.toOwnedLock(),

View file

@ -34,7 +34,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
try args.append("-DCRT");
var files = [_]Compilation.CSourceFile{
.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "musl", "crt", "crt1.c",
}),
.extra_flags = args.items,
@ -54,7 +54,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
try args.append("-DCRT");
var files = [_]Compilation.CSourceFile{
.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "musl", "crt", "rcrt1.c",
}),
.extra_flags = args.items,
@ -75,7 +75,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
try args.append("-DCRT");
var files = [_]Compilation.CSourceFile{
.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", "musl", "crt", "Scrt1.c",
}),
.extra_flags = args.items,
@ -165,7 +165,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
try addCcArgs(comp, arena, &args, ext == .o3);
const c_source_file = try c_source_files.addOne();
c_source_file.* = .{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", src_file }),
.src_path = try comp.dirs.zig_lib.join(arena, &.{ "libc", src_file }),
.extra_flags = args.items,
.owner = undefined,
};
@ -220,9 +220,8 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
&.{ arch_define, family_define };
const root_mod = try Module.create(arena, .{
.global_cache_directory = comp.global_cache_directory,
.paths = .{
.root = .{ .root_dir = comp.zig_lib_directory },
.root = .zig_lib_root,
.root_src_path = "",
},
.fully_qualified_name = "root",
@ -242,14 +241,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
.global = config,
.cc_argv = cc_argv,
.parent = null,
.builtin_mod = null,
.builtin_modules = null, // there is only one module in this compilation
});
const sub_compilation = try Compilation.create(comp.gpa, arena, .{
.local_cache_directory = comp.global_cache_directory,
.global_cache_directory = comp.global_cache_directory,
.zig_lib_directory = comp.zig_lib_directory,
.dirs = comp.dirs.withoutLocalCache(),
.self_exe_path = comp.self_exe_path,
.cache_mode = .whole,
.config = config,
@ -266,9 +261,9 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
.verbose_cimport = comp.verbose_cimport,
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,
.c_source_files = &[_]Compilation.CSourceFile{
.c_source_files = &.{
.{
.src_path = try comp.zig_lib_directory.join(arena, &.{ "libc", "musl", "libc.S" }),
.src_path = try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "libc.S" }),
.owner = root_mod,
},
},
@ -411,25 +406,25 @@ fn addCcArgs(
"-D_XOPEN_SOURCE=700",
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "arch", arch_name }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "arch", arch_name }),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "arch", "generic" }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "arch", "generic" }),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "src", "include" }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "src", "include" }),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "src", "internal" }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "src", "internal" }),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "include" }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "include" }),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", triple }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", triple }),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "generic-musl" }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "generic-musl" }),
o_arg,
@ -444,7 +439,7 @@ fn addCcArgs(
fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 {
const target = comp.getTarget();
return comp.zig_lib_directory.join(arena, &[_][]const u8{
return comp.dirs.zig_lib.join(arena, &.{
"libc", "musl", "crt", std.zig.target.muslArchName(target.cpu.arch, target.abi), basename,
});
}

View file

@ -81,7 +81,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
try addLibcBottomHalfIncludes(comp, arena, &args);
var files = [_]Compilation.CSourceFile{
.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, crt1_reactor_src_file),
}),
.extra_flags = args.items,
@ -96,7 +96,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
try addLibcBottomHalfIncludes(comp, arena, &args);
var files = [_]Compilation.CSourceFile{
.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, crt1_command_src_file),
}),
.extra_flags = args.items,
@ -114,7 +114,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
try addCCArgs(comp, arena, &args, .{ .want_O3 = true, .no_strict_aliasing = true });
for (emmalloc_src_files) |file_path| {
try libc_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
@ -131,7 +131,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
for (libc_bottom_half_src_files) |file_path| {
try libc_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
@ -148,7 +148,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
for (libc_top_half_src_files) |file_path| {
try libc_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
@ -168,7 +168,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
var emu_dl_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
for (emulated_dl_src_files) |file_path| {
try emu_dl_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
@ -186,7 +186,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
var emu_clocks_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
for (emulated_process_clocks_src_files) |file_path| {
try emu_clocks_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
@ -203,7 +203,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
var emu_getpid_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
for (emulated_getpid_src_files) |file_path| {
try emu_getpid_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
@ -220,7 +220,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
var emu_mman_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
for (emulated_mman_src_files) |file_path| {
try emu_mman_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
@ -238,7 +238,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
for (emulated_signal_bottom_half_src_files) |file_path| {
try emu_signal_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
@ -255,7 +255,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
for (emulated_signal_top_half_src_files) |file_path| {
try emu_signal_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
.src_path = try comp.dirs.zig_lib.join(arena, &.{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
@ -316,10 +316,10 @@ fn addCCArgs(
"/",
"-iwithsysroot",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", triple }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", triple }),
"-iwithsysroot",
try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "generic-musl" }),
try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "generic-musl" }),
"-DBULK_MEMORY_THRESHOLD=32",
});
@ -336,7 +336,7 @@ fn addLibcBottomHalfIncludes(
) error{OutOfMemory}!void {
try args.appendSlice(&[_][]const u8{
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"wasi",
"libc-bottom-half",
@ -345,7 +345,7 @@ fn addLibcBottomHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"wasi",
"libc-bottom-half",
@ -355,7 +355,7 @@ fn addLibcBottomHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"wasi",
"libc-bottom-half",
@ -364,7 +364,7 @@ fn addLibcBottomHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"wasi",
"libc-top-half",
@ -374,7 +374,7 @@ fn addLibcBottomHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"musl",
"src",
@ -382,7 +382,7 @@ fn addLibcBottomHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"wasi",
"libc-top-half",
@ -392,7 +392,7 @@ fn addLibcBottomHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"musl",
"src",
@ -408,7 +408,7 @@ fn addLibcTopHalfIncludes(
) error{OutOfMemory}!void {
try args.appendSlice(&[_][]const u8{
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"wasi",
"libc-top-half",
@ -418,7 +418,7 @@ fn addLibcTopHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"musl",
"src",
@ -426,7 +426,7 @@ fn addLibcTopHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"wasi",
"libc-top-half",
@ -436,7 +436,7 @@ fn addLibcTopHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"musl",
"src",
@ -444,7 +444,7 @@ fn addLibcTopHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"wasi",
"libc-top-half",
@ -454,7 +454,7 @@ fn addLibcTopHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"musl",
"arch",
@ -462,7 +462,7 @@ fn addLibcTopHalfIncludes(
}),
"-I",
try comp.zig_lib_directory.join(arena, &[_][]const u8{
try comp.dirs.zig_lib.join(arena, &.{
"libc",
"wasi",
"libc-top-half",

View file

@ -1675,8 +1675,8 @@ pub fn spawnLld(
const rand_int = std.crypto.random.int(u64);
const rsp_path = "tmp" ++ s ++ std.fmt.hex(rand_int) ++ ".rsp";
const rsp_file = try comp.local_cache_directory.handle.createFileZ(rsp_path, .{});
defer comp.local_cache_directory.handle.deleteFileZ(rsp_path) catch |err|
const rsp_file = try comp.dirs.local_cache.handle.createFileZ(rsp_path, .{});
defer comp.dirs.local_cache.handle.deleteFileZ(rsp_path) catch |err|
log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) });
{
defer rsp_file.close();
@ -1700,7 +1700,7 @@ pub fn spawnLld(
var rsp_child = std.process.Child.init(&.{ argv[0], argv[1], try std.fmt.allocPrint(
arena,
"@{s}",
.{try comp.local_cache_directory.join(arena, &.{rsp_path})},
.{try comp.dirs.local_cache.join(arena, &.{rsp_path})},
) }, arena);
if (comp.clang_passthrough_mode) {
rsp_child.stdin_behavior = .Inherit;

View file

@ -206,7 +206,7 @@ pub fn updateFunc(
.dg = .{
.gpa = gpa,
.pt = pt,
.mod = zcu.navFileScope(func.owner_nav).mod,
.mod = zcu.navFileScope(func.owner_nav).mod.?,
.error_msg = null,
.pass = .{ .nav = func.owner_nav },
.is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked,
@ -337,7 +337,7 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l
.dg = .{
.gpa = gpa,
.pt = pt,
.mod = zcu.navFileScope(nav_index).mod,
.mod = zcu.navFileScope(nav_index).mod.?,
.error_msg = null,
.pass = .{ .nav = nav_index },
.is_naked_fn = false,
@ -490,7 +490,7 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
for (self.navs.keys(), self.navs.values()) |nav, *av_block| try self.flushAvBlock(
pt,
zcu.navFileScope(nav).mod,
zcu.navFileScope(nav).mod.?,
&f,
av_block,
self.exported_navs.getPtr(nav),
@ -846,7 +846,7 @@ pub fn updateExports(
const gpa = zcu.gpa;
const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) {
.nav => |nav| .{
zcu.navFileScope(nav).mod,
zcu.navFileScope(nav).mod.?,
.{ .nav = nav },
self.navs.getPtr(nav).?,
(try self.exported_navs.getOrPut(gpa, nav)).value_ptr,

View file

@ -1392,7 +1392,7 @@ fn updateNavCode(
log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result;
const required_alignment = switch (pt.navAlignment(nav_index)) {
.none => target_util.defaultFunctionAlignment(target),
else => |a| a.maxStrict(target_util.minFunctionAlignment(target)),

View file

@ -34,9 +34,7 @@ pub const UpdateError = error{
std.fs.File.PReadError ||
std.fs.File.PWriteError;
pub const FlushError =
UpdateError ||
std.process.GetCwdError;
pub const FlushError = UpdateError;
pub const RelocError =
std.fs.File.PWriteError;
@ -967,7 +965,7 @@ const Entry = struct {
const ip = &zcu.intern_pool;
for (dwarf.types.keys(), dwarf.types.values()) |ty, other_entry| {
const ty_unit: Unit.Index = if (Type.fromInterned(ty).typeDeclInst(zcu)) |inst_index|
dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod) catch unreachable
dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?) catch unreachable
else
.main;
if (sec.getUnit(ty_unit) == unit and unit.getEntry(other_entry) == entry)
@ -977,7 +975,7 @@ const Entry = struct {
});
}
for (dwarf.navs.keys(), dwarf.navs.values()) |nav, other_entry| {
const nav_unit = dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav).srcInst(ip).resolveFile(ip)).mod) catch unreachable;
const nav_unit = dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav).srcInst(ip).resolveFile(ip)).mod.?) catch unreachable;
if (sec.getUnit(nav_unit) == unit and unit.getEntry(other_entry) == entry)
log.err("missing Nav({}({d}))", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) });
}
@ -1620,7 +1618,7 @@ pub const WipNav = struct {
const new_func_info = zcu.funcInfo(func);
const new_file = zcu.navFileScopeIndex(new_func_info.owner_nav);
const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod);
const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod.?);
const dlw = wip_nav.debug_line.writer(dwarf.gpa);
if (dwarf.incremental()) {
@ -1810,7 +1808,7 @@ pub const WipNav = struct {
fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } {
const zcu = wip_nav.pt.zcu;
const ip = &zcu.intern_pool;
const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod);
const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod.?);
const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index);
if (gop.found_existing) return .{ unit, gop.value_ptr.* };
const entry = try wip_nav.dwarf.addCommonEntry(unit);
@ -1828,7 +1826,7 @@ pub const WipNav = struct {
const ip = &zcu.intern_pool;
const maybe_inst_index = ty.typeDeclInst(zcu);
const unit = if (maybe_inst_index) |inst_index|
try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod)
try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?)
else
.main;
const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern());
@ -2386,7 +2384,7 @@ fn initWipNavInner(
else => {},
}
const unit = try dwarf.getUnit(file.mod);
const unit = try dwarf.getUnit(file.mod.?);
const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop();
if (nav_gop.found_existing) {
@ -2514,7 +2512,7 @@ fn initWipNavInner(
try wip_nav.infoAddrSym(sym_index, 0);
wip_nav.func_high_pc = @intCast(wip_nav.debug_info.items.len);
try diw.writeInt(u32, 0, dwarf.endian);
const target = file.mod.resolved_target.result;
const target = file.mod.?.resolved_target.result;
try uleb128(diw, switch (nav.status.fully_resolved.alignment) {
.none => target_info.defaultFunctionAlignment(target),
else => |a| a.maxStrict(target_info.minFunctionAlignment(target)),
@ -2726,7 +2724,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
var wip_nav: WipNav = .{
.dwarf = dwarf,
.pt = pt,
.unit = try dwarf.getUnit(file.mod),
.unit = try dwarf.getUnit(file.mod.?),
.entry = undefined,
.any_children = false,
.func = .none,
@ -4044,7 +4042,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?;
const file = zcu.fileByIndex(inst_info.file);
const unit = try dwarf.getUnit(file.mod);
const unit = try dwarf.getUnit(file.mod.?);
const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
if (inst_info.inst == .main_struct_inst) {
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index);
@ -4348,7 +4346,7 @@ pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedI
var line_buf: [4]u8 = undefined;
std.mem.writeInt(u32, &line_buf, decl.src_line + 1, dwarf.endian);
const unit = dwarf.debug_info.section.getUnit(dwarf.getUnitIfExists(file.mod) orelse return);
const unit = dwarf.debug_info.section.getUnit(dwarf.getUnitIfExists(file.mod.?) orelse return);
const entry = unit.getEntry(dwarf.decls.get(zir_index) orelse return);
try dwarf.getFile().?.pwriteAll(&line_buf, dwarf.debug_info.section.off(dwarf) + unit.off + unit.header_len + entry.off + DebugInfo.declEntryLineOff(dwarf));
}
@ -4418,18 +4416,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
try wip_nav.updateLazy(.unneeded);
}
{
const cwd = try std.process.getCwdAlloc(dwarf.gpa);
defer dwarf.gpa.free(cwd);
for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| {
const root_dir_path = try std.fs.path.resolve(dwarf.gpa, &.{
cwd,
mod.root.root_dir.path orelse "",
mod.root.sub_path,
});
defer dwarf.gpa.free(root_dir_path);
mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path);
}
for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| {
const root_dir_path = try mod.root.toAbsolute(zcu.comp.dirs, dwarf.gpa);
defer dwarf.gpa.free(root_dir_path);
mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path);
}
var header = std.ArrayList(u8).init(dwarf.gpa);
@ -4687,7 +4677,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
dwarf.writeInt(
header.addManyAsSliceAssumeCapacity(dir_index_info.bytes),
mod_info.dirs.getIndex(dwarf.getUnitIfExists(file.mod).?).?,
mod_info.dirs.getIndex(dwarf.getUnitIfExists(file.mod.?).?) orelse 0,
);
unit.cross_section_relocs.appendAssumeCapacity(.{
.source_off = @intCast(header.items.len),
@ -4695,7 +4685,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
.target_unit = StringSection.unit,
.target_entry = (try dwarf.debug_line_str.addString(
dwarf,
if (file.mod.builtin_file == file) file.source.? else "",
if (file.is_builtin) file.source.? else "",
)).toOptional(),
});
header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());

View file

@ -1201,7 +1201,7 @@ fn getNavShdrIndex(
return osec;
}
if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) {
.Debug, .ReleaseSafe => {
if (self.data_index) |symbol_index|
return self.symbol(symbol_index).outputShndx(elf_file).?;
@ -1271,7 +1271,7 @@ fn updateNavCode(
log.debug("updateNavCode {}({d})", .{ nav.fqn.fmt(ip), nav_index });
const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result;
const required_alignment = switch (pt.navAlignment(nav_index)) {
.none => target_util.defaultFunctionAlignment(target),
else => |a| a.maxStrict(target_util.minFunctionAlignment(target)),

View file

@ -867,11 +867,11 @@ pub fn resolveLibSystem(
success: {
if (self.sdk_layout) |sdk_layout| switch (sdk_layout) {
.sdk => {
const dir = try fs.path.join(arena, &[_][]const u8{ comp.sysroot.?, "usr", "lib" });
const dir = try fs.path.join(arena, &.{ comp.sysroot.?, "usr", "lib" });
if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success;
},
.vendored => {
const dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "darwin" });
const dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "darwin" });
if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success;
},
};
@ -4406,7 +4406,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi
const sdk_dir = switch (sdk_layout) {
.sdk => comp.sysroot.?,
.vendored => fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,
.vendored => fs.path.join(arena, &.{ comp.dirs.zig_lib.path.?, "libc", "darwin" }) catch return null,
};
if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {
return parseSdkVersion(ver);

View file

@ -954,7 +954,7 @@ fn updateNavCode(
log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result;
const required_alignment = switch (pt.navAlignment(nav_index)) {
.none => target_util.defaultFunctionAlignment(target),
else => |a| a.maxStrict(target_util.minFunctionAlignment(target)),
@ -1184,7 +1184,7 @@ fn getNavOutputSection(
}
if (is_const) return macho_file.zig_const_sect_index.?;
if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) {
.Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?,
.ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?,
};

View file

@ -315,8 +315,9 @@ pub fn createEmpty(
}
fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void {
const gpa = self.base.comp.gpa;
const zcu = self.base.comp.zcu.?;
const comp = self.base.comp;
const gpa = comp.gpa;
const zcu = comp.zcu.?;
const file_scope = zcu.navFileScopeIndex(nav_index);
const fn_map_res = try self.fn_nav_table.getOrPut(gpa, file_scope);
if (fn_map_res.found_existing) {
@ -345,14 +346,11 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void
try a.writer().writeInt(u16, 1, .big);
// getting the full file path
// TODO don't call getcwd here, that is inappropriate
var buf: [std.fs.max_path_bytes]u8 = undefined;
const full_path = try std.fs.path.join(arena, &.{
file.mod.root.root_dir.path orelse try std.posix.getcwd(&buf),
file.mod.root.sub_path,
file.sub_file_path,
});
try self.addPathComponents(full_path, &a);
{
const full_path = try file.path.toAbsolute(comp.dirs, gpa);
defer gpa.free(full_path);
try self.addPathComponents(full_path, &a);
}
// null terminate
try a.append(0);
@ -437,9 +435,7 @@ pub fn updateFunc(
.start_line = dbg_info_output.start_line.?,
.end_line = dbg_info_output.end_line,
};
// The awkward error handling here is due to putFn calling `std.posix.getcwd` which it should not do.
self.putFn(func.owner_nav, out) catch |err|
return zcu.codegenFail(func.owner_nav, "failed to put fn: {s}", .{@errorName(err)});
try self.putFn(func.owner_nav, out);
return self.updateFinish(pt, func.owner_nav);
}

File diff suppressed because it is too large Load diff

View file

@ -2,13 +2,14 @@ const std = @import("std");
const build_options = @import("build_options");
const introspect = @import("introspect.zig");
const Allocator = std.mem.Allocator;
const fatal = @import("main.zig").fatal;
const fatal = std.process.fatal;
pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Writer) !void {
_ = args;
const self_exe_path = try introspect.findZigExePath(arena);
const cwd_path = try introspect.getResolvedCwd(arena);
const self_exe_path = try std.fs.selfExePathAlloc(arena);
var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| {
var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, cwd_path, self_exe_path) catch |err| {
fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)});
};
defer zig_lib_directory.handle.close();

View file

@ -3,13 +3,13 @@ const fs = std.fs;
const io = std.io;
const mem = std.mem;
const meta = std.meta;
const fatal = std.process.fatal;
const Allocator = std.mem.Allocator;
const Target = std.Target;
const target = @import("target.zig");
const assert = std.debug.assert;
const glibc = @import("libs/glibc.zig");
const introspect = @import("introspect.zig");
const fatal = @import("main.zig").fatal;
pub fn cmdTargets(
allocator: Allocator,

View file

@ -12,7 +12,8 @@ const LazySrcLoc = Zcu.LazySrcLoc;
/// Write human-readable, debug formatted ZIR code to a file.
pub fn renderAsTextToFile(
gpa: Allocator,
scope_file: *Zcu.File,
tree: ?Ast,
zir: Zir,
fs_file: std.fs.File,
) !void {
var arena = std.heap.ArenaAllocator.init(gpa);
@ -21,8 +22,8 @@ pub fn renderAsTextToFile(
var writer: Writer = .{
.gpa = gpa,
.arena = arena.allocator(),
.file = scope_file,
.code = scope_file.zir.?,
.tree = tree,
.code = zir,
.indent = 0,
.parent_decl_node = .root,
.recurse_decls = true,
@ -36,18 +37,18 @@ pub fn renderAsTextToFile(
try stream.print("%{d} ", .{@intFromEnum(main_struct_inst)});
try writer.writeInstToStream(stream, main_struct_inst);
try stream.writeAll("\n");
const imports_index = scope_file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)];
const imports_index = zir.extra[@intFromEnum(Zir.ExtraIndex.imports)];
if (imports_index != 0) {
try stream.writeAll("Imports:\n");
const extra = scope_file.zir.?.extraData(Zir.Inst.Imports, imports_index);
const extra = zir.extraData(Zir.Inst.Imports, imports_index);
var extra_index = extra.end;
for (0..extra.data.imports_len) |_| {
const item = scope_file.zir.?.extraData(Zir.Inst.Imports.Item, extra_index);
const item = zir.extraData(Zir.Inst.Imports.Item, extra_index);
extra_index = item.end;
const import_path = scope_file.zir.?.nullTerminatedString(item.data.name);
const import_path = zir.nullTerminatedString(item.data.name);
try stream.print(" @import(\"{}\") ", .{
std.zig.fmtEscapes(import_path),
});
@ -74,7 +75,7 @@ pub fn renderInstructionContext(
var writer: Writer = .{
.gpa = gpa,
.arena = arena.allocator(),
.file = scope_file,
.tree = scope_file.tree,
.code = scope_file.zir.?,
.indent = if (indent < 2) 2 else indent,
.parent_decl_node = parent_decl_node,
@ -106,7 +107,7 @@ pub fn renderSingleInstruction(
var writer: Writer = .{
.gpa = gpa,
.arena = arena.allocator(),
.file = scope_file,
.tree = scope_file.tree,
.code = scope_file.zir.?,
.indent = indent,
.parent_decl_node = parent_decl_node,
@ -121,7 +122,7 @@ pub fn renderSingleInstruction(
const Writer = struct {
gpa: Allocator,
arena: Allocator,
file: *Zcu.File,
tree: ?Ast,
code: Zir,
indent: u32,
parent_decl_node: Ast.Node.Index,
@ -2761,7 +2762,7 @@ const Writer = struct {
}
fn writeSrcNode(self: *Writer, stream: anytype, src_node: Ast.Node.Offset) !void {
const tree = self.file.tree orelse return;
const tree = self.tree orelse return;
const abs_node = src_node.toAbsolute(self.parent_decl_node);
const src_span = tree.nodeToSpan(abs_node);
const start = self.line_col_cursor.find(tree.source, src_span.start);
@ -2773,7 +2774,7 @@ const Writer = struct {
}
fn writeSrcTok(self: *Writer, stream: anytype, src_tok: Ast.TokenOffset) !void {
const tree = self.file.tree orelse return;
const tree = self.tree orelse return;
const abs_tok = src_tok.toAbsolute(tree.firstToken(self.parent_decl_node));
const span_start = tree.tokenStart(abs_tok);
const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(abs_tok).len));
@ -2786,7 +2787,7 @@ const Writer = struct {
}
fn writeSrcTokAbs(self: *Writer, stream: anytype, src_tok: Ast.TokenIndex) !void {
const tree = self.file.tree orelse return;
const tree = self.tree orelse return;
const span_start = tree.tokenStart(src_tok);
const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len));
const start = self.line_col_cursor.find(tree.source, span_start);

View file

@ -3,7 +3,6 @@ const bogus = @import(
);
// error
// backend=stage2
// target=native
//
// bogus-does-not-exist.zig': FileNotFound
// bogus-does-not-exist.zig:1:1: error: unable to load 'bogus-does-not-exist.zig': FileNotFound
// :2:5: note: file imported here

View file

@ -0,0 +1,8 @@
const foo = @import("foo");
comptime {
_ = foo;
}
// error
//
// :1:21: error: no module named 'foo' available within module 'root'

View file

@ -1,10 +0,0 @@
const foo = @import("foo");
comptime {
_ = foo;
}
// error
// backend=stage2
// target=native
//
// :1:21: error: no module named 'foo' available within module root

View file

@ -0,0 +1,7 @@
comptime {
_ = @import("../a.zig");
}
// error
//
// :2:17: error: import of file outside module path

View file

@ -1,8 +0,0 @@
export fn a() usize {
return @import("../../above.zig").len;
}
// error
// target=native
//
// :2:20: error: import of file outside module path: '../../above.zig'

View file

@ -1,9 +0,0 @@
comptime {
_ = @import("../a.zig");
}
// error
// backend=stage2
// target=native
//
// :2:17: error: import of file outside module path: '../a.zig'

View file

@ -126,9 +126,10 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void {
\\ _ = @import("foo.zig");
\\}
, &[_][]const u8{
":1:1: error: file exists in multiple modules",
":1:1: note: root of module foo",
":3:17: note: imported from module root",
":1:1: error: file exists in modules 'foo' and 'root'",
":1:1: note: files must belong to only one module",
":1:1: note: file is the root of module 'foo'",
":3:17: note: file is imported here by the root of module 'root'",
});
case.addSourceFile("foo.zig",
\\const dummy = 0;

View file

@ -0,0 +1,35 @@
#target=x86_64-linux-selfhosted
#target=x86_64-linux-cbe
#target=x86_64-windows-cbe
#target=wasm32-wasi-selfhosted
#update=initial version
#file=main.zig
pub fn main() !void {
_ = @import("foo.zig");
try std.io.getStdOut().writeAll("success\n");
}
const std = @import("std");
#file=foo.zig
comptime {
_ = @import("bad.zig");
}
#expect_error=bad.zig:1:1: error: unable to load 'bad.zig': FileNotFound
#expect_error=foo.zig:2:17: note: file imported here
#update=change bad import
#file=foo.zig
comptime {
_ = @import("this_is/not_real.zig");
}
#expect_error=this_is/not_real.zig:1:1: error: unable to load 'not_real.zig': FileNotFound
#expect_error=foo.zig:2:17: note: file imported here
#update=remove import of 'foo.zig'
#file=main.zig
pub fn main() !void {
//_ = @import("foo.zig");
try std.io.getStdOut().writeAll("success\n");
}
const std = @import("std");
#expect_stdout="success\n"

View file

@ -0,0 +1,65 @@
#target=x86_64-linux-selfhosted
#target=x86_64-linux-cbe
#target=x86_64-windows-cbe
#target=wasm32-wasi-selfhosted
#module=foo=foo.zig
#update=initial version
#file=main.zig
pub fn main() void {
_ = @import("foo");
//_ = @import("other.zig");
}
#file=foo.zig
comptime {
_ = @import("other.zig");
}
#file=other.zig
fn f() void {
@compileLog(@src().module);
}
comptime {
f();
}
#expect_error=other.zig:2:5: error: found compile log statement
#expect_compile_log=@as([:0]const u8, "foo"[0..3])
#update=change module of other.zig
#file=main.zig
pub fn main() void {
_ = @import("foo");
_ = @import("other.zig");
}
#file=foo.zig
comptime {
//_ = @import("other.zig");
}
#expect_error=other.zig:2:5: error: found compile log statement
#expect_compile_log=@as([:0]const u8, "root"[0..4])
#update=put other.zig in both modules
#file=main.zig
pub fn main() void {
_ = @import("foo");
_ = @import("other.zig");
}
#file=foo.zig
comptime {
_ = @import("other.zig");
}
#expect_error=foo.zig:1:1: error: file exists in modules 'root' and 'foo'
#expect_error=foo.zig:1:1: note: files must belong to only one module
#expect_error=main.zig:3:17: note: file is imported here by the root of module 'root'
#expect_error=foo.zig:2:17: note: file is imported here by the root of module 'foo'
#update=put other.zig in no modules
#file=main.zig
pub fn main() void {
_ = @import("foo");
//_ = @import("other.zig");
}
#file=foo.zig
comptime {
//_ = @import("other.zig");
}
#expect_stdout=""

View file

@ -20,7 +20,8 @@ pub fn main() !void {
#update=delete file
#rm_file=message.zon
#expect_error=message.zon:1:1: error: unable to load './message.zon': FileNotFound
#expect_error=message.zon:1:1: error: unable to load 'message.zon': FileNotFound
#expect_error=main.zig:2:37: note: file imported here
#update=remove reference to ZON file
#file=main.zig
@ -29,7 +30,8 @@ const message: []const u8 = @import("message.zon");
pub fn main() !void {
try std.io.getStdOut().writeAll("a hardcoded string\n");
}
#expect_error=message.zon:1:1: error: unable to load './message.zon': FileNotFound
#expect_error=message.zon:1:1: error: unable to load 'message.zon': FileNotFound
#expect_error=main.zig:2:37: note: file imported here
#update=recreate ZON file
#file=message.zon

View file

@ -1,5 +1,4 @@
const foo = @import("foo");
const shared = @import("shared");
const assert = @import("std").debug.assert;
pub fn main() void {

View file

@ -106,7 +106,6 @@ pub fn main() !void {
try child_args.appendSlice(arena, &.{
resolved_zig_exe,
"build-exe",
case.root_source_file,
"-fincremental",
"-fno-ubsan-rt",
"-target",
@ -135,6 +134,13 @@ pub fn main() !void {
if (debug_link) {
try child_args.appendSlice(arena, &.{ "--debug-log", "link", "--debug-log", "link_state", "--debug-log", "link_relocs" });
}
for (case.modules) |mod| {
try child_args.appendSlice(arena, &.{ "--dep", mod.name });
}
try child_args.append(arena, try std.fmt.allocPrint(arena, "-Mroot={s}", .{case.root_source_file}));
for (case.modules) |mod| {
try child_args.append(arena, try std.fmt.allocPrint(arena, "-M{s}={s}", .{ mod.name, mod.file }));
}
const zig_prog_node = target_prog_node.start("zig build-exe", 0);
defer zig_prog_node.end();
@ -308,9 +314,8 @@ const Eval = struct {
const digest = body[@sizeOf(EbpHdr)..][0..Cache.bin_digest_len];
const result_dir = ".local-cache" ++ std.fs.path.sep_str ++ "o" ++ std.fs.path.sep_str ++ Cache.binToHex(digest.*);
const name = std.fs.path.stem(std.fs.path.basename(eval.case.root_source_file));
const bin_name = try std.zig.binNameAlloc(arena, .{
.root_name = name,
.root_name = "root", // corresponds to the module name "root"
.target = eval.target.resolved,
.output_mode = .Exe,
});
@ -359,7 +364,7 @@ const Eval = struct {
error_bundle.renderToStdErr(color.renderOptions());
eval.fatal("update '{s}': more errors than expected", .{update.name});
}
eval.checkOneError(update, error_bundle, expected.errors[expected_idx], false, err_idx);
try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], false, err_idx);
expected_idx += 1;
for (error_bundle.getNotes(err_idx)) |note_idx| {
@ -368,7 +373,7 @@ const Eval = struct {
error_bundle.renderToStdErr(color.renderOptions());
eval.fatal("update '{s}': more error notes than expected", .{update.name});
}
eval.checkOneError(update, error_bundle, expected.errors[expected_idx], true, note_idx);
try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], true, note_idx);
expected_idx += 1;
}
}
@ -387,13 +392,21 @@ const Eval = struct {
expected: Case.ExpectedError,
is_note: bool,
err_idx: std.zig.ErrorBundle.MessageIndex,
) void {
) Allocator.Error!void {
const err = eb.getErrorMessage(err_idx);
if (err.src_loc == .none) @panic("TODO error message with no source location");
if (err.count != 1) @panic("TODO error message with count>1");
const msg = eb.nullTerminatedString(err.msg);
const src = eb.getSourceLocation(err.src_loc);
const filename = eb.nullTerminatedString(src.src_path);
const raw_filename = eb.nullTerminatedString(src.src_path);
// We need to replace backslashes for consistency between platforms.
const filename = name: {
if (std.mem.indexOfScalar(u8, raw_filename, '\\') == null) break :name raw_filename;
const copied = try eval.arena.dupe(u8, raw_filename);
std.mem.replaceScalar(u8, copied, '\\', '/');
break :name copied;
};
if (expected.is_note != is_note or
!std.mem.eql(u8, expected.filename, filename) or
@ -605,6 +618,7 @@ const Case = struct {
updates: []Update,
root_source_file: []const u8,
targets: []const Target,
modules: []const Module,
const Target = struct {
query: []const u8,
@ -626,6 +640,11 @@ const Case = struct {
};
};
const Module = struct {
name: []const u8,
file: []const u8,
};
const Update = struct {
name: []const u8,
outcome: Outcome,
@ -660,6 +679,7 @@ const Case = struct {
const fatal = std.process.fatal;
var targets: std.ArrayListUnmanaged(Target) = .empty;
var modules: std.ArrayListUnmanaged(Module) = .empty;
var updates: std.ArrayListUnmanaged(Update) = .empty;
var changes: std.ArrayListUnmanaged(FullContents) = .empty;
var deletes: std.ArrayListUnmanaged([]const u8) = .empty;
@ -698,6 +718,15 @@ const Case = struct {
.resolved = resolved,
.backend = backend,
});
} else if (std.mem.eql(u8, key, "module")) {
const split_idx = std.mem.indexOfScalar(u8, val, '=') orelse
fatal("line {d}: module does not include file", .{line_n});
const name = val[0..split_idx];
const file = val[split_idx + 1 ..];
try modules.append(arena, .{
.name = name,
.file = file,
});
} else if (std.mem.eql(u8, key, "update")) {
if (updates.items.len > 0) {
const last_update = &updates.items[updates.items.len - 1];
@ -811,6 +840,7 @@ const Case = struct {
.updates = updates.items,
.root_source_file = root_source_file orelse fatal("missing root source file", .{}),
.targets = targets.items, // arena so no need for toOwnedSlice
.modules = modules.items,
};
}
};