Skip to content

rework package manager #17392

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 39 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
51e15a9
std.tar: add option for omitting empty directories
andrewrk Oct 4, 2023
24c8adc
std.zig.ErrorBundle: add some explicit error sets
andrewrk Oct 4, 2023
ef87729
Manifest: add top-level `paths` field for inclusion rules
andrewrk Oct 4, 2023
d06da95
add basic build.zig.zon documentation
andrewrk Oct 4, 2023
88bbec8
rework package manager
andrewrk Oct 4, 2023
d0bcc39
get `zig fetch` working with the new system
andrewrk Oct 7, 2023
1c0d6f9
require inclusion directives in root manifest but not deps
andrewrk Oct 7, 2023
f708c5f
CLI: finish updating module API usage
andrewrk Oct 7, 2023
aed6adb
fix Fetch.JobQueue.consolidateErrors
andrewrk Oct 7, 2023
ddb7c40
fix inverted logic for allowing/disallowing paths field
andrewrk Oct 7, 2023
1ca4428
fix recursive package fetching logic
andrewrk Oct 7, 2023
cbb9b5d
std: add unstable sorting to array hash maps
andrewrk Oct 7, 2023
9eb2154
make Package.Path support string escape formatting
andrewrk Oct 7, 2023
4eb7b61
package fetching: generate dependencies.zig file
andrewrk Oct 7, 2023
e86b7fc
fix detection of build.zig file inside packages
andrewrk Oct 7, 2023
a232f7e
finish implementing the auto-generated dependencies.zig module
andrewrk Oct 7, 2023
35d81c9
more fixes related to previous commits Package/Module API
andrewrk Oct 7, 2023
e5c2a7d
finish hooking up new dependency tree logic
andrewrk Oct 8, 2023
7b25d05
std.tar: fix creation of symlinks with omit_empty_directories
andrewrk Oct 8, 2023
b7fc53c
dependencies.zig: omit modules without build.zig as deps
andrewrk Oct 8, 2023
b2fefc8
dependencies.zig: omit deps without hashes
andrewrk Oct 8, 2023
a605bd9
zig build: add `--fetch` argument
andrewrk Oct 8, 2023
29156de
CLI: fix only_core_functionality logic
andrewrk Oct 8, 2023
1fd95fc
Package.Fetch: resolve instead of join relative paths
andrewrk Oct 8, 2023
47a4133
Package.Fetch: fix handling of relative paths
andrewrk Oct 8, 2023
ce052d8
Manifest: fix not initializing token locations
andrewrk Oct 8, 2023
1ad33f5
give build.zig modules access to their dependencies' build.zig modules
andrewrk Oct 8, 2023
f48ec4b
use long-lived arena for `@cImport`-generated Module
andrewrk Oct 8, 2023
f0cc6f1
Package.Fetch: fix not making directory paths for symlinks
andrewrk Oct 9, 2023
8f20ce7
zig fetch: require 'paths' field in the manifest
andrewrk Oct 9, 2023
7bae6d9
fix dependencies.zig generation with no dependencies
andrewrk Oct 9, 2023
6d84caf
move some package management related source files around
andrewrk Oct 9, 2023
5e7c44a
Package.Fetch: tighten up check for path outside root
andrewrk Oct 9, 2023
1b372f1
fix using the wrong allocator for modules
andrewrk Oct 9, 2023
efbfa8e
std.fs.path.resolve: add test cases for empty string
andrewrk Oct 9, 2023
4a2cf38
Package.Fetch: apply inclusion rules from build.zig.zon
andrewrk Oct 9, 2023
cd43977
Package.Fetch: improved deletion algorithm
andrewrk Oct 9, 2023
5eb5d52
give modules friendly names for error reporting
andrewrk Oct 9, 2023
95907cb
restore progress reporting for package fetching
andrewrk Oct 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/src/Liveness.zig"
"${CMAKE_SOURCE_DIR}/src/Module.zig"
"${CMAKE_SOURCE_DIR}/src/Package.zig"
"${CMAKE_SOURCE_DIR}/src/Package/hash.zig"
"${CMAKE_SOURCE_DIR}/src/Package/Fetch.zig"
"${CMAKE_SOURCE_DIR}/src/RangeSet.zig"
"${CMAKE_SOURCE_DIR}/src/Sema.zig"
"${CMAKE_SOURCE_DIR}/src/TypedValue.zig"
Expand Down
2 changes: 1 addition & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub fn build(b: *std.Build) !void {
.name = "check-case",
.root_source_file = .{ .path = "test/src/Cases.zig" },
.optimize = optimize,
.main_pkg_path = .{ .path = "." },
.main_mod_path = .{ .path = "." },
});
check_case_exe.stack_size = stack_size;
check_case_exe.single_threaded = single_threaded;
Expand Down
65 changes: 65 additions & 0 deletions doc/build.zig.zon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# build.zig.zon Documentation

This is the manifest file for build.zig scripts. It is named build.zig.zon in
order to make it clear that it is metadata specifically pertaining to
build.zig.

- **build root** - the directory that contains `build.zig`

## Top-Level Fields

### `name`

String. Required.

### `version`

String. Required.

[semver](https://semver.org/)

### `dependencies`

Struct.

Each dependency must either provide a `url` and `hash`, or a `path`.

#### `url`

String.

When updating this field to a new URL, be sure to delete the corresponding
`hash`, otherwise you are communicating that you expect to find the old hash at
the new URL.

#### `hash`

String.

[multihash](https://multiformats.io/multihash/)

This is computed from the file contents of the directory of files that is
obtained after fetching `url` and applying the inclusion rules given by
`paths`.

This field is the source of truth; packages do not come from an `url`; they
come from a `hash`. `url` is just one of many possible mirrors for how to
obtain a package matching this `hash`.

#### `path`

String.

When this is provided, the package is found in a directory relative to the
build root. In this case the package's hash is irrelevant and therefore not
computed.

### `paths`

List. Required.

Specifies the set of files and directories that are included in this package.
Paths are relative to the build root. Use the empty string (`""`) to refer to
the build root itself.

Only files included in the package are used to compute a package's `hash`.
1 change: 1 addition & 0 deletions lib/build_runner.zig
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,7 @@ fn usage(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi
\\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
\\ --maxrss <bytes> Limit memory usage (default is to use available memory)
\\ --skip-oom-steps Instead of failing, skip steps that would exceed --maxrss
\\ --fetch Exit after fetching dependency tree
\\
\\Project-Specific Options:
\\
Expand Down
25 changes: 20 additions & 5 deletions lib/std/Build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,9 @@ pub const ExecutableOptions = struct {
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
main_mod_path: ?LazyPath = null,

/// Deprecated; use `main_mod_path`.
main_pkg_path: ?LazyPath = null,
};

Expand All @@ -652,7 +655,7 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile {
.use_llvm = options.use_llvm,
.use_lld = options.use_lld,
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
.main_pkg_path = options.main_pkg_path,
.main_mod_path = options.main_mod_path orelse options.main_pkg_path,
});
}

Expand All @@ -667,6 +670,9 @@ pub const ObjectOptions = struct {
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
main_mod_path: ?LazyPath = null,

/// Deprecated; use `main_mod_path`.
main_pkg_path: ?LazyPath = null,
};

Expand All @@ -683,7 +689,7 @@ pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile {
.use_llvm = options.use_llvm,
.use_lld = options.use_lld,
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
.main_pkg_path = options.main_pkg_path,
.main_mod_path = options.main_mod_path orelse options.main_pkg_path,
});
}

Expand All @@ -699,6 +705,9 @@ pub const SharedLibraryOptions = struct {
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
main_mod_path: ?LazyPath = null,

/// Deprecated; use `main_mod_path`.
main_pkg_path: ?LazyPath = null,
};

Expand All @@ -717,7 +726,7 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile
.use_llvm = options.use_llvm,
.use_lld = options.use_lld,
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
.main_pkg_path = options.main_pkg_path,
.main_mod_path = options.main_mod_path orelse options.main_pkg_path,
});
}

Expand All @@ -733,6 +742,9 @@ pub const StaticLibraryOptions = struct {
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
main_mod_path: ?LazyPath = null,

/// Deprecated; use `main_mod_path`.
main_pkg_path: ?LazyPath = null,
};

Expand All @@ -751,7 +763,7 @@ pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile
.use_llvm = options.use_llvm,
.use_lld = options.use_lld,
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
.main_pkg_path = options.main_pkg_path,
.main_mod_path = options.main_mod_path orelse options.main_pkg_path,
});
}

Expand All @@ -769,6 +781,9 @@ pub const TestOptions = struct {
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
main_mod_path: ?LazyPath = null,

/// Deprecated; use `main_mod_path`.
main_pkg_path: ?LazyPath = null,
};

Expand All @@ -787,7 +802,7 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {
.use_llvm = options.use_llvm,
.use_lld = options.use_lld,
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
.main_pkg_path = options.main_pkg_path,
.main_mod_path = options.main_mod_path orelse options.main_pkg_path,
});
}

Expand Down
20 changes: 19 additions & 1 deletion lib/std/Build/Cache.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ 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,
.handle = fs.cwd(),
};
}

pub fn join(self: Directory, allocator: Allocator, paths: []const []const u8) ![]u8 {
if (self.path) |p| {
// TODO clean way to do this with only 1 allocation
Expand Down Expand Up @@ -47,12 +61,16 @@ pub const Directory = struct {
writer: anytype,
) !void {
_ = options;
if (fmt_string.len != 0) fmt.invalidFmtError(fmt, self);
if (fmt_string.len != 0) fmt.invalidFmtError(fmt_string, self);
if (self.path) |p| {
try writer.writeAll(p);
try writer.writeAll(fs.path.sep_str);
}
}

pub fn eql(self: Directory, other: Directory) bool {
return self.handle.fd == other.handle.fd;
}
};

gpa: Allocator,
Expand Down
15 changes: 9 additions & 6 deletions lib/std/Build/Step/Compile.zig
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ c_std: std.Build.CStd,
/// Set via options; intended to be read-only after that.
zig_lib_dir: ?LazyPath,
/// Set via options; intended to be read-only after that.
main_pkg_path: ?LazyPath,
main_mod_path: ?LazyPath,
exec_cmd_args: ?[]const ?[]const u8,
filter: ?[]const u8,
test_evented_io: bool = false,
Expand Down Expand Up @@ -316,6 +316,9 @@ pub const Options = struct {
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
main_mod_path: ?LazyPath = null,

/// deprecated; use `main_mod_path`.
main_pkg_path: ?LazyPath = null,
};

Expand Down Expand Up @@ -480,7 +483,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
.installed_headers = ArrayList(*Step).init(owner.allocator),
.c_std = std.Build.CStd.C99,
.zig_lib_dir = null,
.main_pkg_path = null,
.main_mod_path = null,
.exec_cmd_args = null,
.filter = options.filter,
.test_runner = options.test_runner,
Expand Down Expand Up @@ -515,8 +518,8 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
lp.addStepDependencies(&self.step);
}

if (options.main_pkg_path) |lp| {
self.main_pkg_path = lp.dupe(self.step.owner);
if (options.main_mod_path orelse options.main_pkg_path) |lp| {
self.main_mod_path = lp.dupe(self.step.owner);
lp.addStepDependencies(&self.step);
}

Expand Down Expand Up @@ -1998,8 +2001,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try zig_args.append(dir.getPath(b));
}

if (self.main_pkg_path) |dir| {
try zig_args.append("--main-pkg-path");
if (self.main_mod_path) |dir| {
try zig_args.append("--main-mod-path");
try zig_args.append(dir.getPath(b));
}

Expand Down
33 changes: 30 additions & 3 deletions lib/std/array_hash_map.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1229,14 +1229,41 @@ pub fn ArrayHashMapUnmanaged(
/// Sorts the entries and then rebuilds the index.
/// `sort_ctx` must have this method:
/// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool`
/// Uses a stable sorting algorithm.
pub inline fn sort(self: *Self, sort_ctx: anytype) void {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call sortContext instead.");
return self.sortContext(sort_ctx, undefined);
return sortContextInternal(self, .stable, sort_ctx, undefined);
}

pub fn sortContext(self: *Self, sort_ctx: anytype, ctx: Context) void {
self.entries.sort(sort_ctx);
/// Sorts the entries and then rebuilds the index.
/// `sort_ctx` must have this method:
/// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool`
/// Uses an unstable sorting algorithm.
pub inline fn sortUnstable(self: *Self, sort_ctx: anytype) void {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call sortUnstableContext instead.");
return self.sortContextInternal(.unstable, sort_ctx, undefined);
}

pub inline fn sortContext(self: *Self, sort_ctx: anytype, ctx: Context) void {
return sortContextInternal(self, .stable, sort_ctx, ctx);
}

pub inline fn sortUnstableContext(self: *Self, sort_ctx: anytype, ctx: Context) void {
return sortContextInternal(self, .unstable, sort_ctx, ctx);
}

fn sortContextInternal(
self: *Self,
comptime mode: std.sort.Mode,
sort_ctx: anytype,
ctx: Context,
) void {
switch (mode) {
.stable => self.entries.sort(sort_ctx),
.unstable => self.entries.sortUnstable(sort_ctx),
}
const header = self.index_header orelse return;
header.reset();
self.insertAllEntriesIntoNewHeader(if (store_hash) {} else ctx, header);
Expand Down
8 changes: 5 additions & 3 deletions lib/std/fs/path.zig
Original file line number Diff line number Diff line change
Expand Up @@ -728,15 +728,17 @@ pub fn resolvePosix(allocator: Allocator, paths: []const []const u8) Allocator.E
}
}

test "resolve" {
test resolve {
try testResolveWindows(&[_][]const u8{ "a\\b\\c\\", "..\\..\\.." }, ".");
try testResolveWindows(&[_][]const u8{"."}, ".");
try testResolveWindows(&[_][]const u8{""}, ".");

try testResolvePosix(&[_][]const u8{ "a/b/c/", "../../.." }, ".");
try testResolvePosix(&[_][]const u8{"."}, ".");
try testResolvePosix(&[_][]const u8{""}, ".");
}

test "resolveWindows" {
test resolveWindows {
try testResolveWindows(
&[_][]const u8{ "Z:\\", "/usr/local", "lib\\zig\\std\\array_list.zig" },
"Z:\\usr\\local\\lib\\zig\\std\\array_list.zig",
Expand Down Expand Up @@ -764,7 +766,7 @@ test "resolveWindows" {
try testResolveWindows(&[_][]const u8{"a/b"}, "a\\b");
}

test "resolvePosix" {
test resolvePosix {
try testResolvePosix(&.{ "/a/b", "c" }, "/a/b/c");
try testResolvePosix(&.{ "/a/b", "c", "//d", "e///" }, "/d/e");
try testResolvePosix(&.{ "/a/b/c", "..", "../" }, "/a");
Expand Down
2 changes: 1 addition & 1 deletion lib/std/multi_array_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ pub fn MultiArrayList(comptime T: type) type {

/// `ctx` has the following method:
/// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool`
fn sortInternal(self: Self, a: usize, b: usize, ctx: anytype, comptime mode: enum { stable, unstable }) void {
fn sortInternal(self: Self, a: usize, b: usize, ctx: anytype, comptime mode: std.sort.Mode) void {
const sort_context: struct {
sub_ctx: @TypeOf(ctx),
slice: Slice,
Expand Down
2 changes: 1 addition & 1 deletion lib/std/process.zig
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn getCwdAlloc(allocator: Allocator) ![]u8 {
}
}

test "getCwdAlloc" {
test getCwdAlloc {
if (builtin.os.tag == .wasi) return error.SkipZigTest;

const cwd = try getCwdAlloc(testing.allocator);
Expand Down
2 changes: 2 additions & 0 deletions lib/std/sort.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const testing = std.testing;
const mem = std.mem;
const math = std.math;

pub const Mode = enum { stable, unstable };

pub const block = @import("sort/block.zig").block;
pub const pdq = @import("sort/pdq.zig").pdq;
pub const pdqContext = @import("sort/pdq.zig").pdqContext;
Expand Down
Loading