aboutsummaryrefslogtreecommitdiff
path: root/lib/std/build.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-03-03 09:44:13 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-03-03 09:44:13 -0500
commitd1cb16aace5f5996cf2556d07fd3418a951b31df (patch)
treee154f475be8de6f0b0c486cf1baa1557c3f12b65 /lib/std/build.zig
parent3418a332ab3a120f21354d98579d7a3a2dcb523b (diff)
parent387418277a4964714ddaec3336a602ec87dde0f9 (diff)
downloadzig-d1cb16aace5f5996cf2556d07fd3418a951b31df.tar.gz
zig-d1cb16aace5f5996cf2556d07fd3418a951b31df.zip
Merge remote-tracking branch 'origin/master' into llvm10
Diffstat (limited to 'lib/std/build.zig')
-rw-r--r--lib/std/build.zig247
1 files changed, 137 insertions, 110 deletions
diff --git a/lib/std/build.zig b/lib/std/build.zig
index 29837d56d9..ecf3930551 100644
--- a/lib/std/build.zig
+++ b/lib/std/build.zig
@@ -1,5 +1,5 @@
const std = @import("std.zig");
-const builtin = @import("builtin");
+const builtin = std.builtin;
const io = std.io;
const fs = std.fs;
const mem = std.mem;
@@ -15,6 +15,7 @@ const BufSet = std.BufSet;
const BufMap = std.BufMap;
const fmt_lib = std.fmt;
const File = std.fs.File;
+const CrossTarget = std.zig.CrossTarget;
pub const FmtStep = @import("build/fmt.zig").FmtStep;
pub const TranslateCStep = @import("build/translate_c.zig").TranslateCStep;
@@ -521,24 +522,91 @@ 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;
+ pub const StandardTargetOptionsArgs = struct {
+ whitelist: ?[]const CrossTarget = null,
+
+ default_target: CrossTarget = CrossTarget{},
+ };
+
+ /// Exposes standard `zig build` options for choosing a target.
+ pub fn standardTargetOptions(self: *Builder, args: StandardTargetOptionsArgs) CrossTarget {
+ const triple = self.option(
+ []const u8,
+ "target",
+ "The CPU architecture, OS, and ABI to build for.",
+ ) orelse return args.default_target;
+
+ // TODO add cpu and features as part of the target triple
+
+ var diags: CrossTarget.ParseOptions.Diagnostics = .{};
+ const selected_target = CrossTarget.parse(.{
+ .arch_os_abi = triple,
+ .diagnostics = &diags,
+ }) catch |err| switch (err) {
+ error.UnknownCpuModel => {
+ std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{
+ diags.cpu_name.?,
+ @tagName(diags.arch.?),
+ });
+ for (diags.arch.?.allCpuModels()) |cpu| {
+ std.debug.warn(" {}\n", .{cpu.name});
+ }
+ process.exit(1);
+ },
+ error.UnknownCpuFeature => {
+ std.debug.warn(
+ \\Unknown CPU feature: '{}'
+ \\Available CPU features for architecture '{}':
+ \\
+ , .{
+ diags.unknown_feature_name,
+ @tagName(diags.arch.?),
+ });
+ for (diags.arch.?.allFeaturesList()) |feature| {
+ std.debug.warn(" {}: {}\n", .{ feature.name, feature.description });
+ }
+ process.exit(1);
+ },
+ error.UnknownOperatingSystem => {
+ std.debug.warn(
+ \\Unknown OS: '{}'
+ \\Available operating systems:
+ \\
+ , .{diags.os_name});
+ inline for (std.meta.fields(std.Target.Os.Tag)) |field| {
+ std.debug.warn(" {}\n", .{field.name});
+ }
+ process.exit(1);
+ },
+ else => |e| {
+ std.debug.warn("Unable to parse target '{}': {}\n", .{ triple, @errorName(e) });
+ process.exit(1);
+ },
+ };
+
+ const selected_canonicalized_triple = selected_target.zigTriple(self.allocator) catch unreachable;
+
+ if (args.whitelist) |list| whitelist_check: {
+ // Make sure it's a match of one of the list.
+ for (list) |t| {
+ const t_triple = t.zigTriple(self.allocator) catch unreachable;
+ if (mem.eql(u8, t_triple, selected_canonicalized_triple)) {
+ break :whitelist_check;
}
}
- return Target.Native;
- } else {
- const target_str = self.option([]const u8, "target", "the target to build for") orelse return Target.Native;
- return Target.parse(.{ .arch_os_abi = target_str }) catch unreachable; // TODO better error message for bad target
+ std.debug.warn("Chosen target '{}' does not match one of the supported targets:\n", .{
+ selected_canonicalized_triple,
+ });
+ for (list) |t| {
+ const t_triple = t.zigTriple(self.allocator) catch unreachable;
+ std.debug.warn(" {}\n", .{t_triple});
+ }
+ // TODO instead of process exit, return error and have a zig build flag implemented by
+ // the build runner that turns process exits into error return traces
+ process.exit(1);
}
+
+ return selected_target;
}
pub fn addUserInputOption(self: *Builder, name: []const u8, value: []const u8) !bool {
@@ -796,7 +864,7 @@ pub const Builder = struct {
pub fn findProgram(self: *Builder, names: []const []const u8, paths: []const []const u8) ![]const u8 {
// TODO report error for ambiguous situations
- const exe_extension = (Target{ .Native = {} }).exeFileExt();
+ const exe_extension = @as(CrossTarget, .{}).exeFileExt();
for (self.search_prefixes.toSliceConst()) |search_prefix| {
for (names) |name| {
if (fs.path.isAbsolute(name)) {
@@ -971,21 +1039,19 @@ pub const Builder = struct {
};
test "builder.findProgram compiles" {
- // TODO: uncomment and fix the leak
- // const builder = try Builder.create(std.testing.allocator, "zig", "zig-cache", "zig-cache");
- const builder = try Builder.create(std.heap.page_allocator, "zig", "zig-cache", "zig-cache");
+ var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+ defer arena.deinit();
+
+ const builder = try Builder.create(&arena.allocator, "zig", "zig-cache", "zig-cache");
defer builder.destroy();
_ = builder.findProgram(&[_][]const u8{}, &[_][]const u8{}) catch null;
}
-/// Deprecated. Use `builtin.Version`.
+/// Deprecated. Use `std.builtin.Version`.
pub const Version = builtin.Version;
-/// Deprecated. Use `std.Target.Cross`.
-pub const CrossTarget = std.Target.Cross;
-
-/// Deprecated. Use `std.Target`.
-pub const Target = std.Target;
+/// Deprecated. Use `std.zig.CrossTarget`.
+pub const Target = std.zig.CrossTarget;
pub const Pkg = struct {
name: []const u8,
@@ -1038,7 +1104,7 @@ pub const LibExeObjStep = struct {
step: Step,
builder: *Builder,
name: []const u8,
- target: Target,
+ target: CrossTarget = CrossTarget{},
linker_script: ?[]const u8 = null,
version_script: ?[]const u8 = null,
out_filename: []const u8,
@@ -1076,7 +1142,7 @@ pub const LibExeObjStep = struct {
out_pdb_filename: []const u8,
packages: ArrayList(Pkg),
build_options_contents: std.Buffer,
- system_linker_hack: bool,
+ system_linker_hack: bool = false,
object_src: []const u8,
@@ -1091,7 +1157,6 @@ pub const LibExeObjStep = struct {
install_step: ?*InstallArtifactStep,
libc_file: ?[]const u8 = null,
- target_glibc: ?Version = null,
valgrind_support: ?bool = null,
@@ -1112,8 +1177,6 @@ pub const LibExeObjStep = struct {
/// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`.
glibc_multi_install_dir: ?[]const u8 = null,
- dynamic_linker: ?[]const u8 = null,
-
/// Position Independent Code
force_pic: ?bool = null,
@@ -1191,7 +1254,6 @@ pub const LibExeObjStep = struct {
.kind = kind,
.root_src = root_src,
.name = name,
- .target = Target.Native,
.frameworks = BufSet.init(builder.allocator),
.step = Step.init(name, builder.allocator, make),
.version = ver,
@@ -1210,7 +1272,6 @@ pub const LibExeObjStep = struct {
.object_src = undefined,
.build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable,
.c_std = Builder.CStd.C99,
- .system_linker_hack = false,
.override_lib_dir = null,
.main_pkg_path = null,
.exec_cmd_args = null,
@@ -1282,36 +1343,11 @@ 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 {
- return self.setTheTarget(Target{
- .Cross = CrossTarget{
- .arch = target_arch,
- .os = target_os,
- .abi = target_abi,
- .cpu_features = target_arch.getBaselineCpuFeatures(),
- },
- });
- }
-
- pub fn setTheTarget(self: *LibExeObjStep, target: Target) void {
+ pub fn setTarget(self: *LibExeObjStep, target: CrossTarget) void {
self.target = target;
self.computeOutFileNames();
}
- pub fn setTargetGLibC(self: *LibExeObjStep, major: u32, minor: u32, patch: u32) void {
- self.target_glibc = Version{
- .major = major,
- .minor = minor,
- .patch = patch,
- };
- }
-
pub fn setOutputDir(self: *LibExeObjStep, dir: []const u8) void {
self.output_dir = self.builder.dupePath(dir);
}
@@ -1692,7 +1728,7 @@ pub const LibExeObjStep = struct {
.NotFound => return error.VcpkgNotFound,
.Found => |root| {
const allocator = self.builder.allocator;
- const triplet = try Target.vcpkgTriplet(allocator, self.target, linkage);
+ const triplet = try self.target.vcpkgTriplet(allocator, linkage);
defer self.builder.allocator.free(triplet);
const include_path = try fs.path.join(allocator, &[_][]const u8{ root, "installed", triplet, "include" });
@@ -1862,10 +1898,10 @@ pub const LibExeObjStep = struct {
}
switch (self.build_mode) {
- builtin.Mode.Debug => {},
- builtin.Mode.ReleaseSafe => zig_args.append("--release-safe") catch unreachable,
- builtin.Mode.ReleaseFast => zig_args.append("--release-fast") catch unreachable,
- builtin.Mode.ReleaseSmall => zig_args.append("--release-small") catch unreachable,
+ .Debug => {},
+ .ReleaseSafe => zig_args.append("--release-safe") catch unreachable,
+ .ReleaseFast => zig_args.append("--release-fast") catch unreachable,
+ .ReleaseSmall => zig_args.append("--release-small") catch unreachable,
}
try zig_args.append("--cache-dir");
@@ -1905,47 +1941,46 @@ pub const LibExeObjStep = struct {
try zig_args.append(@tagName(self.code_model));
}
- switch (self.target) {
- .Native => {},
- .Cross => |cross| {
- try zig_args.append("-target");
- try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
+ if (!self.target.isNative()) {
+ try zig_args.append("-target");
+ try zig_args.append(try self.target.zigTriple(builder.allocator));
- const all_features = self.target.getArch().allFeaturesList();
- var populated_cpu_features = cross.cpu.model.features;
- populated_cpu_features.populateDependencies(all_features);
+ // TODO this logic can disappear if cpu model + features becomes part of the target triple
+ const cross = self.target.toTarget();
+ const all_features = cross.cpu.arch.allFeaturesList();
+ var populated_cpu_features = cross.cpu.model.features;
+ populated_cpu_features.populateDependencies(all_features);
- if (populated_cpu_features.eql(cross.cpu.features)) {
- // The CPU name alone is sufficient.
- // If it is the baseline CPU, no command line args are required.
- if (cross.cpu.model != Target.Cpu.baseline(self.target.getArch()).model) {
- try zig_args.append("-mcpu");
- try zig_args.append(cross.cpu.model.name);
- }
- } else {
- var mcpu_buffer = try std.Buffer.init(builder.allocator, "-mcpu=");
- try mcpu_buffer.append(cross.cpu.model.name);
-
- for (all_features) |feature, i_usize| {
- const i = @intCast(Target.Cpu.Feature.Set.Index, i_usize);
- const in_cpu_set = populated_cpu_features.isEnabled(i);
- const in_actual_set = cross.cpu.features.isEnabled(i);
- if (in_cpu_set and !in_actual_set) {
- try mcpu_buffer.appendByte('-');
- try mcpu_buffer.append(feature.name);
- } else if (!in_cpu_set and in_actual_set) {
- try mcpu_buffer.appendByte('+');
- try mcpu_buffer.append(feature.name);
- }
+ if (populated_cpu_features.eql(cross.cpu.features)) {
+ // The CPU name alone is sufficient.
+ // If it is the baseline CPU, no command line args are required.
+ if (cross.cpu.model != std.Target.Cpu.baseline(cross.cpu.arch).model) {
+ try zig_args.append("-mcpu");
+ try zig_args.append(cross.cpu.model.name);
+ }
+ } else {
+ var mcpu_buffer = try std.Buffer.init(builder.allocator, "-mcpu=");
+ try mcpu_buffer.append(cross.cpu.model.name);
+
+ for (all_features) |feature, i_usize| {
+ const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize);
+ const in_cpu_set = populated_cpu_features.isEnabled(i);
+ const in_actual_set = cross.cpu.features.isEnabled(i);
+ if (in_cpu_set and !in_actual_set) {
+ try mcpu_buffer.appendByte('-');
+ try mcpu_buffer.append(feature.name);
+ } else if (!in_cpu_set and in_actual_set) {
+ try mcpu_buffer.appendByte('+');
+ try mcpu_buffer.append(feature.name);
}
- try zig_args.append(mcpu_buffer.toSliceConst());
}
- },
- }
+ try zig_args.append(mcpu_buffer.toSliceConst());
+ }
- if (self.target_glibc) |ver| {
- try zig_args.append("-target-glibc");
- try zig_args.append(builder.fmt("{}.{}.{}", .{ ver.major, ver.minor, ver.patch }));
+ if (self.target.dynamic_linker.get()) |dynamic_linker| {
+ try zig_args.append("--dynamic-linker");
+ try zig_args.append(dynamic_linker);
+ }
}
if (self.linker_script) |linker_script| {
@@ -1953,11 +1988,6 @@ pub const LibExeObjStep = struct {
zig_args.append(builder.pathFromRoot(linker_script)) catch unreachable;
}
- if (self.dynamic_linker) |dynamic_linker| {
- try zig_args.append("--dynamic-linker");
- try zig_args.append(dynamic_linker);
- }
-
if (self.version_script) |version_script| {
try zig_args.append("--version-script");
try zig_args.append(builder.pathFromRoot(version_script));
@@ -1975,7 +2005,7 @@ pub const LibExeObjStep = struct {
} else switch (self.target.getExternalExecutor()) {
.native, .unavailable => {},
.qemu => |bin_name| if (self.enable_qemu) qemu: {
- const need_cross_glibc = self.target.isGnu() and self.target.isLinux() and self.is_linking_libc;
+ const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc;
const glibc_dir_arg = if (need_cross_glibc)
self.glibc_multi_install_dir orelse break :qemu
else
@@ -2420,10 +2450,7 @@ const VcpkgRootStatus = enum {
Found,
};
-pub const VcpkgLinkage = enum {
- Static,
- Dynamic,
-};
+pub const VcpkgLinkage = std.builtin.LinkMode;
pub const InstallDir = enum {
Prefix,