std.Build.ResolvedTarget: rename target field to result

This change is seemingly insignificant but I actually agonized over this
for three days. Some other things I considered:

* (status quo in master branch) make Compile step creation functions
  accept a Target.Query and delete the ResolvedTarget struct.
  - downside: redundantly resolve target queries many times
* same as before but additionally add a hash map to cache target query
  resolutions.
  - downside: now there is a hash map that doesn't actually need to
    exist, just to make the API more ergonomic.
* add is_native_os and is_native_abi fields to std.Target and use it
  directly as the result of resolving a target query.
  - downside: they really don't belong there. They would be available
    as comptime booleans via `@import("builtin")` but they should not
    be exposed that way.

With this change the downsides are:
* the option name of addExecutable and friends is `target` instead of
  `resolved_target` matching the type name.
  - upside: this does not break compatibility with existing build
    scripts
* you likely end up seeing `target.result.cpu.arch` rather than
  `target.cpu.arch`.
  - upside: this is an improvement over `target.target.cpu.arch` which
    it was before this commit.
  - downside: `b.host.target` is now `b.host.result`.
This commit is contained in:
Andrew Kelley 2023-12-05 16:09:07 -07:00
parent f5613a0e35
commit b92e30ff0b
16 changed files with 43 additions and 41 deletions

View File

@ -221,7 +221,7 @@ pub fn build(b: *std.Build) !void {
test_step.dependOn(&exe.step);
if (target.target.os.tag == .windows and target.target.abi == .gnu) {
if (target.result.os.tag == .windows and target.result.abi == .gnu) {
// LTO is currently broken on mingw, this can be removed when it's fixed.
exe.want_lto = false;
check_case_exe.want_lto = false;
@ -347,7 +347,7 @@ pub fn build(b: *std.Build) !void {
try addStaticLlvmOptionsToExe(exe);
try addStaticLlvmOptionsToExe(check_case_exe);
}
if (target.target.os.tag == .windows) {
if (target.result.os.tag == .windows) {
inline for (.{ exe, check_case_exe }) |artifact| {
artifact.linkSystemLibrary("version");
artifact.linkSystemLibrary("uuid");
@ -371,7 +371,7 @@ pub fn build(b: *std.Build) !void {
);
// On mingw, we need to opt into windows 7+ to get some features required by tracy.
const tracy_c_flags: []const []const u8 = if (target.target.os.tag == .windows and target.target.abi == .gnu)
const tracy_c_flags: []const []const u8 = if (target.result.os.tag == .windows and target.result.abi == .gnu)
&[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined", "-D_WIN32_WINNT=0x601" }
else
&[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" };
@ -383,7 +383,7 @@ pub fn build(b: *std.Build) !void {
}
exe.linkLibC();
if (target.target.os.tag == .windows) {
if (target.result.os.tag == .windows) {
exe.linkSystemLibrary("dbghelp");
exe.linkSystemLibrary("ws2_32");
}

View File

@ -48,7 +48,7 @@ pub fn main() !void {
const host: std.Build.ResolvedTarget = .{
.query = .{},
.target = try std.zig.system.resolveTargetQuery(.{}),
.result = try std.zig.system.resolveTargetQuery(.{}),
};
const build_root_directory: std.Build.Cache.Directory = .{

View File

@ -2044,7 +2044,7 @@ pub fn hex64(x: u64) [16]u8 {
/// of the target are "native". This can apply to the CPU, the OS, or even the ABI.
pub const ResolvedTarget = struct {
query: Target.Query,
target: Target,
result: Target,
};
/// Converts a target query into a fully resolved target that can be passed to
@ -2056,7 +2056,7 @@ pub fn resolveTargetQuery(b: *Build, query: Target.Query) ResolvedTarget {
return .{
.query = query,
.target = std.zig.system.resolveTargetQuery(query) catch
.result = std.zig.system.resolveTargetQuery(query) catch
@panic("unable to resolve target query"),
};
}

View File

@ -10,7 +10,7 @@ root_source_file: ?LazyPath,
/// maintain step dependency edges.
import_table: std.StringArrayHashMapUnmanaged(*Module),
target: ?std.Build.ResolvedTarget = null,
resolved_target: ?std.Build.ResolvedTarget = null,
optimize: ?std.builtin.OptimizeMode = null,
dwarf_format: ?std.dwarf.Format,
@ -192,7 +192,7 @@ pub fn init(m: *Module, owner: *std.Build, options: CreateOptions, compile: ?*St
.depending_steps = .{},
.root_source_file = if (options.root_source_file) |lp| lp.dupe(owner) else null,
.import_table = .{},
.target = options.target,
.resolved_target = options.target,
.optimize = options.optimize,
.link_libc = options.link_libc,
.link_libcpp = options.link_libcpp,
@ -627,7 +627,7 @@ pub fn appendZigProcessFlags(
try zig_args.append(@tagName(m.code_model));
}
if (m.target) |*target| {
if (m.resolved_target) |*target| {
// Communicate the query via CLI since it's more compact.
if (!target.query.isNative()) {
try zig_args.appendSlice(&.{
@ -737,9 +737,9 @@ fn linkLibraryOrObject(m: *Module, other: *Step.Compile) void {
}
fn requireKnownTarget(m: *Module) std.Target {
const resolved_target = m.target orelse
const resolved_target = m.resolved_target orelse
@panic("this API requires the Module to be created with a known 'target' field");
return resolved_target.target;
return resolved_target.result;
}
const Module = @This();

View File

@ -251,7 +251,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
else
owner.fmt("{s} ", .{name});
const target = options.root_module.target.?.target;
const target = options.root_module.target.?.result;
const step_name = owner.fmt("{s} {s}{s} {s}", .{
switch (options.kind) {
@ -954,7 +954,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try addFlag(&zig_args, "llvm", self.use_llvm);
try addFlag(&zig_args, "lld", self.use_lld);
if (self.root_module.target.?.query.ofmt) |ofmt| {
if (self.root_module.resolved_target.?.query.ofmt) |ofmt| {
try zig_args.append(try std.fmt.allocPrint(b.allocator, "-ofmt={s}", .{@tagName(ofmt)}));
}
@ -1845,5 +1845,5 @@ fn matchCompileError(actual: []const u8, expected: []const u8) bool {
pub fn rootModuleTarget(c: *Compile) std.Target {
// The root module is always given a target, so we know this to be non-null.
return c.root_module.target.?.target;
return c.root_module.resolved_target.?.result;
}

View File

@ -678,8 +678,8 @@ fn runCommand(
const need_cross_glibc = exe.rootModuleTarget().isGnuLibC() and
exe.is_linking_libc;
const other_target = exe.root_module.target.?.target;
switch (std.zig.system.getExternalExecutor(b.host.target, &other_target, .{
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,
.link_libc = exe.is_linking_libc,
})) {
@ -752,7 +752,7 @@ fn runCommand(
.bad_dl => |foreign_dl| {
if (allow_skip) return error.MakeSkipped;
const host_dl = b.host.target.dynamic_linker.get() orelse "(none)";
const host_dl = b.host.result.dynamic_linker.get() orelse "(none)";
return step.fail(
\\the host system is unable to execute binaries from the target
@ -764,7 +764,7 @@ fn runCommand(
.bad_os_or_cpu => {
if (allow_skip) return error.MakeSkipped;
const host_name = try b.host.target.zigTriple(b.allocator);
const host_name = try b.host.result.zigTriple(b.allocator);
const foreign_name = try exe.rootModuleTarget().zigTriple(b.allocator);
return step.fail("the host system ({s}) is unable to execute binaries from the target ({s})", .{
@ -1295,7 +1295,9 @@ fn addPathForDynLibs(self: *Run, artifact: *Step.Compile) void {
while (it.next()) |item| {
const other = item.compile.?;
if (item.module == &other.root_module) {
if (item.module.target.?.target.os.tag == .windows and other.isDynamicLibrary()) {
if (item.module.resolved_target.?.result.os.tag == .windows and
other.isDynamicLibrary())
{
addPathDir(self, fs.path.dirname(other.getEmittedBin().getPath(b)).?);
}
}
@ -1314,7 +1316,7 @@ fn failForeign(
return error.MakeSkipped;
const b = self.step.owner;
const host_name = try b.host.target.zigTriple(b.allocator);
const host_name = try b.host.result.zigTriple(b.allocator);
const foreign_name = try exe.rootModuleTarget().zigTriple(b.allocator);
return self.step.fail(

View File

@ -1763,7 +1763,7 @@ fn testInitArrayOrder(b: *Build, opts: Options) *Step {
exe.addObject(g_o);
exe.addObject(h_o);
if (opts.target.target.isGnuLibC()) {
if (opts.target.result.isGnuLibC()) {
// TODO I think we need to clarify our use of `-fPIC -fPIE` flags for different targets
exe.pie = true;
}

View File

@ -14,7 +14,7 @@ pub const Options = struct {
};
pub fn addTestStep(b: *Build, prefix: []const u8, opts: Options) *Step {
const target = opts.target.target.zigTriple(b.allocator) catch @panic("OOM");
const target = opts.target.result.zigTriple(b.allocator) catch @panic("OOM");
const optimize = @tagName(opts.optimize);
const use_llvm = if (opts.use_llvm) "llvm" else "no-llvm";
const name = std.fmt.allocPrint(b.allocator, "test-{s}-{s}-{s}-{s}", .{

View File

@ -15,7 +15,7 @@ pub fn build(b: *std.Build) void {
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const sdk = std.zig.system.darwin.getSdk(b.allocator, target.target) orelse
const sdk = std.zig.system.darwin.getSdk(b.allocator, target.result) orelse
@panic("macOS SDK is required to run the test");
const exe = b.addExecutable(.{

View File

@ -467,7 +467,7 @@ fn addFromDirInner(
// Cross-product to get all possible test combinations
for (targets) |target_query| {
const resolved_target = b.resolveTargetQuery(target_query);
const target = resolved_target.target;
const target = resolved_target.result;
for (backends) |backend| {
if (backend == .stage2 and
target.cpu.arch != .wasm32 and target.cpu.arch != .x86_64)
@ -647,8 +647,8 @@ pub fn lowerToBuildSteps(
parent_step.dependOn(&artifact.step);
},
.Execution => |expected_stdout| no_exec: {
const run = if (case.target.target.ofmt == .c) run_step: {
if (getExternalExecutor(host, &case.target.target, .{ .link_libc = true }) != .native) {
const run = if (case.target.result.ofmt == .c) run_step: {
if (getExternalExecutor(host, &case.target.result, .{ .link_libc = true }) != .native) {
// We wouldn't be able to run the compiled C code.
break :no_exec;
}
@ -667,7 +667,7 @@ pub fn lowerToBuildSteps(
"--",
"-lc",
"-target",
case.target.target.zigTriple(b.allocator) catch @panic("OOM"),
case.target.result.zigTriple(b.allocator) catch @panic("OOM"),
});
run_c.addArtifactArg(artifact);
break :run_step run_c;
@ -693,7 +693,7 @@ pub fn lowerToBuildSteps(
continue; // Pass test.
}
if (getExternalExecutor(host, &case.target.target, .{ .link_libc = true }) != .native) {
if (getExternalExecutor(host, &case.target.result, .{ .link_libc = true }) != .native) {
// We wouldn't be able to run the compiled C code.
continue; // Pass test.
}

View File

@ -42,7 +42,7 @@ fn add(
exe_cpp.addCSourceFile(.{ .file = .{ .path = "test.cpp" }, .flags = &[0][]const u8{} });
exe_cpp.linkLibCpp();
switch (target.target.os.tag) {
switch (target.result.os.tag) {
.windows => {
// https://github.com/ziglang/zig/issues/8531
exe_cpp.want_lto = false;

View File

@ -4,16 +4,16 @@ pub fn build(b: *std.Build) void {
const test_step = b.step("test", "Test it");
b.default_step = test_step;
const resolved_target = b.standardTargetOptions(.{});
const target = resolved_target.target;
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
if (target.ofmt != .elf or !(target.abi.isMusl() or target.abi.isGnu())) return;
if (target.result.ofmt != .elf or !(target.result.abi.isMusl() or target.result.abi.isGnu()))
return;
const exe = b.addExecutable(.{
.name = "main",
.optimize = optimize,
.target = resolved_target,
.target = target,
});
exe.linkLibC();
exe.addCSourceFile(.{

View File

@ -12,7 +12,7 @@ pub fn build(b: *std.Build) void {
.cpu_arch = .aarch64,
.os_tag = .ios,
});
const sdk = std.zig.system.darwin.getSdk(b.allocator, target.target) orelse
const sdk = std.zig.system.darwin.getSdk(b.allocator, target.result) orelse
@panic("no iOS SDK found");
b.sysroot = sdk;

View File

@ -11,7 +11,7 @@ pub fn build(b: *std.Build) void {
// The test requires getFdPath in order to to get the path of the
// File returned by openSelfExe
if (!std.os.isGetFdPathSupportedOnTarget(target.target.os)) return;
if (!std.os.isGetFdPathSupportedOnTarget(target.result.os)) return;
const main = b.addExecutable(.{
.name = "main",

View File

@ -22,7 +22,7 @@ pub fn build(b: *std.Build) void {
.root_source_file = .{ .path = "unwind.zig" },
.target = target,
.optimize = optimize,
.unwind_tables = target.target.isDarwin(),
.unwind_tables = target.result.isDarwin(),
.omit_frame_pointer = false,
});
@ -70,7 +70,7 @@ pub fn build(b: *std.Build) void {
.strip = false,
});
if (target.target.os.tag == .windows)
if (target.result.os.tag == .windows)
c_shared_lib.defineCMacro("LIB_API", "__declspec(dllexport)");
c_shared_lib.addCSourceFile(.{
@ -84,7 +84,7 @@ pub fn build(b: *std.Build) void {
.root_source_file = .{ .path = "shared_lib_unwind.zig" },
.target = target,
.optimize = optimize,
.unwind_tables = target.target.isDarwin(),
.unwind_tables = target.result.isDarwin(),
.omit_frame_pointer = true,
});

View File

@ -1043,7 +1043,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
continue;
const resolved_target = b.resolveTargetQuery(test_target.target);
const target = resolved_target.target;
const target = resolved_target.result;
if (options.skip_cross_glibc and !test_target.target.isNative() and
target.isGnuLibC() and test_target.link_libc == true)
@ -1229,7 +1229,7 @@ pub fn addCAbiTests(b: *std.Build, skip_non_native: bool, skip_release: bool) *S
if (skip_non_native and !c_abi_target.target.isNative()) continue;
const resolved_target = b.resolveTargetQuery(c_abi_target.target);
const target = resolved_target.target;
const target = resolved_target.result;
if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
// https://github.com/ziglang/zig/issues/14908