authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-09 13:31:42-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-09 13:31:42-04:00
logae2345b742053a84e1f64f92b76202702ac872d9
tree969498d967a38d6db7afa56426797d399e04afea
parent038946288cf25e430d1ebfee014847470e0f65ba
signature Commit is signed but in an unrecognized format.

zig build: add standardTargetOptions and deprecate setTarget

in favor of setTheTarget

1 files changed, 200 insertions(+), 40 deletions(-)

std/build.zig+200-40
...@@ -380,10 +380,12 @@ pub const Builder = struct {...@@ -380,10 +380,12 @@ pub const Builder = struct {
380 switch (builtin.os) {380 switch (builtin.os) {
381 .windows => {},381 .windows => {},
382 else => {382 else => {
383 const triple = (CrossTarget{383 const triple = (Target{
384 .arch = builtin.arch,384 .Cross = CrossTarget{
385 .os = builtin.os,385 .arch = builtin.arch,
386 .abi = builtin.abi,386 .os = builtin.os,
387 .abi = builtin.abi,
388 },
387 }).linuxTriple(self.allocator);389 }).linuxTriple(self.allocator);
388390
389 // TODO: $ ld --verbose | grep SEARCH_DIR391 // TODO: $ ld --verbose | grep SEARCH_DIR
...@@ -507,6 +509,26 @@ pub const Builder = struct {...@@ -507,6 +509,26 @@ pub const Builder = struct {
507 return mode;509 return mode;
508 }510 }
509511
512 /// Exposes standard `zig build` options for choosing a target. Pass `null` to support all targets.
513 pub fn standardTargetOptions(self: *Builder, supported_targets: ?[]const Target) Target {
514 if (supported_targets) |target_list| {
515 // TODO detect multiple args and emit an error message
516 // there's probably a better way to collect the target
517 for (target_list) |targ| {
518 const targ_str = targ.zigTriple(self.allocator) catch unreachable;
519 const targ_desc = targ.allocDescription(self.allocator) catch unreachable;
520 const this_targ_opt = self.option(bool, targ_str, targ_desc) orelse false;
521 if (this_targ_opt) {
522 return targ;
523 }
524 }
525 return Target.Native;
526 } else {
527 const target_str = self.option([]const u8, "target", "the target to build for") orelse return Target.Native;
528 return Target.parse(target_str) catch unreachable; // TODO better error message for bad target
529 }
530 }
531
510 pub fn addUserInputOption(self: *Builder, name: []const u8, value: []const u8) !bool {532 pub fn addUserInputOption(self: *Builder, name: []const u8, value: []const u8) !bool {
511 const gop = try self.user_input_options.getOrPut(name);533 const gop = try self.user_input_options.getOrPut(name);
512 if (!gop.found_existing) {534 if (!gop.found_existing) {
...@@ -858,67 +880,193 @@ pub const Builder = struct {...@@ -858,67 +880,193 @@ pub const Builder = struct {
858 }880 }
859};881};
860882
861const Version = struct {883pub const Version = struct {
862 major: u32,884 major: u32,
863 minor: u32,885 minor: u32,
864 patch: u32,886 patch: u32,
865};887};
866888
867const CrossTarget = struct {889pub const CrossTarget = struct {
868 arch: builtin.Arch,890 arch: builtin.Arch,
869 os: builtin.Os,891 os: builtin.Os,
870 abi: builtin.Abi,892 abi: builtin.Abi,
893};
894
895pub const Target = union(enum) {
896 Native: void,
897 Cross: CrossTarget,
871898
872 pub fn zigTriple(cross_target: CrossTarget, allocator: *Allocator) []u8 {899 pub fn zigTriple(self: Target, allocator: *Allocator) ![]u8 {
873 return std.fmt.allocPrint(900 return std.fmt.allocPrint(
874 allocator,901 allocator,
875 "{}{}-{}-{}",902 "{}{}-{}-{}",
876 @tagName(cross_target.arch),903 @tagName(self.getArch()),
877 Target.archSubArchName(cross_target.arch),904 Target.archSubArchName(self.getArch()),
878 @tagName(cross_target.os),905 @tagName(self.getOs()),
879 @tagName(cross_target.abi),906 @tagName(self.getAbi()),
880 ) catch unreachable;907 );
908 }
909
910 pub fn allocDescription(self: Target, allocator: *Allocator) ![]u8 {
911 // TODO is there anything else worthy of the description that is not
912 // already captured in the triple?
913 return self.zigTriple(allocator);
881 }914 }
882915
883 pub fn linuxTriple(cross_target: CrossTarget, allocator: *Allocator) []u8 {916 pub fn zigTripleNoSubArch(self: Target, allocator: *Allocator) ![]u8 {
884 return std.fmt.allocPrint(917 return std.fmt.allocPrint(
885 allocator,918 allocator,
886 "{}-{}-{}",919 "{}-{}-{}",
887 @tagName(cross_target.arch),920 @tagName(self.getArch()),
888 @tagName(cross_target.os),921 @tagName(self.getOs()),
889 @tagName(cross_target.abi),922 @tagName(self.getAbi()),
890 ) catch unreachable;923 );
891 }924 }
892};
893925
894pub const Target = union(enum) {926 pub fn linuxTriple(self: Target, allocator: *Allocator) ![]u8 {
895 Native: void,927 return std.fmt.allocPrint(
896 Cross: CrossTarget,928 allocator,
929 "{}-{}-{}",
930 @tagName(self.getArch()),
931 @tagName(self.getOs()),
932 @tagName(self.getAbi()),
933 );
934 }
935
936 pub fn parse(text: []const u8) !Target {
937 var it = mem.separate(text, "-");
938 const arch_name = it.next() orelse return error.MissingArchitecture;
939 const os_name = it.next() orelse return error.MissingOperatingSystem;
940 const abi_name = it.next();
941
942 var cross = CrossTarget{
943 .arch = try parseArchSub(arch_name),
944 .os = try parseOs(os_name),
945 .abi = undefined,
946 };
947 cross.abi = if (abi_name) |n| try parseAbi(n) else defaultAbi(cross.arch, cross.os);
948 return Target{ .Cross = cross };
949 }
950
951 pub fn defaultAbi(arch: builtin.Arch, target_os: builtin.Os) builtin.Abi {
952 switch (arch) {
953 .wasm32, .wasm64 => return .musl,
954 else => {},
955 }
956 switch (target_os) {
957 .freestanding,
958 .ananas,
959 .cloudabi,
960 .dragonfly,
961 .lv2,
962 .solaris,
963 .haiku,
964 .minix,
965 .rtems,
966 .nacl,
967 .cnk,
968 .aix,
969 .cuda,
970 .nvcl,
971 .amdhsa,
972 .ps4,
973 .elfiamcu,
974 .mesa3d,
975 .contiki,
976 .amdpal,
977 .zen,
978 .hermit,
979 => return .eabi,
980 .openbsd,
981 .macosx,
982 .freebsd,
983 .ios,
984 .tvos,
985 .watchos,
986 .fuchsia,
987 .kfreebsd,
988 .netbsd,
989 .hurd,
990 => return .gnu,
991 .windows,
992 .uefi,
993 => return .msvc,
994 .linux,
995 .wasi,
996 => return .musl,
997 }
998 }
999
1000 pub const ParseArchSubError = error{
1001 UnknownArchitecture,
1002 UnknownSubArchitecture,
1003 };
1004
1005 pub fn parseArchSub(text: []const u8) ParseArchSubError!builtin.Arch {
1006 const info = @typeInfo(builtin.Arch);
1007 inline for (info.Union.fields) |field| {
1008 if (mem.eql(u8, text, field.name)) {
1009 if (field.field_type == void) {
1010 return (builtin.Arch)(@field(builtin.Arch, field.name));
1011 } else {
1012 const sub_info = @typeInfo(field.field_type);
1013 inline for (sub_info.Enum.fields) |sub_field| {
1014 const combined = field.name ++ sub_field.name;
1015 if (mem.eql(u8, text, combined)) {
1016 return @unionInit(builtin.Arch, field.name, @field(field.field_type, sub_field.name));
1017 }
1018 }
1019 return error.UnknownSubArchitecture;
1020 }
1021 }
1022 }
1023 return error.UnknownArchitecture;
1024 }
1025
1026 pub fn parseOs(text: []const u8) !builtin.Os {
1027 const info = @typeInfo(builtin.Os);
1028 inline for (info.Enum.fields) |field| {
1029 if (mem.eql(u8, text, field.name)) {
1030 return @field(builtin.Os, field.name);
1031 }
1032 }
1033 return error.UnknownOperatingSystem;
1034 }
1035
1036 pub fn parseAbi(text: []const u8) !builtin.Abi {
1037 const info = @typeInfo(builtin.Abi);
1038 inline for (info.Enum.fields) |field| {
1039 if (mem.eql(u8, text, field.name)) {
1040 return @field(builtin.Abi, field.name);
1041 }
1042 }
1043 return error.UnknownApplicationBinaryInterface;
1044 }
8971045
898 fn archSubArchName(arch: builtin.Arch) []const u8 {1046 fn archSubArchName(arch: builtin.Arch) []const u8 {
899 return switch (arch) {1047 return switch (arch) {
900 builtin.Arch.arm => |sub| @tagName(sub),1048 .arm => |sub| @tagName(sub),
901 builtin.Arch.armeb => |sub| @tagName(sub),1049 .armeb => |sub| @tagName(sub),
902 builtin.Arch.thumb => |sub| @tagName(sub),1050 .thumb => |sub| @tagName(sub),
903 builtin.Arch.thumbeb => |sub| @tagName(sub),1051 .thumbeb => |sub| @tagName(sub),
904 builtin.Arch.aarch64 => |sub| @tagName(sub),1052 .aarch64 => |sub| @tagName(sub),
905 builtin.Arch.aarch64_be => |sub| @tagName(sub),1053 .aarch64_be => |sub| @tagName(sub),
906 builtin.Arch.kalimba => |sub| @tagName(sub),1054 .kalimba => |sub| @tagName(sub),
907 else => "",1055 else => "",
908 };1056 };
909 }1057 }
9101058
911 pub fn subArchName(self: Target) []const u8 {1059 pub fn subArchName(self: Target) []const u8 {
912 switch (self) {1060 switch (self) {
913 Target.Native => return archSubArchName(builtin.arch),1061 .Native => return archSubArchName(builtin.arch),
914 Target.Cross => |cross| return archSubArchName(cross.arch),1062 .Cross => |cross| return archSubArchName(cross.arch),
915 }1063 }
916 }1064 }
9171065
918 pub fn oFileExt(self: Target) []const u8 {1066 pub fn oFileExt(self: Target) []const u8 {
919 const abi = switch (self) {1067 const abi = switch (self) {
920 Target.Native => builtin.abi,1068 .Native => builtin.abi,
921 Target.Cross => |t| t.abi,1069 .Cross => |t| t.abi,
922 };1070 };
923 return switch (abi) {1071 return switch (abi) {
924 builtin.Abi.msvc => ".obj",1072 builtin.Abi.msvc => ".obj",
...@@ -942,15 +1090,22 @@ pub const Target = union(enum) {...@@ -942,15 +1090,22 @@ pub const Target = union(enum) {
9421090
943 pub fn getOs(self: Target) builtin.Os {1091 pub fn getOs(self: Target) builtin.Os {
944 return switch (self) {1092 return switch (self) {
945 Target.Native => builtin.os,1093 .Native => builtin.os,
946 Target.Cross => |t| t.os,1094 .Cross => |t| t.os,
947 };1095 };
948 }1096 }
9491097
950 pub fn getArch(self: Target) builtin.Arch {1098 pub fn getArch(self: Target) builtin.Arch {
951 switch (self) {1099 switch (self) {
952 Target.Native => return builtin.arch,1100 .Native => return builtin.arch,
953 Target.Cross => |t| return t.arch,1101 .Cross => |t| return t.arch,
1102 }
1103 }
1104
1105 pub fn getAbi(self: Target) builtin.Abi {
1106 switch (self) {
1107 .Native => return builtin.abi,
1108 .Cross => |t| return t.abi,
954 }1109 }
955 }1110 }
9561111
...@@ -1206,19 +1361,24 @@ pub const LibExeObjStep = struct {...@@ -1206,19 +1361,24 @@ pub const LibExeObjStep = struct {
1206 }1361 }
1207 }1362 }
12081363
1364 /// Deprecated. Use `setTheTarget`.
1209 pub fn setTarget(1365 pub fn setTarget(
1210 self: *LibExeObjStep,1366 self: *LibExeObjStep,
1211 target_arch: builtin.Arch,1367 target_arch: builtin.Arch,
1212 target_os: builtin.Os,1368 target_os: builtin.Os,
1213 target_abi: builtin.Abi,1369 target_abi: builtin.Abi,
1214 ) void {1370 ) void {
1215 self.target = Target{1371 return self.setTheTarget(Target{
1216 .Cross = CrossTarget{1372 .Cross = CrossTarget{
1217 .arch = target_arch,1373 .arch = target_arch,
1218 .os = target_os,1374 .os = target_os,
1219 .abi = target_abi,1375 .abi = target_abi,
1220 },1376 },
1221 };1377 });
1378 }
1379
1380 pub fn setTheTarget(self: *LibExeObjStep, target: Target) void {
1381 self.target = target;
1222 self.computeOutFileNames();1382 self.computeOutFileNames();
1223 }1383 }
12241384
...@@ -1595,9 +1755,9 @@ pub const LibExeObjStep = struct {...@@ -1595,9 +1755,9 @@ pub const LibExeObjStep = struct {
15951755
1596 switch (self.target) {1756 switch (self.target) {
1597 Target.Native => {},1757 Target.Native => {},
1598 Target.Cross => |cross_target| {1758 Target.Cross => {
1599 try zig_args.append("-target");1759 try zig_args.append("-target");
1600 try zig_args.append(cross_target.zigTriple(builder.allocator));1760 try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
1601 },1761 },
1602 }1762 }
16031763