mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
zig build: add standardTargetOptions and deprecate setTarget
in favor of setTheTarget
This commit is contained in:
parent
038946288c
commit
ae2345b742
252
std/build.zig
252
std/build.zig
@ -380,10 +380,12 @@ pub const Builder = struct {
|
||||
switch (builtin.os) {
|
||||
.windows => {},
|
||||
else => {
|
||||
const triple = (CrossTarget{
|
||||
.arch = builtin.arch,
|
||||
.os = builtin.os,
|
||||
.abi = builtin.abi,
|
||||
const triple = (Target{
|
||||
.Cross = CrossTarget{
|
||||
.arch = builtin.arch,
|
||||
.os = builtin.os,
|
||||
.abi = builtin.abi,
|
||||
},
|
||||
}).linuxTriple(self.allocator);
|
||||
|
||||
// TODO: $ ld --verbose | grep SEARCH_DIR
|
||||
@ -507,6 +509,26 @@ pub const Builder = struct {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/// Exposes standard `zig build` options for choosing a target. Pass `null` to support all targets.
|
||||
pub fn standardTargetOptions(self: *Builder, supported_targets: ?[]const Target) Target {
|
||||
if (supported_targets) |target_list| {
|
||||
// TODO detect multiple args and emit an error message
|
||||
// there's probably a better way to collect the target
|
||||
for (target_list) |targ| {
|
||||
const targ_str = targ.zigTriple(self.allocator) catch unreachable;
|
||||
const targ_desc = targ.allocDescription(self.allocator) catch unreachable;
|
||||
const this_targ_opt = self.option(bool, targ_str, targ_desc) orelse false;
|
||||
if (this_targ_opt) {
|
||||
return targ;
|
||||
}
|
||||
}
|
||||
return Target.Native;
|
||||
} else {
|
||||
const target_str = self.option([]const u8, "target", "the target to build for") orelse return Target.Native;
|
||||
return Target.parse(target_str) catch unreachable; // TODO better error message for bad target
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addUserInputOption(self: *Builder, name: []const u8, value: []const u8) !bool {
|
||||
const gop = try self.user_input_options.getOrPut(name);
|
||||
if (!gop.found_existing) {
|
||||
@ -858,67 +880,193 @@ pub const Builder = struct {
|
||||
}
|
||||
};
|
||||
|
||||
const Version = struct {
|
||||
pub const Version = struct {
|
||||
major: u32,
|
||||
minor: u32,
|
||||
patch: u32,
|
||||
};
|
||||
|
||||
const CrossTarget = struct {
|
||||
pub const CrossTarget = struct {
|
||||
arch: builtin.Arch,
|
||||
os: builtin.Os,
|
||||
abi: builtin.Abi,
|
||||
|
||||
pub fn zigTriple(cross_target: CrossTarget, allocator: *Allocator) []u8 {
|
||||
return std.fmt.allocPrint(
|
||||
allocator,
|
||||
"{}{}-{}-{}",
|
||||
@tagName(cross_target.arch),
|
||||
Target.archSubArchName(cross_target.arch),
|
||||
@tagName(cross_target.os),
|
||||
@tagName(cross_target.abi),
|
||||
) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn linuxTriple(cross_target: CrossTarget, allocator: *Allocator) []u8 {
|
||||
return std.fmt.allocPrint(
|
||||
allocator,
|
||||
"{}-{}-{}",
|
||||
@tagName(cross_target.arch),
|
||||
@tagName(cross_target.os),
|
||||
@tagName(cross_target.abi),
|
||||
) catch unreachable;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Target = union(enum) {
|
||||
Native: void,
|
||||
Cross: CrossTarget,
|
||||
|
||||
pub fn zigTriple(self: Target, allocator: *Allocator) ![]u8 {
|
||||
return std.fmt.allocPrint(
|
||||
allocator,
|
||||
"{}{}-{}-{}",
|
||||
@tagName(self.getArch()),
|
||||
Target.archSubArchName(self.getArch()),
|
||||
@tagName(self.getOs()),
|
||||
@tagName(self.getAbi()),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn allocDescription(self: Target, allocator: *Allocator) ![]u8 {
|
||||
// TODO is there anything else worthy of the description that is not
|
||||
// already captured in the triple?
|
||||
return self.zigTriple(allocator);
|
||||
}
|
||||
|
||||
pub fn zigTripleNoSubArch(self: Target, allocator: *Allocator) ![]u8 {
|
||||
return std.fmt.allocPrint(
|
||||
allocator,
|
||||
"{}-{}-{}",
|
||||
@tagName(self.getArch()),
|
||||
@tagName(self.getOs()),
|
||||
@tagName(self.getAbi()),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn linuxTriple(self: Target, allocator: *Allocator) ![]u8 {
|
||||
return std.fmt.allocPrint(
|
||||
allocator,
|
||||
"{}-{}-{}",
|
||||
@tagName(self.getArch()),
|
||||
@tagName(self.getOs()),
|
||||
@tagName(self.getAbi()),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn parse(text: []const u8) !Target {
|
||||
var it = mem.separate(text, "-");
|
||||
const arch_name = it.next() orelse return error.MissingArchitecture;
|
||||
const os_name = it.next() orelse return error.MissingOperatingSystem;
|
||||
const abi_name = it.next();
|
||||
|
||||
var cross = CrossTarget{
|
||||
.arch = try parseArchSub(arch_name),
|
||||
.os = try parseOs(os_name),
|
||||
.abi = undefined,
|
||||
};
|
||||
cross.abi = if (abi_name) |n| try parseAbi(n) else defaultAbi(cross.arch, cross.os);
|
||||
return Target{ .Cross = cross };
|
||||
}
|
||||
|
||||
pub fn defaultAbi(arch: builtin.Arch, target_os: builtin.Os) builtin.Abi {
|
||||
switch (arch) {
|
||||
.wasm32, .wasm64 => return .musl,
|
||||
else => {},
|
||||
}
|
||||
switch (target_os) {
|
||||
.freestanding,
|
||||
.ananas,
|
||||
.cloudabi,
|
||||
.dragonfly,
|
||||
.lv2,
|
||||
.solaris,
|
||||
.haiku,
|
||||
.minix,
|
||||
.rtems,
|
||||
.nacl,
|
||||
.cnk,
|
||||
.aix,
|
||||
.cuda,
|
||||
.nvcl,
|
||||
.amdhsa,
|
||||
.ps4,
|
||||
.elfiamcu,
|
||||
.mesa3d,
|
||||
.contiki,
|
||||
.amdpal,
|
||||
.zen,
|
||||
.hermit,
|
||||
=> return .eabi,
|
||||
.openbsd,
|
||||
.macosx,
|
||||
.freebsd,
|
||||
.ios,
|
||||
.tvos,
|
||||
.watchos,
|
||||
.fuchsia,
|
||||
.kfreebsd,
|
||||
.netbsd,
|
||||
.hurd,
|
||||
=> return .gnu,
|
||||
.windows,
|
||||
.uefi,
|
||||
=> return .msvc,
|
||||
.linux,
|
||||
.wasi,
|
||||
=> return .musl,
|
||||
}
|
||||
}
|
||||
|
||||
pub const ParseArchSubError = error{
|
||||
UnknownArchitecture,
|
||||
UnknownSubArchitecture,
|
||||
};
|
||||
|
||||
pub fn parseArchSub(text: []const u8) ParseArchSubError!builtin.Arch {
|
||||
const info = @typeInfo(builtin.Arch);
|
||||
inline for (info.Union.fields) |field| {
|
||||
if (mem.eql(u8, text, field.name)) {
|
||||
if (field.field_type == void) {
|
||||
return (builtin.Arch)(@field(builtin.Arch, field.name));
|
||||
} else {
|
||||
const sub_info = @typeInfo(field.field_type);
|
||||
inline for (sub_info.Enum.fields) |sub_field| {
|
||||
const combined = field.name ++ sub_field.name;
|
||||
if (mem.eql(u8, text, combined)) {
|
||||
return @unionInit(builtin.Arch, field.name, @field(field.field_type, sub_field.name));
|
||||
}
|
||||
}
|
||||
return error.UnknownSubArchitecture;
|
||||
}
|
||||
}
|
||||
}
|
||||
return error.UnknownArchitecture;
|
||||
}
|
||||
|
||||
pub fn parseOs(text: []const u8) !builtin.Os {
|
||||
const info = @typeInfo(builtin.Os);
|
||||
inline for (info.Enum.fields) |field| {
|
||||
if (mem.eql(u8, text, field.name)) {
|
||||
return @field(builtin.Os, field.name);
|
||||
}
|
||||
}
|
||||
return error.UnknownOperatingSystem;
|
||||
}
|
||||
|
||||
pub fn parseAbi(text: []const u8) !builtin.Abi {
|
||||
const info = @typeInfo(builtin.Abi);
|
||||
inline for (info.Enum.fields) |field| {
|
||||
if (mem.eql(u8, text, field.name)) {
|
||||
return @field(builtin.Abi, field.name);
|
||||
}
|
||||
}
|
||||
return error.UnknownApplicationBinaryInterface;
|
||||
}
|
||||
|
||||
fn archSubArchName(arch: builtin.Arch) []const u8 {
|
||||
return switch (arch) {
|
||||
builtin.Arch.arm => |sub| @tagName(sub),
|
||||
builtin.Arch.armeb => |sub| @tagName(sub),
|
||||
builtin.Arch.thumb => |sub| @tagName(sub),
|
||||
builtin.Arch.thumbeb => |sub| @tagName(sub),
|
||||
builtin.Arch.aarch64 => |sub| @tagName(sub),
|
||||
builtin.Arch.aarch64_be => |sub| @tagName(sub),
|
||||
builtin.Arch.kalimba => |sub| @tagName(sub),
|
||||
.arm => |sub| @tagName(sub),
|
||||
.armeb => |sub| @tagName(sub),
|
||||
.thumb => |sub| @tagName(sub),
|
||||
.thumbeb => |sub| @tagName(sub),
|
||||
.aarch64 => |sub| @tagName(sub),
|
||||
.aarch64_be => |sub| @tagName(sub),
|
||||
.kalimba => |sub| @tagName(sub),
|
||||
else => "",
|
||||
};
|
||||
}
|
||||
|
||||
pub fn subArchName(self: Target) []const u8 {
|
||||
switch (self) {
|
||||
Target.Native => return archSubArchName(builtin.arch),
|
||||
Target.Cross => |cross| return archSubArchName(cross.arch),
|
||||
.Native => return archSubArchName(builtin.arch),
|
||||
.Cross => |cross| return archSubArchName(cross.arch),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn oFileExt(self: Target) []const u8 {
|
||||
const abi = switch (self) {
|
||||
Target.Native => builtin.abi,
|
||||
Target.Cross => |t| t.abi,
|
||||
.Native => builtin.abi,
|
||||
.Cross => |t| t.abi,
|
||||
};
|
||||
return switch (abi) {
|
||||
builtin.Abi.msvc => ".obj",
|
||||
@ -942,15 +1090,22 @@ pub const Target = union(enum) {
|
||||
|
||||
pub fn getOs(self: Target) builtin.Os {
|
||||
return switch (self) {
|
||||
Target.Native => builtin.os,
|
||||
Target.Cross => |t| t.os,
|
||||
.Native => builtin.os,
|
||||
.Cross => |t| t.os,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getArch(self: Target) builtin.Arch {
|
||||
switch (self) {
|
||||
Target.Native => return builtin.arch,
|
||||
Target.Cross => |t| return t.arch,
|
||||
.Native => return builtin.arch,
|
||||
.Cross => |t| return t.arch,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getAbi(self: Target) builtin.Abi {
|
||||
switch (self) {
|
||||
.Native => return builtin.abi,
|
||||
.Cross => |t| return t.abi,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1206,19 +1361,24 @@ pub const LibExeObjStep = struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// Deprecated. Use `setTheTarget`.
|
||||
pub fn setTarget(
|
||||
self: *LibExeObjStep,
|
||||
target_arch: builtin.Arch,
|
||||
target_os: builtin.Os,
|
||||
target_abi: builtin.Abi,
|
||||
) void {
|
||||
self.target = Target{
|
||||
return self.setTheTarget(Target{
|
||||
.Cross = CrossTarget{
|
||||
.arch = target_arch,
|
||||
.os = target_os,
|
||||
.abi = target_abi,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
pub fn setTheTarget(self: *LibExeObjStep, target: Target) void {
|
||||
self.target = target;
|
||||
self.computeOutFileNames();
|
||||
}
|
||||
|
||||
@ -1595,9 +1755,9 @@ pub const LibExeObjStep = struct {
|
||||
|
||||
switch (self.target) {
|
||||
Target.Native => {},
|
||||
Target.Cross => |cross_target| {
|
||||
Target.Cross => {
|
||||
try zig_args.append("-target");
|
||||
try zig_args.append(cross_target.zigTriple(builder.allocator));
|
||||
try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user