Skip to content

Commit 105db13

Browse files
committed
std.Build: implement --host-target, --host-cpu, --host-dynamic-linker
This also makes a long-overdue change of extracting common state from Build into a shared Graph object. Getting the semantics right for these flags turned out to be quite tricky. In the end it works like this: * The override only happens when the target is fully native, with no additional query parameters, such as versions or CPU features added. * The override affects the resolved Target but leaves the original Query unmodified. * The "is native?" detection logic operates on the original, unmodified query. This makes it possible to provide invalid host target information, causing confusing errors to occur. Don't do that. There are some minor breaking changes to std.Build API such as the fact that `b.zig_exe` is now moved to `b.graph.zig_exe`, as well as a handful of other similar flags.
1 parent bd1d2b0 commit 105db13

File tree

15 files changed

+230
-216
lines changed

15 files changed

+230
-216
lines changed

build.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub fn build(b: *std.Build) !void {
4545
});
4646

4747
const docgen_cmd = b.addRunArtifact(docgen_exe);
48-
docgen_cmd.addArgs(&.{ "--zig", b.zig_exe });
48+
docgen_cmd.addArgs(&.{ "--zig", b.graph.zig_exe });
4949
if (b.zig_lib_dir) |p| {
5050
docgen_cmd.addArg("--zig-lib-dir");
5151
docgen_cmd.addDirectoryArg(p);
@@ -410,14 +410,14 @@ pub fn build(b: *std.Build) !void {
410410
test_cases_options.addOption(bool, "only_c", only_c);
411411
test_cases_options.addOption(bool, "only_core_functionality", true);
412412
test_cases_options.addOption(bool, "only_reduce", false);
413-
test_cases_options.addOption(bool, "enable_qemu", b.enable_qemu);
414-
test_cases_options.addOption(bool, "enable_wine", b.enable_wine);
415-
test_cases_options.addOption(bool, "enable_wasmtime", b.enable_wasmtime);
416-
test_cases_options.addOption(bool, "enable_rosetta", b.enable_rosetta);
417-
test_cases_options.addOption(bool, "enable_darling", b.enable_darling);
413+
test_cases_options.addOption(bool, "enable_qemu", b.graph.enable_qemu);
414+
test_cases_options.addOption(bool, "enable_wine", b.graph.enable_wine);
415+
test_cases_options.addOption(bool, "enable_wasmtime", b.graph.enable_wasmtime);
416+
test_cases_options.addOption(bool, "enable_rosetta", b.graph.enable_rosetta);
417+
test_cases_options.addOption(bool, "enable_darling", b.graph.enable_darling);
418418
test_cases_options.addOption(u32, "mem_leak_frames", mem_leak_frames * 2);
419419
test_cases_options.addOption(bool, "value_tracing", value_tracing);
420-
test_cases_options.addOption(?[]const u8, "glibc_runtimes_dir", b.glibc_runtimes_dir);
420+
test_cases_options.addOption(?[]const u8, "glibc_runtimes_dir", b.graph.glibc_runtimes_dir);
421421
test_cases_options.addOption([:0]const u8, "version", version);
422422
test_cases_options.addOption(std.SemanticVersion, "semver", semver);
423423
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 {
884884
}
885885
}
886886

887-
var check_dir = fs.path.dirname(b.zig_exe).?;
887+
var check_dir = fs.path.dirname(b.graph.zig_exe).?;
888888
while (true) {
889889
var dir = fs.cwd().openDir(check_dir, .{}) catch unreachable;
890890
defer dir.close();

deps/aro/build/GenerateDef.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
5353
const self = @fieldParentPtr(GenerateDef, "step", step);
5454
const arena = b.allocator;
5555

56-
var man = b.cache.obtain();
56+
var man = b.graph.cache.obtain();
5757
defer man.deinit();
5858

5959
// Random bytes to make GenerateDef unique. Refresh this with new

lib/build_runner.zig

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ pub fn main() !void {
4646
return error.InvalidArgs;
4747
};
4848

49-
const host: std.Build.ResolvedTarget = .{
50-
.query = .{},
51-
.result = try std.zig.system.resolveTargetQuery(.{}),
52-
};
53-
5449
const build_root_directory: std.Build.Cache.Directory = .{
5550
.path = build_root,
5651
.handle = try std.fs.cwd().openDir(build_root, .{}),
@@ -66,28 +61,28 @@ pub fn main() !void {
6661
.handle = try std.fs.cwd().makeOpenPath(global_cache_root, .{}),
6762
};
6863

69-
var cache: std.Build.Cache = .{
70-
.gpa = arena,
71-
.manifest_dir = try local_cache_directory.handle.makeOpenPath("h", .{}),
64+
var graph: std.Build.Graph = .{
65+
.arena = arena,
66+
.cache = .{
67+
.gpa = arena,
68+
.manifest_dir = try local_cache_directory.handle.makeOpenPath("h", .{}),
69+
},
70+
.zig_exe = zig_exe,
71+
.env_map = try process.getEnvMap(arena),
72+
.global_cache_root = global_cache_directory,
7273
};
73-
cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() });
74-
cache.addPrefix(build_root_directory);
75-
cache.addPrefix(local_cache_directory);
76-
cache.addPrefix(global_cache_directory);
77-
cache.hash.addBytes(builtin.zig_version_string);
7874

79-
var system_library_options: std.StringArrayHashMapUnmanaged(std.Build.SystemLibraryMode) = .{};
75+
graph.cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() });
76+
graph.cache.addPrefix(build_root_directory);
77+
graph.cache.addPrefix(local_cache_directory);
78+
graph.cache.addPrefix(global_cache_directory);
79+
graph.cache.hash.addBytes(builtin.zig_version_string);
8080

8181
const builder = try std.Build.create(
82-
arena,
83-
zig_exe,
82+
&graph,
8483
build_root_directory,
8584
local_cache_directory,
86-
global_cache_directory,
87-
host,
88-
&cache,
8985
dependencies.root_deps,
90-
&system_library_options,
9186
);
9287

9388
var targets = ArrayList([]const u8).init(arena);
@@ -132,10 +127,16 @@ pub fn main() !void {
132127
steps_menu = true;
133128
} else if (mem.eql(u8, arg, "--system-lib")) {
134129
const name = nextArgOrFatal(args, &arg_idx);
135-
builder.system_library_options.put(arena, name, .user_enabled) catch @panic("OOM");
130+
graph.system_library_options.put(arena, name, .user_enabled) catch @panic("OOM");
136131
} else if (mem.eql(u8, arg, "--no-system-lib")) {
137132
const name = nextArgOrFatal(args, &arg_idx);
138-
builder.system_library_options.put(arena, name, .user_disabled) catch @panic("OOM");
133+
graph.system_library_options.put(arena, name, .user_disabled) catch @panic("OOM");
134+
} else if (mem.eql(u8, arg, "--host-target")) {
135+
graph.host_query_options.arch_os_abi = nextArgOrFatal(args, &arg_idx);
136+
} else if (mem.eql(u8, arg, "--host-cpu")) {
137+
graph.host_query_options.cpu_features = nextArgOrFatal(args, &arg_idx);
138+
} else if (mem.eql(u8, arg, "--host-dynamic-linker")) {
139+
graph.host_query_options.dynamic_linker = nextArgOrFatal(args, &arg_idx);
139140
} else if (mem.eql(u8, arg, "--prefix-lib-dir")) {
140141
dir_list.lib_dir = nextArgOrFatal(args, &arg_idx);
141142
} else if (mem.eql(u8, arg, "--prefix-exe-dir")) {
@@ -193,7 +194,7 @@ pub fn main() !void {
193194
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
194195
builder.debug_compile_errors = true;
195196
} else if (mem.eql(u8, arg, "--glibc-runtimes")) {
196-
builder.glibc_runtimes_dir = nextArgOrFatal(args, &arg_idx);
197+
graph.glibc_runtimes_dir = nextArgOrFatal(args, &arg_idx);
197198
} else if (mem.eql(u8, arg, "--verbose-link")) {
198199
builder.verbose_link = true;
199200
} else if (mem.eql(u8, arg, "--verbose-air")) {
@@ -213,25 +214,25 @@ pub fn main() !void {
213214
} else if (mem.eql(u8, arg, "--prominent-compile-errors")) {
214215
prominent_compile_errors = true;
215216
} else if (mem.eql(u8, arg, "-fwine")) {
216-
builder.enable_wine = true;
217+
graph.enable_wine = true;
217218
} else if (mem.eql(u8, arg, "-fno-wine")) {
218-
builder.enable_wine = false;
219+
graph.enable_wine = false;
219220
} else if (mem.eql(u8, arg, "-fqemu")) {
220-
builder.enable_qemu = true;
221+
graph.enable_qemu = true;
221222
} else if (mem.eql(u8, arg, "-fno-qemu")) {
222-
builder.enable_qemu = false;
223+
graph.enable_qemu = false;
223224
} else if (mem.eql(u8, arg, "-fwasmtime")) {
224-
builder.enable_wasmtime = true;
225+
graph.enable_wasmtime = true;
225226
} else if (mem.eql(u8, arg, "-fno-wasmtime")) {
226-
builder.enable_wasmtime = false;
227+
graph.enable_wasmtime = false;
227228
} else if (mem.eql(u8, arg, "-frosetta")) {
228-
builder.enable_rosetta = true;
229+
graph.enable_rosetta = true;
229230
} else if (mem.eql(u8, arg, "-fno-rosetta")) {
230-
builder.enable_rosetta = false;
231+
graph.enable_rosetta = false;
231232
} else if (mem.eql(u8, arg, "-fdarling")) {
232-
builder.enable_darling = true;
233+
graph.enable_darling = true;
233234
} else if (mem.eql(u8, arg, "-fno-darling")) {
234-
builder.enable_darling = false;
235+
graph.enable_darling = false;
235236
} else if (mem.eql(u8, arg, "-freference-trace")) {
236237
builder.reference_trace = 256;
237238
} else if (mem.startsWith(u8, arg, "-freference-trace=")) {
@@ -266,11 +267,19 @@ pub fn main() !void {
266267
}
267268
}
268269

270+
const host_query = std.Build.parseTargetQuery(graph.host_query_options) catch |err| switch (err) {
271+
error.ParseFailed => process.exit(1),
272+
};
273+
builder.host = .{
274+
.query = .{},
275+
.result = try std.zig.system.resolveTargetQuery(host_query),
276+
};
277+
269278
const stderr = std.io.getStdErr();
270279
const ttyconf = get_tty_conf(color, stderr);
271280
switch (ttyconf) {
272-
.no_color => try builder.env_map.put("NO_COLOR", "1"),
273-
.escape_codes => try builder.env_map.put("YES_COLOR", "1"),
281+
.no_color => try graph.env_map.put("NO_COLOR", "1"),
282+
.escape_codes => try graph.env_map.put("YES_COLOR", "1"),
274283
.windows_api => {},
275284
}
276285

@@ -1029,7 +1038,7 @@ fn usage(b: *std.Build, out_stream: anytype) !void {
10291038
\\
10301039
\\Steps:
10311040
\\
1032-
, .{b.zig_exe});
1041+
, .{b.graph.zig_exe});
10331042
try steps(b, out_stream);
10341043

10351044
try out_stream.writeAll(
@@ -1104,22 +1113,23 @@ fn usage(b: *std.Build, out_stream: anytype) !void {
11041113
\\ --system [dir] System Package Mode. Disable fetching; prefer system libs
11051114
\\ --host-target [triple] Use the provided target as the host
11061115
\\ --host-cpu [cpu] Use the provided CPU as the host
1116+
\\ --host-dynamic-linker [path] Use the provided dynamic linker as the host
11071117
\\ --system-lib [name] Use the system-provided library
11081118
\\ --no-system-lib [name] Do not use the system-provided library
11091119
\\
11101120
\\ Available System Library Integrations: Enabled:
11111121
\\
11121122
);
1113-
if (b.system_library_options.entries.len == 0) {
1123+
if (b.graph.system_library_options.entries.len == 0) {
11141124
try out_stream.writeAll(" (none) -\n");
11151125
} else {
1116-
for (b.system_library_options.keys(), b.system_library_options.values()) |name, v| {
1126+
for (b.graph.system_library_options.keys(), b.graph.system_library_options.values()) |k, v| {
11171127
const status = switch (v) {
11181128
.declared_enabled => "yes",
11191129
.declared_disabled => "no",
11201130
.user_enabled, .user_disabled => unreachable, // already emitted error
11211131
};
1122-
try out_stream.print(" {s:<43} {s}\n", .{ name, status });
1132+
try out_stream.print(" {s:<43} {s}\n", .{ k, status });
11231133
}
11241134
}
11251135

@@ -1203,7 +1213,7 @@ fn fatal(comptime f: []const u8, args: anytype) noreturn {
12031213

12041214
fn validateSystemLibraryOptions(b: *std.Build) void {
12051215
var bad = false;
1206-
for (b.system_library_options.keys(), b.system_library_options.values()) |k, v| {
1216+
for (b.graph.system_library_options.keys(), b.graph.system_library_options.values()) |k, v| {
12071217
switch (v) {
12081218
.user_disabled, .user_enabled => {
12091219
// The user tried to enable or disable a system library integration, but

0 commit comments

Comments
 (0)