Skip to content

Commit e3a9ac1

Browse files
committed
compiler: jit zig dep-hash
1 parent 13d841e commit e3a9ac1

File tree

6 files changed

+227
-225
lines changed

6 files changed

+227
-225
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,8 @@ set(ZIG_STAGE2_SOURCES
505505
lib/std/zig/system/NativePaths.zig
506506
lib/std/zig/system/x86.zig
507507
lib/std/zig/tokenizer.zig
508+
lib/std/zig/Manifest.zig
509+
lib/std/zig/introspect.zig
508510
src/Air.zig
509511
src/Builtin.zig
510512
src/Compilation.zig
@@ -516,7 +518,6 @@ set(ZIG_STAGE2_SOURCES
516518
src/Package.zig
517519
src/Package/Fetch.zig
518520
src/Package/Fetch/git.zig
519-
src/Package/Manifest.zig
520521
src/Package/Module.zig
521522
src/RangeSet.zig
522523
src/Sema.zig
@@ -580,7 +581,6 @@ set(ZIG_STAGE2_SOURCES
580581
src/codegen/spirv/spec.zig
581582
src/crash_report.zig
582583
src/glibc.zig
583-
src/introspect.zig
584584
src/libcxx.zig
585585
src/libtsan.zig
586586
src/libunwind.zig

bootstrap.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ int main(int argc, char **argv) {
142142
"pub const force_gpa = false;\n"
143143
"pub const only_c = false;\n"
144144
"pub const only_core_functionality = true;\n"
145-
"pub const only_dep_hash = false;\n"
146145
, zig_version);
147146
if (written < 100)
148147
panic("unable to write to config.zig file");

build.zig

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const zig_version: std.SemanticVersion = .{ .major = 0, .minor = 14, .patch = 0
1313
const stack_size = 32 * 1024 * 1024;
1414

1515
pub fn build(b: *std.Build) !void {
16-
const only_dep_hash = b.option(bool, "only-dep-hash", "Only compile zig dep-hash") orelse false;
1716
const only_c = b.option(bool, "only-c", "Translate the Zig compiler to C code, with only the C backend enabled") orelse false;
1817
const target = t: {
1918
var default_target: std.Target.Query = .{};
@@ -28,7 +27,7 @@ pub fn build(b: *std.Build) !void {
2827
const use_zig_libcxx = b.option(bool, "use-zig-libcxx", "If libc++ is needed, use zig's bundled version, don't try to integrate with the system") orelse false;
2928

3029
const test_step = b.step("test", "Run all the tests");
31-
const skip_install_lib_files = b.option(bool, "no-lib", "skip copying of lib/ files and langref to installation prefix. Useful for development") orelse only_dep_hash;
30+
const skip_install_lib_files = b.option(bool, "no-lib", "skip copying of lib/ files and langref to installation prefix. Useful for development") orelse false;
3231
const skip_install_langref = b.option(bool, "no-langref", "skip copying of langref to the installation prefix") orelse skip_install_lib_files;
3332
const std_docs = b.option(bool, "std-docs", "include standard library autodocs") orelse false;
3433
const no_bin = b.option(bool, "no-bin", "skip emitting compiler binary") orelse false;
@@ -233,7 +232,6 @@ pub fn build(b: *std.Build) !void {
233232
exe_options.addOption(bool, "force_gpa", force_gpa);
234233
exe_options.addOption(bool, "only_c", only_c);
235234
exe_options.addOption(bool, "only_core_functionality", only_c);
236-
exe_options.addOption(bool, "only_dep_hash", only_dep_hash);
237235

238236
if (link_libc) {
239237
exe.linkLibC();

lib/compiler/dep-hash.zig

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
const usage_dep_hash =
2+
\\Usage: zig dep-hash [--list] [dep-name]
3+
\\
4+
\\ List the hashes of packages in the build.zig.zon manifest.
5+
\\
6+
\\Options:
7+
\\ --list List all package hashes
8+
\\ --build-root [path] Set package root directory
9+
\\ --global-cache-dir [path] Override the global cache directory
10+
\\ -h, --help Print this help and exit
11+
\\
12+
\\
13+
;
14+
15+
pub fn main() !void {
16+
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
17+
defer arena_instance.deinit();
18+
const arena = arena_instance.allocator();
19+
const gpa = arena;
20+
21+
const args = try std.process.argsAlloc(arena);
22+
const color: std.zig.Color = .auto;
23+
var list = false;
24+
var package_opt: ?[]const u8 = null;
25+
var build_root_path: ?[]const u8 = null;
26+
var override_global_cache_dir: ?[]const u8 = try std.zig.EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
27+
28+
assert(args.len > 0);
29+
30+
{
31+
var i: usize = 1;
32+
while (i < args.len) : (i += 1) {
33+
const arg = args[i];
34+
if (arg[0] == '-') {
35+
if (std.mem.eql(u8, arg, "-h") or std.mem.eql(u8, arg, "--help")) {
36+
const stdout = std.io.getStdOut();
37+
try stdout.writeAll(usage_dep_hash);
38+
return std.process.cleanExit();
39+
} else if (std.mem.eql(u8, arg, "--list")) {
40+
list = true;
41+
} else if (std.mem.eql(u8, arg, "--build-root")) {
42+
i += 1;
43+
if (i >= args.len) fatal("build root expected after --build-root", .{});
44+
build_root_path = args[i];
45+
} else if (std.mem.eql(u8, arg, "--global-cache-dir")) {
46+
i += 1;
47+
if (i >= args.len) fatal("cache directory expected after --global-cache-dir", .{});
48+
override_global_cache_dir = args[i];
49+
} else {
50+
fatal("unrecognized parameter: '{s}'", .{arg});
51+
}
52+
} else if (package_opt != null) {
53+
fatal("unexpected extra parameter: '{s}'", .{arg});
54+
} else {
55+
package_opt = arg;
56+
}
57+
}
58+
}
59+
60+
var build_root = try std.zig.findBuildRoot(arena, .{
61+
.cwd_path = build_root_path,
62+
.hint = build_root_path == null,
63+
});
64+
defer build_root.deinit();
65+
66+
var global_cache_package_directory: std.fs.Dir = l: {
67+
const p = try std.fs.path.join(arena, &.{
68+
override_global_cache_dir orelse try std.zig.introspect.resolveGlobalCacheDir(arena),
69+
"p",
70+
});
71+
72+
break :l try std.fs.cwd().makeOpenPath(p, .{});
73+
};
74+
defer global_cache_package_directory.close();
75+
76+
var manifest, var ast = std.zig.loadManifest(gpa, arena, .{
77+
.root_name = null,
78+
.dir = build_root.directory.handle,
79+
.color = color,
80+
}) catch |err| switch (err) {
81+
error.FileNotFound => fatal("no manifest found in build root", .{}),
82+
else => |e| return e,
83+
};
84+
defer {
85+
manifest.deinit(gpa);
86+
ast.deinit(gpa);
87+
}
88+
89+
if (package_opt) |package| {
90+
if (package.len == 0) {
91+
fatal("package name must not be empty", .{});
92+
}
93+
const dep: std.zig.Manifest.Dependency = dep: {
94+
var iter = std.mem.tokenizeScalar(u8, package, '.');
95+
96+
var dep = manifest.dependencies.get(iter.next().?) orelse {
97+
fatal("there is no dependency named '{s}' in the manifest\n", .{package});
98+
};
99+
100+
var dep_name = iter.buffer[0 .. iter.index - 1];
101+
102+
while (iter.next()) |p| {
103+
if (dep.hash) |hash| {
104+
var package_dir = global_cache_package_directory.openDir(hash, .{}) catch |e| switch (e) {
105+
error.FileNotFound => fatal("{s} is not in the global cache (hash: {s})", .{
106+
dep_name, hash,
107+
}),
108+
else => |err| return err,
109+
};
110+
defer package_dir.close();
111+
112+
const sub_manifest, _ = try std.zig.loadManifest(arena, arena, .{
113+
.root_name = null,
114+
.dir = package_dir,
115+
.color = color,
116+
});
117+
118+
dep = sub_manifest.dependencies.get(p) orelse {
119+
fatal("{s} has no dependency named '{s}' in its manifest", .{ dep_name, package });
120+
};
121+
dep_name = iter.buffer[0 .. iter.index - 1];
122+
} else switch (dep.location) {
123+
.url => fatal("the hash for {s} is missing from the manifest.\n", .{
124+
dep_name,
125+
}),
126+
.path => |path| fatal("{s} is a local dependency located at {s}\n", .{
127+
dep_name, path,
128+
}),
129+
}
130+
}
131+
132+
break :dep dep;
133+
};
134+
135+
const stdout = std.io.getStdOut().writer();
136+
137+
if (dep.hash) |hash| {
138+
if (list) {
139+
var package_dir = global_cache_package_directory.openDir(hash, .{}) catch |e| switch (e) {
140+
error.FileNotFound => fatal("{s} is not in the global cache (hash: {s})", .{
141+
package, hash,
142+
}),
143+
else => |err| return err,
144+
};
145+
defer package_dir.close();
146+
147+
var sub_manifest, var sub_ast = std.zig.loadManifest(gpa, arena, .{
148+
.root_name = null,
149+
.dir = package_dir,
150+
.color = color,
151+
}) catch |err| switch (err) {
152+
error.FileNotFound => fatal("no manifest found in build root", .{}),
153+
else => |e| return e,
154+
};
155+
defer {
156+
sub_manifest.deinit(gpa);
157+
sub_ast.deinit(gpa);
158+
}
159+
160+
const prefix = prefix: {
161+
const buffer = try arena.alloc(u8, package.len + 1);
162+
@memcpy(buffer[0..package.len], package);
163+
buffer[buffer.len - 1] = '.';
164+
break :prefix buffer;
165+
};
166+
167+
try listDepHashes(prefix, sub_manifest);
168+
} else {
169+
try stdout.print("{s}\n", .{hash});
170+
}
171+
} else switch (dep.location) {
172+
.url => fatal("the hash for {s} is missing from the manifest.\n", .{package}),
173+
.path => |path| fatal("{s} is a local dependency located at {s}\n", .{ package, path }),
174+
}
175+
} else {
176+
try listDepHashes("", manifest);
177+
}
178+
}
179+
180+
fn listDepHashes(parent_prefix: []const u8, manifest: std.zig.Manifest) !void {
181+
assert(parent_prefix.len != 1);
182+
if (manifest.dependencies.count() == 0) {
183+
const name = if (parent_prefix.len > 0)
184+
parent_prefix[0 .. parent_prefix.len - 1]
185+
else
186+
manifest.name;
187+
188+
const stdout = std.io.getStdOut().writer();
189+
try stdout.print("{s} has no dependencies\n", .{name});
190+
return;
191+
}
192+
193+
var deps = manifest.dependencies.iterator();
194+
while (deps.next()) |entry| {
195+
const stdout = std.io.getStdOut().writer();
196+
const name = entry.key_ptr.*;
197+
if (entry.value_ptr.hash) |hash| {
198+
try stdout.print("{s}{s} {s}\n", .{ parent_prefix, name, hash });
199+
} else {
200+
switch (entry.value_ptr.location) {
201+
.url => try stdout.print("{s}{s} {s}\n", .{
202+
parent_prefix, name, "(missing)",
203+
}),
204+
.path => |p| try stdout.print("{s}{s} {s} (local)\n", .{
205+
parent_prefix, name, p,
206+
}),
207+
}
208+
}
209+
}
210+
}
211+
212+
fn fatal(comptime format: []const u8, args: anytype) noreturn {
213+
std.log.err(format, args);
214+
std.process.exit(1);
215+
}
216+
217+
const std = @import("std");
218+
const assert = std.debug.assert;
219+
const Allocator = std.mem.Allocator;

0 commit comments

Comments
 (0)