Commit 105db13536
Changed files (15)
deps
aro
build
lib
deps/aro/build/GenerateDef.zig
@@ -53,7 +53,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
const self = @fieldParentPtr(GenerateDef, "step", step);
const arena = b.allocator;
- var man = b.cache.obtain();
+ var man = b.graph.cache.obtain();
defer man.deinit();
// Random bytes to make GenerateDef unique. Refresh this with new
lib/std/Build/Step/Compile.zig
@@ -923,7 +923,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
var zig_args = ArrayList([]const u8).init(arena);
defer zig_args.deinit();
- try zig_args.append(b.zig_exe);
+ try zig_args.append(b.graph.zig_exe);
const cmd = switch (self.kind) {
.lib => "build-lib",
@@ -933,6 +933,16 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
};
try zig_args.append(cmd);
+ if (!mem.eql(u8, b.graph.host_query_options.arch_os_abi, "native")) {
+ try zig_args.appendSlice(&.{ "--host-target", b.graph.host_query_options.arch_os_abi });
+ }
+ if (b.graph.host_query_options.cpu_features) |cpu| {
+ try zig_args.appendSlice(&.{ "--host-cpu", cpu });
+ }
+ if (b.graph.host_query_options.dynamic_linker) |dl| {
+ try zig_args.appendSlice(&.{ "--host-dynamic-linker", dl });
+ }
+
if (b.reference_trace) |some| {
try zig_args.append(try std.fmt.allocPrint(arena, "-freference-trace={d}", .{some}));
}
@@ -1393,7 +1403,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try zig_args.append(b.cache_root.path orelse ".");
try zig_args.append("--global-cache-dir");
- try zig_args.append(b.global_cache_root.path orelse ".");
+ try zig_args.append(b.graph.global_cache_root.path orelse ".");
try zig_args.append("--name");
try zig_args.append(self.name);
lib/std/Build/Step/ConfigHeader.zig
@@ -171,7 +171,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
const gpa = b.allocator;
const arena = b.allocator;
- var man = b.cache.obtain();
+ var man = b.graph.cache.obtain();
defer man.deinit();
// Random bytes to make ConfigHeader unique. Refresh this with new
lib/std/Build/Step/Fmt.zig
@@ -52,7 +52,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
var argv: std.ArrayListUnmanaged([]const u8) = .{};
try argv.ensureUnusedCapacity(arena, 2 + 1 + self.paths.len + 2 * self.exclude_paths.len);
- argv.appendAssumeCapacity(b.zig_exe);
+ argv.appendAssumeCapacity(b.graph.zig_exe);
argv.appendAssumeCapacity("fmt");
if (self.check) {
lib/std/Build/Step/ObjCopy.zig
@@ -94,7 +94,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
const b = step.owner;
const self = @fieldParentPtr(ObjCopy, "step", step);
- var man = b.cache.obtain();
+ var man = b.graph.cache.obtain();
defer man.deinit();
// Random bytes to make ObjCopy unique. Refresh this with new random
@@ -133,7 +133,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
};
var argv = std.ArrayList([]const u8).init(b.allocator);
- try argv.appendSlice(&.{ b.zig_exe, "objcopy" });
+ try argv.appendSlice(&.{ b.graph.zig_exe, "objcopy" });
if (self.only_section) |only_section| {
try argv.appendSlice(&.{ "-j", only_section });
lib/std/Build/Step/Options.zig
@@ -222,7 +222,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
const basename = "options.zig";
// Hash contents to file name.
- var hash = b.cache.hash;
+ var hash = b.graph.cache.hash;
// Random bytes to make unique. Refresh this with new random bytes when
// implementation is modified in a non-backwards-compatible way.
hash.add(@as(u32, 0xad95e922));
@@ -301,27 +301,28 @@ test Options {
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
- const host: std.Build.ResolvedTarget = .{
- .query = .{},
- .result = try std.zig.system.resolveTargetQuery(.{}),
- };
-
- var cache: std.Build.Cache = .{
- .gpa = arena.allocator(),
- .manifest_dir = std.fs.cwd(),
+ var graph: std.Build.Graph = .{
+ .arena = arena.allocator(),
+ .cache = .{
+ .gpa = arena.allocator(),
+ .manifest_dir = std.fs.cwd(),
+ },
+ .zig_exe = "test",
+ .env_map = std.process.EnvMap.init(arena.allocator()),
+ .global_cache_root = .{ .path = "test", .handle = std.fs.cwd() },
};
var builder = try std.Build.create(
- arena.allocator(),
- "test",
+ &graph,
.{ .path = "test", .handle = std.fs.cwd() },
.{ .path = "test", .handle = std.fs.cwd() },
- .{ .path = "test", .handle = std.fs.cwd() },
- host,
- &cache,
&.{},
);
- defer builder.destroy();
+
+ builder.host = .{
+ .query = .{},
+ .result = try std.zig.system.resolveTargetQuery(.{}),
+ };
const options = builder.addOptions();
lib/std/Build/Step/Run.zig
@@ -463,7 +463,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
var argv_list = ArrayList([]const u8).init(arena);
var output_placeholders = ArrayList(IndexedOutput).init(arena);
- var man = b.cache.obtain();
+ var man = b.graph.cache.obtain();
defer man.deinit();
for (self.argv.items) |arg| {
@@ -747,7 +747,7 @@ fn runCommand(
exe.is_linking_libc;
const other_target = exe.root_module.resolved_target.?.result;
switch (std.zig.system.getExternalExecutor(b.host.result, &other_target, .{
- .qemu_fixes_dl = need_cross_glibc and b.glibc_runtimes_dir != null,
+ .qemu_fixes_dl = need_cross_glibc and b.graph.glibc_runtimes_dir != null,
.link_libc = exe.is_linking_libc,
})) {
.native, .rosetta => {
@@ -755,7 +755,7 @@ fn runCommand(
break :interpret;
},
.wine => |bin_name| {
- if (b.enable_wine) {
+ if (b.graph.enable_wine) {
try interp_argv.append(bin_name);
try interp_argv.appendSlice(argv);
} else {
@@ -763,9 +763,9 @@ fn runCommand(
}
},
.qemu => |bin_name| {
- if (b.enable_qemu) {
+ if (b.graph.enable_qemu) {
const glibc_dir_arg = if (need_cross_glibc)
- b.glibc_runtimes_dir orelse
+ b.graph.glibc_runtimes_dir orelse
return failForeign(self, "--glibc-runtimes", argv[0], exe)
else
null;
@@ -798,7 +798,7 @@ fn runCommand(
}
},
.darling => |bin_name| {
- if (b.enable_darling) {
+ if (b.graph.enable_darling) {
try interp_argv.append(bin_name);
try interp_argv.appendSlice(argv);
} else {
@@ -806,7 +806,7 @@ fn runCommand(
}
},
.wasmtime => |bin_name| {
- if (b.enable_wasmtime) {
+ if (b.graph.enable_wasmtime) {
try interp_argv.append(bin_name);
try interp_argv.append("--dir=.");
try interp_argv.append(argv[0]);
@@ -1036,7 +1036,7 @@ fn spawnChildAndCollect(
child.cwd = b.build_root.path;
child.cwd_dir = b.build_root.handle;
}
- child.env_map = self.env_map orelse b.env_map;
+ child.env_map = self.env_map orelse &b.graph.env_map;
child.request_resource_usage_statistics = true;
child.stdin_behavior = switch (self.stdio) {
lib/std/Build/Step/TranslateC.zig
@@ -121,7 +121,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
const self = @fieldParentPtr(TranslateC, "step", step);
var argv_list = std.ArrayList([]const u8).init(b.allocator);
- try argv_list.append(b.zig_exe);
+ try argv_list.append(b.graph.zig_exe);
try argv_list.append("translate-c");
if (self.link_libc) {
try argv_list.append("-lc");
lib/std/Build/Step/WriteFile.zig
@@ -190,7 +190,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
// If, for example, a hard-coded path was used as the location to put WriteFile
// files, then two WriteFiles executing in parallel might clobber each other.
- var man = b.cache.obtain();
+ var man = b.graph.cache.obtain();
defer man.deinit();
// Random bytes to make WriteFile unique. Refresh this with
lib/std/Build/Step.zig
@@ -314,7 +314,7 @@ pub fn evalZigProcess(
try handleVerbose(s.owner, null, argv);
var child = std.ChildProcess.init(argv, arena);
- child.env_map = b.env_map;
+ child.env_map = &b.graph.env_map;
child.stdin_behavior = .Pipe;
child.stdout_behavior = .Pipe;
child.stderr_behavior = .Pipe;
lib/std/Build.zig
@@ -22,15 +22,14 @@ pub const Cache = @import("Build/Cache.zig");
pub const Step = @import("Build/Step.zig");
pub const Module = @import("Build/Module.zig");
+/// Shared state among all Build instances.
+graph: *Graph,
install_tls: TopLevelStep,
uninstall_tls: TopLevelStep,
allocator: Allocator,
user_input_options: UserInputOptionsMap,
available_options_map: AvailableOptionsMap,
available_options_list: ArrayList(AvailableOption),
-/// All Build instances share this hash map.
-system_library_options: *std.StringArrayHashMapUnmanaged(SystemLibraryMode),
-system_package_mode: bool,
verbose: bool,
verbose_link: bool,
verbose_cc: bool,
@@ -41,9 +40,7 @@ verbose_cimport: bool,
verbose_llvm_cpu_features: bool,
reference_trace: ?u32 = null,
invalid_user_input: bool,
-zig_exe: [:0]const u8,
default_step: *Step,
-env_map: *EnvMap,
top_level_steps: std.StringArrayHashMapUnmanaged(*TopLevelStep),
install_prefix: []const u8,
dest_dir: ?[]const u8,
@@ -52,14 +49,12 @@ exe_dir: []const u8,
h_dir: []const u8,
install_path: []const u8,
sysroot: ?[]const u8 = null,
-search_prefixes: ArrayList([]const u8),
+search_prefixes: std.ArrayListUnmanaged([]const u8),
libc_file: ?[]const u8 = null,
installed_files: ArrayList(InstalledFile),
/// Path to the directory containing build.zig.
build_root: Cache.Directory,
cache_root: Cache.Directory,
-global_cache_root: Cache.Directory,
-cache: *Cache,
zig_lib_dir: ?LazyPath,
pkg_config_pkg_list: ?(PkgConfigError![]const PkgConfigPkg) = null,
args: ?[][]const u8 = null,
@@ -71,22 +66,6 @@ debug_pkg_config: bool = false,
/// Set to 0 to disable stack collection.
debug_stack_frames_count: u8 = 8,
-/// Experimental. Use system Darling installation to run cross compiled macOS build artifacts.
-enable_darling: bool = false,
-/// Use system QEMU installation to run cross compiled foreign architecture build artifacts.
-enable_qemu: bool = false,
-/// Darwin. Use Rosetta to run x86_64 macOS build artifacts on arm64 macOS.
-enable_rosetta: bool = false,
-/// Use system Wasmtime installation to run cross compiled wasm/wasi build artifacts.
-enable_wasmtime: bool = false,
-/// Use system Wine installation to run cross compiled Windows build artifacts.
-enable_wine: bool = false,
-/// After following the steps in https://github.com/ziglang/zig/wiki/Updating-libc#glibc,
-/// this will be the directory $glibc-build-dir/install/glibcs
-/// Given the example of the aarch64 target, this is the directory
-/// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`.
-glibc_runtimes_dir: ?[]const u8 = null,
-
/// Information about the native target. Computed before build() is invoked.
host: ResolvedTarget,
@@ -101,9 +80,38 @@ initialized_deps: *InitializedDepMap,
/// A mapping from dependency names to package hashes.
available_deps: AvailableDeps,
+/// Shared state among all Build instances.
+/// Settings that are here rather than in Build are not configurable per-package.
+pub const Graph = struct {
+ arena: Allocator,
+ system_library_options: std.StringArrayHashMapUnmanaged(SystemLibraryMode) = .{},
+ system_package_mode: bool = false,
+ cache: Cache,
+ zig_exe: [:0]const u8,
+ env_map: EnvMap,
+ global_cache_root: Cache.Directory,
+ host_query_options: std.Target.Query.ParseOptions = .{},
+
+ /// Experimental. Use system Darling installation to run cross compiled macOS build artifacts.
+ enable_darling: bool = false,
+ /// Use system QEMU installation to run cross compiled foreign architecture build artifacts.
+ enable_qemu: bool = false,
+ /// Darwin. Use Rosetta to run x86_64 macOS build artifacts on arm64 macOS.
+ enable_rosetta: bool = false,
+ /// Use system Wasmtime installation to run cross compiled wasm/wasi build artifacts.
+ enable_wasmtime: bool = false,
+ /// Use system Wine installation to run cross compiled Windows build artifacts.
+ enable_wine: bool = false,
+ /// After following the steps in https://github.com/ziglang/zig/wiki/Updating-libc#glibc,
+ /// this will be the directory $glibc-build-dir/install/glibcs
+ /// Given the example of the aarch64 target, this is the directory
+ /// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`.
+ glibc_runtimes_dir: ?[]const u8 = null,
+};
+
const AvailableDeps = []const struct { []const u8, []const u8 };
-pub const SystemLibraryMode = enum {
+const SystemLibraryMode = enum {
/// User asked for the library to be disabled.
/// The build runner has not confirmed whether the setting is recognized yet.
user_disabled,
@@ -226,29 +234,20 @@ pub const DirList = struct {
};
pub fn create(
- allocator: Allocator,
- zig_exe: [:0]const u8,
+ graph: *Graph,
build_root: Cache.Directory,
cache_root: Cache.Directory,
- global_cache_root: Cache.Directory,
- host: ResolvedTarget,
- cache: *Cache,
available_deps: AvailableDeps,
- system_library_options: *std.StringArrayHashMapUnmanaged(SystemLibraryMode),
) !*Build {
- const env_map = try allocator.create(EnvMap);
- env_map.* = try process.getEnvMap(allocator);
+ const arena = graph.arena;
+ const initialized_deps = try arena.create(InitializedDepMap);
+ initialized_deps.* = InitializedDepMap.initContext(arena, .{ .allocator = arena });
- const initialized_deps = try allocator.create(InitializedDepMap);
- initialized_deps.* = InitializedDepMap.initContext(allocator, .{ .allocator = allocator });
-
- const self = try allocator.create(Build);
+ const self = try arena.create(Build);
self.* = .{
- .zig_exe = zig_exe,
+ .graph = graph,
.build_root = build_root,
.cache_root = cache_root,
- .global_cache_root = global_cache_root,
- .cache = cache,
.verbose = false,
.verbose_link = false,
.verbose_cc = false,
@@ -258,20 +257,19 @@ pub fn create(
.verbose_cimport = false,
.verbose_llvm_cpu_features = false,
.invalid_user_input = false,
- .allocator = allocator,
- .user_input_options = UserInputOptionsMap.init(allocator),
- .available_options_map = AvailableOptionsMap.init(allocator),
- .available_options_list = ArrayList(AvailableOption).init(allocator),
+ .allocator = arena,
+ .user_input_options = UserInputOptionsMap.init(arena),
+ .available_options_map = AvailableOptionsMap.init(arena),
+ .available_options_list = ArrayList(AvailableOption).init(arena),
.top_level_steps = .{},
.default_step = undefined,
- .env_map = env_map,
- .search_prefixes = ArrayList([]const u8).init(allocator),
+ .search_prefixes = .{},
.install_prefix = undefined,
.lib_dir = undefined,
.exe_dir = undefined,
.h_dir = undefined,
- .dest_dir = env_map.get("DESTDIR"),
- .installed_files = ArrayList(InstalledFile).init(allocator),
+ .dest_dir = graph.env_map.get("DESTDIR"),
+ .installed_files = ArrayList(InstalledFile).init(arena),
.install_tls = .{
.step = Step.init(.{
.id = .top_level,
@@ -292,16 +290,14 @@ pub fn create(
.zig_lib_dir = null,
.install_path = undefined,
.args = null,
- .host = host,
- .modules = std.StringArrayHashMap(*Module).init(allocator),
- .named_writefiles = std.StringArrayHashMap(*Step.WriteFile).init(allocator),
+ .host = undefined,
+ .modules = std.StringArrayHashMap(*Module).init(arena),
+ .named_writefiles = std.StringArrayHashMap(*Step.WriteFile).init(arena),
.initialized_deps = initialized_deps,
.available_deps = available_deps,
- .system_library_options = system_library_options,
- .system_package_mode = false,
};
- try self.top_level_steps.put(allocator, self.install_tls.step.name, &self.install_tls);
- try self.top_level_steps.put(allocator, self.uninstall_tls.step.name, &self.uninstall_tls);
+ try self.top_level_steps.put(arena, self.install_tls.step.name, &self.install_tls);
+ try self.top_level_steps.put(arena, self.uninstall_tls.step.name, &self.uninstall_tls);
self.default_step = &self.install_tls.step;
return self;
}
@@ -328,6 +324,7 @@ fn createChildOnly(
const allocator = parent.allocator;
const child = try allocator.create(Build);
child.* = .{
+ .graph = parent.graph,
.allocator = allocator,
.install_tls = .{
.step = Step.init(.{
@@ -359,9 +356,7 @@ fn createChildOnly(
.verbose_llvm_cpu_features = parent.verbose_llvm_cpu_features,
.reference_trace = parent.reference_trace,
.invalid_user_input = false,
- .zig_exe = parent.zig_exe,
.default_step = undefined,
- .env_map = parent.env_map,
.top_level_steps = .{},
.install_prefix = undefined,
.dest_dir = parent.dest_dir,
@@ -375,26 +370,16 @@ fn createChildOnly(
.installed_files = ArrayList(InstalledFile).init(allocator),
.build_root = build_root,
.cache_root = parent.cache_root,
- .global_cache_root = parent.global_cache_root,
- .cache = parent.cache,
.zig_lib_dir = parent.zig_lib_dir,
.debug_log_scopes = parent.debug_log_scopes,
.debug_compile_errors = parent.debug_compile_errors,
.debug_pkg_config = parent.debug_pkg_config,
- .enable_darling = parent.enable_darling,
- .enable_qemu = parent.enable_qemu,
- .enable_rosetta = parent.enable_rosetta,
- .enable_wasmtime = parent.enable_wasmtime,
- .enable_wine = parent.enable_wine,
- .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),
.named_writefiles = std.StringArrayHashMap(*Step.WriteFile).init(allocator),
.initialized_deps = parent.initialized_deps,
.available_deps = pkg_deps,
- .system_library_options = parent.system_library_options,
- .system_package_mode = parent.system_package_mode,
};
try child.top_level_steps.put(allocator, child.install_tls.step.name, &child.install_tls);
try child.top_level_steps.put(allocator, child.uninstall_tls.step.name, &child.uninstall_tls);
@@ -572,7 +557,7 @@ fn hashUserInputOptionsMap(allocator: Allocator, user_input_options: UserInputOp
fn determineAndApplyInstallPrefix(b: *Build) !void {
// Create an installation directory local to this package. This will be used when
// dependant packages require a standard prefix, such as include directories for C headers.
- var hash = b.cache.hash;
+ var hash = b.graph.cache.hash;
// Random bytes to make unique. Refresh this with new random bytes when
// implementation is modified in a non-backwards-compatible way.
hash.add(@as(u32, 0xd8cb0055));
@@ -587,12 +572,6 @@ fn determineAndApplyInstallPrefix(b: *Build) !void {
b.resolveInstallPrefix(install_prefix, .{});
}
-pub fn destroy(b: *Build) void {
- b.env_map.deinit();
- b.top_level_steps.deinit(b.allocator);
- b.allocator.destroy(b);
-}
-
/// This function is intended to be called by lib/build_runner.zig, not a build.zig file.
pub fn resolveInstallPrefix(self: *Build, install_prefix: ?[]const u8, dir_list: DirList) void {
if (self.dest_dir) |dest_dir| {
@@ -1273,67 +1252,83 @@ pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) Resolve
return b.resolveTargetQuery(query);
}
-/// Exposes standard `zig build` options for choosing a target.
-pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs) Target.Query {
- const maybe_triple = b.option(
- []const u8,
- "target",
- "The CPU architecture, OS, and ABI to build for",
- );
- const mcpu = b.option([]const u8, "cpu", "Target CPU features to add or subtract");
-
- if (maybe_triple == null and mcpu == null) {
- return args.default_target;
- }
-
- const triple = maybe_triple orelse "native";
-
+pub fn parseTargetQuery(options: std.Target.Query.ParseOptions) error{ParseFailed}!std.Target.Query {
var diags: Target.Query.ParseOptions.Diagnostics = .{};
- const selected_target = Target.Query.parse(.{
- .arch_os_abi = triple,
- .cpu_features = mcpu,
- .diagnostics = &diags,
- }) catch |err| switch (err) {
+ var opts_copy = options;
+ opts_copy.diagnostics = &diags;
+ return std.Target.Query.parse(options) catch |err| switch (err) {
error.UnknownCpuModel => {
- log.err("Unknown CPU: '{s}'\nAvailable CPUs for architecture '{s}':", .{
- diags.cpu_name.?,
- @tagName(diags.arch.?),
+ std.debug.print("unknown CPU: '{s}'\navailable CPUs for architecture '{s}':\n", .{
+ diags.cpu_name.?, @tagName(diags.arch.?),
});
for (diags.arch.?.allCpuModels()) |cpu| {
- log.err(" {s}", .{cpu.name});
+ std.debug.print(" {s}\n", .{cpu.name});
}
- b.markInvalidUserInput();
- return args.default_target;
+ return error.ParseFailed;
},
error.UnknownCpuFeature => {
- log.err(
- \\Unknown CPU feature: '{s}'
- \\Available CPU features for architecture '{s}':
+ std.debug.print(
+ \\unknown CPU feature: '{s}'
+ \\available CPU features for architecture '{s}':
\\
, .{
diags.unknown_feature_name.?,
@tagName(diags.arch.?),
});
for (diags.arch.?.allFeaturesList()) |feature| {
- log.err(" {s}: {s}", .{ feature.name, feature.description });
+ std.debug.print(" {s}: {s}\n", .{ feature.name, feature.description });
}
- b.markInvalidUserInput();
- return args.default_target;
+ return error.ParseFailed;
},
error.UnknownOperatingSystem => {
- log.err(
- \\Unknown OS: '{s}'
- \\Available operating systems:
+ std.debug.print(
+ \\unknown OS: '{s}'
+ \\available operating systems:
\\
, .{diags.os_name.?});
inline for (std.meta.fields(Target.Os.Tag)) |field| {
- log.err(" {s}", .{field.name});
+ std.debug.print(" {s}\n", .{field.name});
}
- b.markInvalidUserInput();
- return args.default_target;
+ return error.ParseFailed;
},
else => |e| {
- log.err("Unable to parse target '{s}': {s}\n", .{ triple, @errorName(e) });
+ std.debug.print("unable to parse target '{s}': {s}\n", .{
+ options.arch_os_abi, @errorName(e),
+ });
+ return error.ParseFailed;
+ },
+ };
+}
+
+/// Exposes standard `zig build` options for choosing a target.
+pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs) Target.Query {
+ const maybe_triple = b.option(
+ []const u8,
+ "target",
+ "The CPU architecture, OS, and ABI to build for",
+ );
+ const mcpu = b.option(
+ []const u8,
+ "cpu",
+ "Target CPU features to add or subtract",
+ );
+ const dynamic_linker = b.option(
+ []const u8,
+ "dynamic-linker",
+ "Path to interpreter on the target system",
+ );
+
+ if (maybe_triple == null and mcpu == null and dynamic_linker == null)
+ return args.default_target;
+
+ const triple = maybe_triple orelse "native";
+
+ const selected_target = parseTargetQuery(.{
+ .arch_os_abi = triple,
+ .cpu_features = mcpu,
+ .dynamic_linker = dynamic_linker,
+ }) catch |err| switch (err) {
+ error.ParseFailed => {
b.markInvalidUserInput();
return args.default_target;
},
@@ -1622,7 +1617,7 @@ pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []con
return fs.realpathAlloc(self.allocator, full_path) catch continue;
}
}
- if (self.env_map.get("PATH")) |PATH| {
+ if (self.graph.env_map.get("PATH")) |PATH| {
for (names) |name| {
if (fs.path.isAbsolute(name)) {
return name;
@@ -1668,7 +1663,7 @@ pub fn runAllowFail(
child.stdin_behavior = .Ignore;
child.stdout_behavior = .Pipe;
child.stderr_behavior = stderr_behavior;
- child.env_map = self.env_map;
+ child.env_map = &self.graph.env_map;
try child.spawn();
@@ -1714,8 +1709,8 @@ pub fn run(b: *Build, argv: []const []const u8) []u8 {
};
}
-pub fn addSearchPrefix(self: *Build, search_prefix: []const u8) void {
- self.search_prefixes.append(self.dupePath(search_prefix)) catch @panic("OOM");
+pub fn addSearchPrefix(b: *Build, search_prefix: []const u8) void {
+ b.search_prefixes.append(b.allocator, b.dupePath(search_prefix)) catch @panic("OOM");
}
pub fn getInstallPath(self: *Build, dir: InstallDir, dest_rel_path: []const u8) []const u8 {
@@ -2310,9 +2305,7 @@ pub const ResolvedTarget = struct {
/// Converts a target query into a fully resolved target that can be passed to
/// various parts of the API.
pub fn resolveTargetQuery(b: *Build, query: Target.Query) ResolvedTarget {
- // This context will likely be required in the future when the target is
- // resolved via a WASI API or via the build protocol.
- _ = b;
+ if (query.isNative()) return b.host;
return .{
.query = query,
@@ -2326,7 +2319,7 @@ pub fn wantSharedLibSymLinks(target: Target) bool {
}
pub fn systemLibraryOption(b: *Build, name: []const u8) bool {
- const gop = b.system_library_options.getOrPut(b.allocator, name) catch @panic("OOM");
+ const gop = b.graph.system_library_options.getOrPut(b.allocator, name) catch @panic("OOM");
if (gop.found_existing) switch (gop.value_ptr.*) {
.user_disabled => {
gop.value_ptr.* = .declared_disabled;
@@ -2340,7 +2333,7 @@ pub fn systemLibraryOption(b: *Build, name: []const u8) bool {
.declared_enabled => return true,
} else {
gop.key_ptr.* = b.dupe(name);
- if (b.system_package_mode) {
+ if (b.graph.system_package_mode) {
gop.value_ptr.* = .declared_enabled;
return true;
} else {
lib/build_runner.zig
@@ -46,11 +46,6 @@ pub fn main() !void {
return error.InvalidArgs;
};
- const host: std.Build.ResolvedTarget = .{
- .query = .{},
- .result = try std.zig.system.resolveTargetQuery(.{}),
- };
-
const build_root_directory: std.Build.Cache.Directory = .{
.path = build_root,
.handle = try std.fs.cwd().openDir(build_root, .{}),
@@ -66,28 +61,28 @@ pub fn main() !void {
.handle = try std.fs.cwd().makeOpenPath(global_cache_root, .{}),
};
- var cache: std.Build.Cache = .{
- .gpa = arena,
- .manifest_dir = try local_cache_directory.handle.makeOpenPath("h", .{}),
+ var graph: std.Build.Graph = .{
+ .arena = arena,
+ .cache = .{
+ .gpa = arena,
+ .manifest_dir = try local_cache_directory.handle.makeOpenPath("h", .{}),
+ },
+ .zig_exe = zig_exe,
+ .env_map = try process.getEnvMap(arena),
+ .global_cache_root = global_cache_directory,
};
- cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() });
- cache.addPrefix(build_root_directory);
- cache.addPrefix(local_cache_directory);
- cache.addPrefix(global_cache_directory);
- cache.hash.addBytes(builtin.zig_version_string);
- var system_library_options: std.StringArrayHashMapUnmanaged(std.Build.SystemLibraryMode) = .{};
+ graph.cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() });
+ graph.cache.addPrefix(build_root_directory);
+ graph.cache.addPrefix(local_cache_directory);
+ graph.cache.addPrefix(global_cache_directory);
+ graph.cache.hash.addBytes(builtin.zig_version_string);
const builder = try std.Build.create(
- arena,
- zig_exe,
+ &graph,
build_root_directory,
local_cache_directory,
- global_cache_directory,
- host,
- &cache,
dependencies.root_deps,
- &system_library_options,
);
var targets = ArrayList([]const u8).init(arena);
@@ -132,10 +127,16 @@ pub fn main() !void {
steps_menu = true;
} else if (mem.eql(u8, arg, "--system-lib")) {
const name = nextArgOrFatal(args, &arg_idx);
- builder.system_library_options.put(arena, name, .user_enabled) catch @panic("OOM");
+ graph.system_library_options.put(arena, name, .user_enabled) catch @panic("OOM");
} else if (mem.eql(u8, arg, "--no-system-lib")) {
const name = nextArgOrFatal(args, &arg_idx);
- builder.system_library_options.put(arena, name, .user_disabled) catch @panic("OOM");
+ graph.system_library_options.put(arena, name, .user_disabled) catch @panic("OOM");
+ } else if (mem.eql(u8, arg, "--host-target")) {
+ graph.host_query_options.arch_os_abi = nextArgOrFatal(args, &arg_idx);
+ } else if (mem.eql(u8, arg, "--host-cpu")) {
+ graph.host_query_options.cpu_features = nextArgOrFatal(args, &arg_idx);
+ } else if (mem.eql(u8, arg, "--host-dynamic-linker")) {
+ graph.host_query_options.dynamic_linker = nextArgOrFatal(args, &arg_idx);
} else if (mem.eql(u8, arg, "--prefix-lib-dir")) {
dir_list.lib_dir = nextArgOrFatal(args, &arg_idx);
} else if (mem.eql(u8, arg, "--prefix-exe-dir")) {
@@ -193,7 +194,7 @@ pub fn main() !void {
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
builder.debug_compile_errors = true;
} else if (mem.eql(u8, arg, "--glibc-runtimes")) {
- builder.glibc_runtimes_dir = nextArgOrFatal(args, &arg_idx);
+ graph.glibc_runtimes_dir = nextArgOrFatal(args, &arg_idx);
} else if (mem.eql(u8, arg, "--verbose-link")) {
builder.verbose_link = true;
} else if (mem.eql(u8, arg, "--verbose-air")) {
@@ -213,25 +214,25 @@ pub fn main() !void {
} else if (mem.eql(u8, arg, "--prominent-compile-errors")) {
prominent_compile_errors = true;
} else if (mem.eql(u8, arg, "-fwine")) {
- builder.enable_wine = true;
+ graph.enable_wine = true;
} else if (mem.eql(u8, arg, "-fno-wine")) {
- builder.enable_wine = false;
+ graph.enable_wine = false;
} else if (mem.eql(u8, arg, "-fqemu")) {
- builder.enable_qemu = true;
+ graph.enable_qemu = true;
} else if (mem.eql(u8, arg, "-fno-qemu")) {
- builder.enable_qemu = false;
+ graph.enable_qemu = false;
} else if (mem.eql(u8, arg, "-fwasmtime")) {
- builder.enable_wasmtime = true;
+ graph.enable_wasmtime = true;
} else if (mem.eql(u8, arg, "-fno-wasmtime")) {
- builder.enable_wasmtime = false;
+ graph.enable_wasmtime = false;
} else if (mem.eql(u8, arg, "-frosetta")) {
- builder.enable_rosetta = true;
+ graph.enable_rosetta = true;
} else if (mem.eql(u8, arg, "-fno-rosetta")) {
- builder.enable_rosetta = false;
+ graph.enable_rosetta = false;
} else if (mem.eql(u8, arg, "-fdarling")) {
- builder.enable_darling = true;
+ graph.enable_darling = true;
} else if (mem.eql(u8, arg, "-fno-darling")) {
- builder.enable_darling = false;
+ graph.enable_darling = false;
} else if (mem.eql(u8, arg, "-freference-trace")) {
builder.reference_trace = 256;
} else if (mem.startsWith(u8, arg, "-freference-trace=")) {
@@ -266,11 +267,19 @@ pub fn main() !void {
}
}
+ const host_query = std.Build.parseTargetQuery(graph.host_query_options) catch |err| switch (err) {
+ error.ParseFailed => process.exit(1),
+ };
+ builder.host = .{
+ .query = .{},
+ .result = try std.zig.system.resolveTargetQuery(host_query),
+ };
+
const stderr = std.io.getStdErr();
const ttyconf = get_tty_conf(color, stderr);
switch (ttyconf) {
- .no_color => try builder.env_map.put("NO_COLOR", "1"),
- .escape_codes => try builder.env_map.put("YES_COLOR", "1"),
+ .no_color => try graph.env_map.put("NO_COLOR", "1"),
+ .escape_codes => try graph.env_map.put("YES_COLOR", "1"),
.windows_api => {},
}
@@ -1029,7 +1038,7 @@ fn usage(b: *std.Build, out_stream: anytype) !void {
\\
\\Steps:
\\
- , .{b.zig_exe});
+ , .{b.graph.zig_exe});
try steps(b, out_stream);
try out_stream.writeAll(
@@ -1104,22 +1113,23 @@ fn usage(b: *std.Build, out_stream: anytype) !void {
\\ --system [dir] System Package Mode. Disable fetching; prefer system libs
\\ --host-target [triple] Use the provided target as the host
\\ --host-cpu [cpu] Use the provided CPU as the host
+ \\ --host-dynamic-linker [path] Use the provided dynamic linker as the host
\\ --system-lib [name] Use the system-provided library
\\ --no-system-lib [name] Do not use the system-provided library
\\
\\ Available System Library Integrations: Enabled:
\\
);
- if (b.system_library_options.entries.len == 0) {
+ if (b.graph.system_library_options.entries.len == 0) {
try out_stream.writeAll(" (none) -\n");
} else {
- for (b.system_library_options.keys(), b.system_library_options.values()) |name, v| {
+ for (b.graph.system_library_options.keys(), b.graph.system_library_options.values()) |k, v| {
const status = switch (v) {
.declared_enabled => "yes",
.declared_disabled => "no",
.user_enabled, .user_disabled => unreachable, // already emitted error
};
- try out_stream.print(" {s:<43} {s}\n", .{ name, status });
+ try out_stream.print(" {s:<43} {s}\n", .{ k, status });
}
}
@@ -1203,7 +1213,7 @@ fn fatal(comptime f: []const u8, args: anytype) noreturn {
fn validateSystemLibraryOptions(b: *std.Build) void {
var bad = false;
- for (b.system_library_options.keys(), b.system_library_options.values()) |k, v| {
+ for (b.graph.system_library_options.keys(), b.graph.system_library_options.values()) |k, v| {
switch (v) {
.user_disabled, .user_enabled => {
// The user tried to enable or disable a system library integration, but
test/src/Cases.zig
@@ -562,7 +562,7 @@ pub fn lowerToBuildSteps(
run.setName(incr_case.base_path);
run.addArgs(&.{
case_base_path_with_dir,
- b.zig_exe,
+ b.graph.zig_exe,
});
run.expectStdOutEqual("");
parent_step.dependOn(&run.step);
@@ -653,7 +653,7 @@ pub fn lowerToBuildSteps(
break :no_exec;
}
const run_c = b.addSystemCommand(&.{
- b.zig_exe,
+ b.graph.zig_exe,
"run",
"-cflags",
"-Ilib",
test/tests.zig
@@ -796,7 +796,7 @@ pub fn addCliTests(b: *std.Build) *Step {
{
// Test `zig init`.
const tmp_path = b.makeTempPath();
- const init_exe = b.addSystemCommand(&.{ b.zig_exe, "init" });
+ const init_exe = b.addSystemCommand(&.{ b.graph.zig_exe, "init" });
init_exe.setCwd(.{ .cwd_relative = tmp_path });
init_exe.setName("zig init");
init_exe.expectStdOutEqual("");
@@ -810,20 +810,20 @@ pub fn addCliTests(b: *std.Build) *Step {
const bad_out_arg = "-femit-bin=does" ++ s ++ "not" ++ s ++ "exist" ++ s ++ "foo.exe";
const ok_src_arg = "src" ++ s ++ "main.zig";
const expected = "error: unable to open output directory 'does" ++ s ++ "not" ++ s ++ "exist': FileNotFound\n";
- const run_bad = b.addSystemCommand(&.{ b.zig_exe, "build-exe", ok_src_arg, bad_out_arg });
+ const run_bad = b.addSystemCommand(&.{ b.graph.zig_exe, "build-exe", ok_src_arg, bad_out_arg });
run_bad.setName("zig build-exe error message for bad -femit-bin arg");
run_bad.expectExitCode(1);
run_bad.expectStdErrEqual(expected);
run_bad.expectStdOutEqual("");
run_bad.step.dependOn(&init_exe.step);
- const run_test = b.addSystemCommand(&.{ b.zig_exe, "build", "test" });
+ const run_test = b.addSystemCommand(&.{ b.graph.zig_exe, "build", "test" });
run_test.setCwd(.{ .cwd_relative = tmp_path });
run_test.setName("zig build test");
run_test.expectStdOutEqual("");
run_test.step.dependOn(&init_exe.step);
- const run_run = b.addSystemCommand(&.{ b.zig_exe, "build", "run" });
+ const run_run = b.addSystemCommand(&.{ b.graph.zig_exe, "build", "run" });
run_run.setCwd(.{ .cwd_relative = tmp_path });
run_run.setName("zig build run");
run_run.expectStdOutEqual("Run `zig build test` to run the tests.\n");
@@ -857,7 +857,7 @@ pub fn addCliTests(b: *std.Build) *Step {
// This is intended to be the exact CLI usage used by godbolt.org.
const run = b.addSystemCommand(&.{
- b.zig_exe, "build-obj",
+ b.graph.zig_exe, "build-obj",
"--cache-dir", tmp_path,
"--name", "example",
"-fno-emit-bin", "-fno-emit-h",
@@ -900,7 +900,7 @@ pub fn addCliTests(b: *std.Build) *Step {
subdir.writeFile("fmt3.zig", unformatted_code) catch @panic("unhandled");
// Test zig fmt affecting only the appropriate files.
- const run1 = b.addSystemCommand(&.{ b.zig_exe, "fmt", "fmt1.zig" });
+ const run1 = b.addSystemCommand(&.{ b.graph.zig_exe, "fmt", "fmt1.zig" });
run1.setName("run zig fmt one file");
run1.setCwd(.{ .cwd_relative = tmp_path });
run1.has_side_effects = true;
@@ -908,7 +908,7 @@ pub fn addCliTests(b: *std.Build) *Step {
run1.expectStdOutEqual("fmt1.zig\n");
// Test excluding files and directories from a run
- const run2 = b.addSystemCommand(&.{ b.zig_exe, "fmt", "--exclude", "fmt2.zig", "--exclude", "subdir", "." });
+ const run2 = b.addSystemCommand(&.{ b.graph.zig_exe, "fmt", "--exclude", "fmt2.zig", "--exclude", "subdir", "." });
run2.setName("run zig fmt on directory with exclusions");
run2.setCwd(.{ .cwd_relative = tmp_path });
run2.has_side_effects = true;
@@ -916,7 +916,7 @@ pub fn addCliTests(b: *std.Build) *Step {
run2.step.dependOn(&run1.step);
// Test excluding non-existent file
- const run3 = b.addSystemCommand(&.{ b.zig_exe, "fmt", "--exclude", "fmt2.zig", "--exclude", "nonexistent.zig", "." });
+ const run3 = b.addSystemCommand(&.{ b.graph.zig_exe, "fmt", "--exclude", "fmt2.zig", "--exclude", "nonexistent.zig", "." });
run3.setName("run zig fmt on directory with non-existent exclusion");
run3.setCwd(.{ .cwd_relative = tmp_path });
run3.has_side_effects = true;
@@ -924,7 +924,7 @@ pub fn addCliTests(b: *std.Build) *Step {
run3.step.dependOn(&run2.step);
// running it on the dir, only the new file should be changed
- const run4 = b.addSystemCommand(&.{ b.zig_exe, "fmt", "." });
+ const run4 = b.addSystemCommand(&.{ b.graph.zig_exe, "fmt", "." });
run4.setName("run zig fmt the directory");
run4.setCwd(.{ .cwd_relative = tmp_path });
run4.has_side_effects = true;
@@ -932,7 +932,7 @@ pub fn addCliTests(b: *std.Build) *Step {
run4.step.dependOn(&run3.step);
// both files have been formatted, nothing should change now
- const run5 = b.addSystemCommand(&.{ b.zig_exe, "fmt", "." });
+ const run5 = b.addSystemCommand(&.{ b.graph.zig_exe, "fmt", "." });
run5.setName("run zig fmt with nothing to do");
run5.setCwd(.{ .cwd_relative = tmp_path });
run5.has_side_effects = true;
@@ -946,7 +946,7 @@ pub fn addCliTests(b: *std.Build) *Step {
write6.step.dependOn(&run5.step);
// Test `zig fmt` handling UTF-16 decoding.
- const run6 = b.addSystemCommand(&.{ b.zig_exe, "fmt", "." });
+ const run6 = b.addSystemCommand(&.{ b.graph.zig_exe, "fmt", "." });
run6.setName("run zig fmt convert UTF-16 to UTF-8");
run6.setCwd(.{ .cwd_relative = tmp_path });
run6.has_side_effects = true;
build.zig
@@ -45,7 +45,7 @@ pub fn build(b: *std.Build) !void {
});
const docgen_cmd = b.addRunArtifact(docgen_exe);
- docgen_cmd.addArgs(&.{ "--zig", b.zig_exe });
+ docgen_cmd.addArgs(&.{ "--zig", b.graph.zig_exe });
if (b.zig_lib_dir) |p| {
docgen_cmd.addArg("--zig-lib-dir");
docgen_cmd.addDirectoryArg(p);
@@ -410,14 +410,14 @@ pub fn build(b: *std.Build) !void {
test_cases_options.addOption(bool, "only_c", only_c);
test_cases_options.addOption(bool, "only_core_functionality", true);
test_cases_options.addOption(bool, "only_reduce", false);
- test_cases_options.addOption(bool, "enable_qemu", b.enable_qemu);
- test_cases_options.addOption(bool, "enable_wine", b.enable_wine);
- test_cases_options.addOption(bool, "enable_wasmtime", b.enable_wasmtime);
- test_cases_options.addOption(bool, "enable_rosetta", b.enable_rosetta);
- test_cases_options.addOption(bool, "enable_darling", b.enable_darling);
+ test_cases_options.addOption(bool, "enable_qemu", b.graph.enable_qemu);
+ test_cases_options.addOption(bool, "enable_wine", b.graph.enable_wine);
+ test_cases_options.addOption(bool, "enable_wasmtime", b.graph.enable_wasmtime);
+ test_cases_options.addOption(bool, "enable_rosetta", b.graph.enable_rosetta);
+ test_cases_options.addOption(bool, "enable_darling", b.graph.enable_darling);
test_cases_options.addOption(u32, "mem_leak_frames", mem_leak_frames * 2);
test_cases_options.addOption(bool, "value_tracing", value_tracing);
- test_cases_options.addOption(?[]const u8, "glibc_runtimes_dir", b.glibc_runtimes_dir);
+ test_cases_options.addOption(?[]const u8, "glibc_runtimes_dir", b.graph.glibc_runtimes_dir);
test_cases_options.addOption([:0]const u8, "version", version);
test_cases_options.addOption(std.SemanticVersion, "semver", semver);
test_cases_options.addOption(?[]const u8, "test_filter", test_filter);
@@ -884,7 +884,7 @@ fn findConfigH(b: *std.Build, config_h_path_option: ?[]const u8) ?[]const u8 {
}
}
- var check_dir = fs.path.dirname(b.zig_exe).?;
+ var check_dir = fs.path.dirname(b.graph.zig_exe).?;
while (true) {
var dir = fs.cwd().openDir(check_dir, .{}) catch unreachable;
defer dir.close();