Skip to content

Commit

Permalink
Minor build runners update
Browse files Browse the repository at this point in the history
0.11.0
- Fix `getPath() was called on a GeneratedFile that wasn't built yet.`
- Add missing `cache.hash.addBytes(builtin.zig_version_string);`

0.11.0, master:
- Resolve mod imports in `build.zig`s
- Show completions for mod imports in `build.zig`s
  • Loading branch information
llogick committed Nov 5, 2023
1 parent 7430bb6 commit 69aca32
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 6 deletions.
12 changes: 11 additions & 1 deletion src/DocumentStore.zig
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ pub fn loadBuildConfiguration(self: *DocumentStore, build_file_uri: Uri) !std.js
.allocator = self.allocator,
.argv = args,
.cwd = std.fs.path.dirname(build_file_path).?,
.max_output_bytes = 1024 * 100,
.max_output_bytes = 1024 * 1024,
});
};
defer self.allocator.free(zig_run_result.stdout);
Expand Down Expand Up @@ -1413,6 +1413,16 @@ pub fn uriFromImportStr(self: *DocumentStore, allocator: std.mem.Allocator, hand
return try URI.fromPath(allocator, pkg.path);
}
}
} else if (isBuildFile(handle.uri)) blk: {
const build_file = self.getBuildFile(handle.uri).?;
const build_config = build_file.tryLockConfig() orelse break :blk;
defer build_file.unlockConfig();

for (build_config.deps_build_roots) |dep_build_root| {
if (std.mem.eql(u8, import_str, dep_build_root.name)) {
return try URI.fromPath(allocator, dep_build_root.path);
}
}
}
return null;
} else {
Expand Down
38 changes: 33 additions & 5 deletions src/build_runner/0.11.0.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const root = @import("@build");
const std = @import("std");
const builtin = @import("builtin");
const log = std.log;
const process = std.process;

Expand Down Expand Up @@ -64,6 +65,7 @@ pub fn main() !void {
cache.addPrefix(build_root_directory);
cache.addPrefix(local_cache_directory);
cache.addPrefix(global_cache_directory);
cache.hash.addBytes(builtin.zig_version_string);

const host = try std.zig.system.NativeTargetInfo.detect(.{});

Expand Down Expand Up @@ -129,11 +131,23 @@ pub fn main() !void {
}
}

var deps_build_roots: std.ArrayListUnmanaged(BuildConfig.DepsBuildRoots) = .{};
inline for (@typeInfo(dependencies.build_root).Struct.decls) |decl| {
try deps_build_roots.append(allocator, .{
.name = decl.name,
// XXX Check if it exists?
.path = try std.fs.path.resolve(allocator, &[_][]const u8{ @field(dependencies.build_root, decl.name), "./build.zig" }),
});
}
const deps_build_roots_list = try deps_build_roots.toOwnedSlice(allocator);
defer allocator.free(deps_build_roots_list);

const package_list = try packages.toPackageList();
defer allocator.free(package_list);

try std.json.stringify(
BuildConfig{
.deps_build_roots = deps_build_roots_list,
.packages = package_list,
.include_dirs = include_dirs.keys(),
},
Expand Down Expand Up @@ -208,14 +222,14 @@ fn processStep(
) anyerror!void {
if (step.cast(Build.Step.InstallArtifact)) |install_exe| {
if (install_exe.artifact.root_src) |src| {
_ = try packages.addPackage("root", src.getPath(builder));
if (copied_from_zig.getPath(src, builder)) |path| _ = try packages.addPackage("root", path);
}
try processIncludeDirs(builder, include_dirs, install_exe.artifact.include_dirs.items);
try processPkgConfig(builder.allocator, include_dirs, install_exe.artifact);
try processModules(builder, packages, install_exe.artifact.modules);
} else if (step.cast(Build.Step.Compile)) |exe| {
if (exe.root_src) |src| {
_ = try packages.addPackage("root", src.getPath(builder));
if (copied_from_zig.getPath(src, builder)) |path| _ = try packages.addPackage("root", path);
}
try processIncludeDirs(builder, include_dirs, exe.include_dirs.items);
try processPkgConfig(builder.allocator, include_dirs, exe);
Expand All @@ -233,7 +247,7 @@ fn processModules(
modules: std.StringArrayHashMap(*Build.Module),
) !void {
for (modules.keys(), modules.values()) |name, mod| {
const path = mod.builder.pathFromRoot(mod.source_file.getPath(mod.builder));
const path = copied_from_zig.getPath(mod.source_file, mod.builder) orelse continue;

const already_added = try packages.addPackage(name, path);
// if the package has already been added short circuit here or recursive modules will ruin us
Expand All @@ -252,8 +266,7 @@ fn processIncludeDirs(

for (dirs) |dir| {
const candidate: []const u8 = switch (dir) {
.path => |path| path.getPath(builder),
.path_system => |path| path.getPath(builder),
.path, .path_system => |path| copied_from_zig.getPath(path, builder) orelse continue,
else => continue,
};

Expand Down Expand Up @@ -310,6 +323,21 @@ fn getPkgConfigIncludes(

// TODO: Having a copy of this is not very nice
const copied_from_zig = struct {
/// Copied from `std.Build.LazyPath.getPath2` and massaged a bit.
fn getPath(path: std.Build.LazyPath, builder: *Build) ?[]const u8 {
switch (path) {
.path => |p| return builder.pathFromRoot(p),
.cwd_relative => |p| return pathFromCwd(builder, p),
.generated => |gen| return builder.pathFromRoot(gen.path orelse return null),
}
}

/// Copied from `std.Build.pathFromCwd` as it is non-pub.
fn pathFromCwd(b: *Build, p: []const u8) []u8 {
const cwd = process.getCwdAlloc(b.allocator) catch @panic("OOM");
return std.fs.path.resolve(b.allocator, &.{ cwd, p }) catch @panic("OOM");
}

fn runPkgConfig(self: *Build.Step.Compile, lib_name: []const u8) ![]const []const u8 {
const b = self.step.owner;
const pkg_name = match: {
Expand Down
2 changes: 2 additions & 0 deletions src/build_runner/BuildConfig.zig
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
pub const BuildConfig = @This();

deps_build_roots: []DepsBuildRoots,
packages: []Pkg,
include_dirs: []const []const u8,

pub const DepsBuildRoots = Pkg;
pub const Pkg = struct {
name: []const u8,
path: []const u8,
Expand Down
34 changes: 34 additions & 0 deletions src/build_runner/master.zig
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,45 @@ pub fn main() !void {
}
}

// Sample `@dependencies` structure:
// pub const packages = struct {
// pub const @"1220363c7e27b2d3f39de6ff6e90f9537a0634199860fea237a55ddb1e1717f5d6a5" = struct {
// pub const build_root = "/home/rad/.cache/zig/p/1220363c7e27b2d3f39de6ff6e90f9537a0634199860fea237a55ddb1e1717f5d6a5";
// pub const build_zig = @import("1220363c7e27b2d3f39de6ff6e90f9537a0634199860fea237a55ddb1e1717f5d6a5");
// pub const deps: []const struct { []const u8, []const u8 } = &.{};
// };
// ...
// };
// pub const root_deps: []const struct { []const u8, []const u8 } = &.{
// .{ "known_folders", "1220bb12c9bfe291eed1afe6a2070c7c39918ab1979f24a281bba39dfb23f5bcd544" },
// .{ "diffz", "122089a8247a693cad53beb161bde6c30f71376cd4298798d45b32740c3581405864" },
// .{ "binned_allocator", "1220363c7e27b2d3f39de6ff6e90f9537a0634199860fea237a55ddb1e1717f5d6a5" },
// };

var deps_build_roots: std.ArrayListUnmanaged(BuildConfig.DepsBuildRoots) = .{};
for (dependencies.root_deps) |root_dep| {
inline for (@typeInfo(dependencies.packages).Struct.decls) |package| {
if (std.mem.eql(u8, package.name, root_dep[1])) {
const package_info = @field(dependencies.packages, package.name);
if (!@hasDecl(package_info, "build_root")) continue;
try deps_build_roots.append(allocator, .{
.name = root_dep[0],
// XXX Check if it exists?
.path = try std.fs.path.resolve(allocator, &[_][]const u8{ package_info.build_root, "./build.zig" }),
});
}
}
}

const deps_build_roots_list = try deps_build_roots.toOwnedSlice(allocator);
defer allocator.free(deps_build_roots_list);

const package_list = try packages.toPackageList();
defer allocator.free(package_list);

try std.json.stringify(
BuildConfig{
.deps_build_roots = deps_build_roots_list,
.packages = package_list,
.include_dirs = include_dirs.keys(),
},
Expand Down
13 changes: 13 additions & 0 deletions src/features/completions.zig
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,19 @@ fn completeFileSystemStringLiteral(
.detail = pkg.path,
}, {});
}
} else if (DocumentStore.isBuildFile(handle.uri)) blk: {
const build_file = store.getBuildFile(handle.uri).?;
const build_config = build_file.tryLockConfig() orelse break :blk;
defer build_file.unlockConfig();

try completions.ensureUnusedCapacity(arena, build_config.deps_build_roots.len);
for (build_config.deps_build_roots) |dbr| {
completions.putAssumeCapacity(.{
.label = dbr.name,
.kind = .Module,
.detail = dbr.path,
}, {});
}
}

try completions.ensureUnusedCapacity(arena, 2);
Expand Down

0 comments on commit 69aca32

Please sign in to comment.