diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index bb36bb978f..1ad111f2e3 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -9,6 +9,13 @@ pub const Directory = struct { path: ?[]const u8, handle: fs.Dir, + pub fn clone(d: Directory, arena: Allocator) Allocator.Error!Directory { + return .{ + .path = if (d.path) |p| try arena.dupe(u8, p) else null, + .handle = d.handle, + }; + } + pub fn cwd() Directory { return .{ .path = null, diff --git a/src/Module.zig b/src/Module.zig index 153edeafef..41f4ec2b41 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -4074,7 +4074,7 @@ pub fn importFile( return mod.importPkg(pkg); } if (!mem.endsWith(u8, import_string, ".zig")) { - return error.PackageNotFound; + return error.ModuleNotFound; } const gpa = mod.gpa; @@ -4120,7 +4120,7 @@ pub fn importFile( { break :p try gpa.dupe(u8, resolved_path); } - return error.ImportOutsidePkgPath; + return error.ImportOutsideModulePath; }; errdefer gpa.free(sub_file_path); @@ -4206,7 +4206,7 @@ pub fn embedFile(mod: *Module, cur_file: *File, import_string: []const u8) !*Emb { break :p try gpa.dupe(u8, resolved_path); } - return error.ImportOutsidePkgPath; + return error.ImportOutsideModulePath; }; errdefer gpa.free(sub_file_path); diff --git a/src/Package.zig b/src/Package.zig index 5de914e114..84ba10bfa5 100644 --- a/src/Package.zig +++ b/src/Package.zig @@ -9,6 +9,13 @@ pub const Path = struct { /// Empty string means the root_dir is the path. sub_path: []const u8 = "", + pub fn clone(p: Path, arena: Allocator) Allocator.Error!Path { + return .{ + .root_dir = try p.root_dir.clone(arena), + .sub_path = try arena.dupe(u8, p.sub_path), + }; + } + pub fn cwd() Path { return .{ .root_dir = Cache.Directory.cwd() }; } diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 7ea1fee733..ace1871d42 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -109,7 +109,6 @@ pub const JobQueue = struct { /// build runner to obtain via `@import("@dependencies")`. pub fn createDependenciesModule(jq: *JobQueue, buf: *std.ArrayList(u8)) Allocator.Error!void { const keys = jq.table.keys(); - const values = jq.table.values(); if (keys.len == 0) return createEmptyDependenciesModule(buf); @@ -124,7 +123,11 @@ pub const JobQueue = struct { } }, .{ .keys = keys })); - for (keys[1..], values[1..]) |hash, fetch| { + for (keys, jq.table.values()) |hash, fetch| { + if (fetch == jq.all_fetches.items[0]) { + // The first one is a dummy package for the current project. + continue; + } try buf.writer().print( \\ pub const {} = struct {{ \\ pub const build_root = "{q}"; diff --git a/src/Sema.zig b/src/Sema.zig index 5e428c9f77..2df8b8570e 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -13075,13 +13075,13 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const operand = inst_data.get(sema.code); const result = mod.importFile(block.getFileScope(mod), operand) catch |err| switch (err) { - error.ImportOutsidePkgPath => { - return sema.fail(block, operand_src, "import of file outside package path: '{s}'", .{operand}); + error.ImportOutsideModulePath => { + return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand}); }, - error.PackageNotFound => { + error.ModuleNotFound => { //const name = try block.getFileScope(mod).mod.getName(sema.gpa, mod.*); //defer sema.gpa.free(name); - return sema.fail(block, operand_src, "no package named '{s}' available within package '{}'", .{ + return sema.fail(block, operand_src, "no module named '{s}' available within module '{}'", .{ operand, block.getFileScope(mod).mod.root, }); }, @@ -13112,7 +13112,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A } const embed_file = mod.embedFile(block.getFileScope(mod), name) catch |err| switch (err) { - error.ImportOutsidePkgPath => { + error.ImportOutsideModulePath => { return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name}); }, else => { diff --git a/src/main.zig b/src/main.zig index bf4c37781f..df32783807 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4885,39 +4885,60 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi } try job_queue.createDependenciesModule(&dependencies_zig_src); - } - { - // Atomically create the file in a directory named after the hash of its contents. - const basename = "dependencies.zig"; - const rand_int = std.crypto.random.int(u64); - const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ Package.Manifest.hex64(rand_int); + + const deps_mod = m: { + // Atomically create the file in a directory named after the hash of its contents. + const basename = "dependencies.zig"; + const rand_int = std.crypto.random.int(u64); + const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ + Package.Manifest.hex64(rand_int); + { + var tmp_dir = try local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{}); + defer tmp_dir.close(); + try tmp_dir.writeFile(basename, dependencies_zig_src.items); + } + + var hh: Cache.HashHelper = .{}; + hh.addBytes(build_options.version); + hh.addBytes(dependencies_zig_src.items); + const hex_digest = hh.final(); + + const o_dir_sub_path = try arena.dupe(u8, "o" ++ fs.path.sep_str ++ hex_digest); + try Package.Fetch.renameTmpIntoCache( + local_cache_directory.handle, + tmp_dir_sub_path, + o_dir_sub_path, + ); + + break :m try Package.Module.create(arena, .{ + .root = .{ + .root_dir = local_cache_directory, + .sub_path = o_dir_sub_path, + }, + .root_src_path = basename, + }); + }; { - var tmp_dir = try local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{}); - defer tmp_dir.close(); - try tmp_dir.writeFile(basename, dependencies_zig_src.items); + // We need a Module for each package's build.zig. + const hashes = job_queue.table.keys(); + const fetches = job_queue.table.values(); + try deps_mod.deps.ensureUnusedCapacity(arena, @intCast(hashes.len)); + for (hashes, fetches) |hash, f| { + if (f == &fetch) { + // The first one is a dummy package for the current project. + continue; + } + const m = try Package.Module.create(arena, .{ + .root = try f.package_root.clone(arena), + .root_src_path = if (f.has_build_zig) Package.build_zig_basename else "", + }); + const hash_cloned = try arena.dupe(u8, &hash); + deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m); + } } - - var hh: Cache.HashHelper = .{}; - hh.addBytes(build_options.version); - hh.addBytes(dependencies_zig_src.items); - const hex_digest = hh.final(); - - const o_dir_sub_path = try arena.dupe(u8, "o" ++ fs.path.sep_str ++ hex_digest); - try Package.Fetch.renameTmpIntoCache( - local_cache_directory.handle, - tmp_dir_sub_path, - o_dir_sub_path, - ); - - const deps_mod = try Package.Module.create(arena, .{ - .root = .{ - .root_dir = local_cache_directory, - .sub_path = o_dir_sub_path, - }, - .root_src_path = basename, - }); try main_mod.deps.put(arena, "@dependencies", deps_mod); } + try main_mod.deps.put(arena, "@build", &build_mod); const comp = Compilation.create(gpa, .{