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.
This commit is contained in:
Andrew Kelley
2024-02-01 15:44:44 -07:00
parent bd1d2b0ae2
commit 105db13536
15 changed files with 237 additions and 223 deletions

View File

@@ -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();