aboutsummaryrefslogtreecommitdiff
path: root/lib/std/Build.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-02-04 14:17:47 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-02-04 14:17:47 -0700
commit09cee1d5e34dd4187242a693c2d7b5a9d1e689b1 (patch)
tree70be147cdf59171bda9079abb3c5fe318ffad72b /lib/std/Build.zig
parentfab9b7110ed1fa7bb082aad5e095047441db2b24 (diff)
parentb7c96c3bbdc0e2172cf9edb0c9c7c52f86c2311e (diff)
downloadzig-09cee1d5e34dd4187242a693c2d7b5a9d1e689b1.tar.gz
zig-09cee1d5e34dd4187242a693c2d7b5a9d1e689b1.zip
Merge remote-tracking branch 'origin/master' into llvm16
Diffstat (limited to 'lib/std/Build.zig')
-rw-r--r--lib/std/Build.zig130
1 files changed, 60 insertions, 70 deletions
diff --git a/lib/std/Build.zig b/lib/std/Build.zig
index 6846007443..15c1647957 100644
--- a/lib/std/Build.zig
+++ b/lib/std/Build.zig
@@ -109,6 +109,8 @@ host: NativeTargetInfo,
dep_prefix: []const u8 = "",
+modules: std.StringArrayHashMap(*Module),
+
pub const ExecError = error{
ReadFailure,
ExitCodeFailure,
@@ -232,6 +234,7 @@ pub fn create(
.install_path = undefined,
.args = null,
.host = host,
+ .modules = std.StringArrayHashMap(*Module).init(allocator),
};
try self.top_level_steps.append(&self.install_tls);
try self.top_level_steps.append(&self.uninstall_tls);
@@ -305,6 +308,7 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: []const u8)
.glibc_runtimes_dir = parent.glibc_runtimes_dir,
.host = parent.host,
.dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }),
+ .modules = std.StringArrayHashMap(*Module).init(allocator),
};
try child.top_level_steps.append(&child.install_tls);
try child.top_level_steps.append(&child.uninstall_tls);
@@ -539,6 +543,49 @@ pub fn addAssembly(b: *Build, options: AssemblyOptions) *CompileStep {
return obj_step;
}
+pub const AddModuleOptions = struct {
+ name: []const u8,
+ source_file: FileSource,
+ dependencies: []const ModuleDependency = &.{},
+};
+
+pub fn addModule(b: *Build, options: AddModuleOptions) void {
+ b.modules.put(b.dupe(options.name), b.createModule(.{
+ .source_file = options.source_file,
+ .dependencies = options.dependencies,
+ })) catch @panic("OOM");
+}
+
+pub const ModuleDependency = struct {
+ name: []const u8,
+ module: *Module,
+};
+
+pub const CreateModuleOptions = struct {
+ source_file: FileSource,
+ dependencies: []const ModuleDependency = &.{},
+};
+
+/// Prefer to use `addModule` which will make the module available to other
+/// packages which depend on this package.
+pub fn createModule(b: *Build, options: CreateModuleOptions) *Module {
+ const module = b.allocator.create(Module) catch @panic("OOM");
+ module.* = .{
+ .builder = b,
+ .source_file = options.source_file,
+ .dependencies = moduleDependenciesToArrayHashMap(b.allocator, options.dependencies),
+ };
+ return module;
+}
+
+fn moduleDependenciesToArrayHashMap(arena: Allocator, deps: []const ModuleDependency) std.StringArrayHashMap(*Module) {
+ var result = std.StringArrayHashMap(*Module).init(arena);
+ for (deps) |dep| {
+ result.put(dep.name, dep.module) catch @panic("OOM");
+ }
+ return result;
+}
+
/// Initializes a RunStep with argv, which must at least have the path to the
/// executable. More command line arguments can be added with `addArg`,
/// `addArgs`, and `addArtifactArg`.
@@ -588,24 +635,6 @@ pub fn dupePath(self: *Build, bytes: []const u8) []u8 {
return the_copy;
}
-/// Duplicates a package recursively.
-pub fn dupePkg(self: *Build, package: Pkg) Pkg {
- var the_copy = Pkg{
- .name = self.dupe(package.name),
- .source = package.source.dupe(self),
- };
-
- if (package.dependencies) |dependencies| {
- const new_dependencies = self.allocator.alloc(Pkg, dependencies.len) catch @panic("OOM");
- the_copy.dependencies = new_dependencies;
-
- for (dependencies) |dep_package, i| {
- new_dependencies[i] = self.dupePkg(dep_package);
- }
- }
- return the_copy;
-}
-
pub fn addWriteFile(self: *Build, file_path: []const u8, data: []const u8) *WriteFileStep {
const write_file_step = self.addWriteFiles();
write_file_step.add(file_path, data);
@@ -1479,6 +1508,12 @@ pub const Dependency = struct {
panic("unable to find artifact '{s}'", .{name});
};
}
+
+ pub fn module(d: *Dependency, name: []const u8) *Module {
+ return d.builder.modules.get(name) orelse {
+ panic("unable to find module '{s}'", .{name});
+ };
+ }
};
pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency {
@@ -1548,10 +1583,13 @@ test "builder.findProgram compiles" {
_ = builder.findProgram(&[_][]const u8{}, &[_][]const u8{}) catch null;
}
-pub const Pkg = struct {
- name: []const u8,
- source: FileSource,
- dependencies: ?[]const Pkg = null,
+pub const Module = struct {
+ builder: *Build,
+ /// This could either be a generated file, in which case the module
+ /// contains exactly one file, or it could be a path to the root source
+ /// file of directory of files which constitute the module.
+ source_file: FileSource,
+ dependencies: std.StringArrayHashMap(*Module),
};
/// A file that is generated by a build step.
@@ -1713,54 +1751,6 @@ pub fn serializeCpu(allocator: Allocator, cpu: std.Target.Cpu) ![]const u8 {
}
}
-test "dupePkg()" {
- if (builtin.os.tag == .wasi) return error.SkipZigTest;
-
- var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
- defer arena.deinit();
-
- const host = try NativeTargetInfo.detect(.{});
-
- var builder = try Build.create(
- arena.allocator(),
- "test",
- "test",
- "test",
- "test",
- host,
- );
- defer builder.destroy();
-
- var pkg_dep = Pkg{
- .name = "pkg_dep",
- .source = .{ .path = "/not/a/pkg_dep.zig" },
- };
- var pkg_top = Pkg{
- .name = "pkg_top",
- .source = .{ .path = "/not/a/pkg_top.zig" },
- .dependencies = &[_]Pkg{pkg_dep},
- };
- const duped = builder.dupePkg(pkg_top);
-
- const original_deps = pkg_top.dependencies.?;
- const dupe_deps = duped.dependencies.?;
-
- // probably the same top level package details
- try std.testing.expectEqualStrings(pkg_top.name, duped.name);
-
- // probably the same dependencies
- try std.testing.expectEqual(original_deps.len, dupe_deps.len);
- try std.testing.expectEqual(original_deps[0].name, pkg_dep.name);
-
- // could segfault otherwise if pointers in duplicated package's fields are
- // the same as those in stack allocated package's fields
- try std.testing.expect(dupe_deps.ptr != original_deps.ptr);
- try std.testing.expect(duped.name.ptr != pkg_top.name.ptr);
- try std.testing.expect(duped.source.path.ptr != pkg_top.source.path.ptr);
- try std.testing.expect(dupe_deps[0].name.ptr != pkg_dep.name.ptr);
- try std.testing.expect(dupe_deps[0].source.path.ptr != pkg_dep.source.path.ptr);
-}
-
test {
_ = CheckFileStep;
_ = CheckObjectStep;