aboutsummaryrefslogtreecommitdiff
path: root/lib/std/Build
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std/Build')
-rw-r--r--lib/std/Build/Cache/DepTokenizer.zig64
-rw-r--r--lib/std/Build/Module.zig9
-rw-r--r--lib/std/Build/Step.zig1
-rw-r--r--lib/std/Build/Step/CheckObject.zig2
-rw-r--r--lib/std/Build/Step/Compile.zig25
-rw-r--r--lib/std/Build/Step/Run.zig29
-rw-r--r--lib/std/Build/Watch.zig16
7 files changed, 127 insertions, 19 deletions
diff --git a/lib/std/Build/Cache/DepTokenizer.zig b/lib/std/Build/Cache/DepTokenizer.zig
index ccd7f82fdf..a1e64c006d 100644
--- a/lib/std/Build/Cache/DepTokenizer.zig
+++ b/lib/std/Build/Cache/DepTokenizer.zig
@@ -25,7 +25,7 @@ pub fn next(self: *Tokenizer) ?Token {
},
},
.target => switch (char) {
- '\t', '\n', '\r', ' ' => {
+ '\n', '\r' => {
return errorIllegalChar(.invalid_target, self.index, char);
},
'$' => {
@@ -40,6 +40,15 @@ pub fn next(self: *Tokenizer) ?Token {
self.state = .target_colon;
self.index += 1;
},
+ '\t', ' ' => {
+ self.state = .target_space;
+
+ const bytes = self.bytes[start..self.index];
+ std.debug.assert(bytes.len != 0);
+ self.index += 1;
+
+ return finishTarget(must_resolve, bytes);
+ },
else => {
self.index += 1;
},
@@ -110,6 +119,19 @@ pub fn next(self: *Tokenizer) ?Token {
self.state = .target;
},
},
+ .target_space => switch (char) {
+ '\t', ' ' => {
+ // silently ignore additional horizontal whitespace
+ self.index += 1;
+ },
+ ':' => {
+ self.state = .rhs;
+ self.index += 1;
+ },
+ else => {
+ return errorIllegalChar(.expected_colon, self.index, char);
+ },
+ },
.rhs => switch (char) {
'\t', ' ' => {
// silently ignore horizontal whitespace
@@ -256,6 +278,10 @@ pub fn next(self: *Tokenizer) ?Token {
self.state = .lhs;
return null;
},
+ .target_space => {
+ const idx = self.index - 1;
+ return errorIllegalChar(.expected_colon, idx, self.bytes[idx]);
+ },
.prereq_quote => {
return errorPosition(.incomplete_quoted_prerequisite, start, self.bytes[start..]);
},
@@ -299,6 +325,7 @@ const State = enum {
target_dollar_sign,
target_colon,
target_colon_reverse_solidus,
+ target_space,
rhs,
rhs_continuation,
rhs_continuation_linefeed,
@@ -322,6 +349,7 @@ pub const Token = union(enum) {
expected_dollar_sign: IndexAndChar,
continuation_eol: IndexAndChar,
incomplete_escape: IndexAndChar,
+ expected_colon: IndexAndChar,
pub const IndexAndChar = struct {
index: usize,
@@ -420,6 +448,7 @@ pub const Token = union(enum) {
.expected_dollar_sign,
.continuation_eol,
.incomplete_escape,
+ .expected_colon,
=> |index_and_char| {
try writer.writeAll("illegal char ");
try printUnderstandableChar(writer, index_and_char.char);
@@ -438,6 +467,7 @@ pub const Token = union(enum) {
.expected_dollar_sign => "expecting '$'",
.continuation_eol => "continuation expecting end-of-line",
.incomplete_escape => "incomplete escape",
+ .expected_colon => "expecting ':'",
};
}
};
@@ -545,6 +575,16 @@ test "empty target linefeeds + hspace + continuations" {
, expect);
}
+test "empty target + hspace + colon" {
+ const expect = "target = {foo.o}";
+
+ try depTokenizer("foo.o :", expect);
+ try depTokenizer("foo.o\t\t\t:", expect);
+ try depTokenizer("foo.o \t \t :", expect);
+ try depTokenizer("\r\nfoo.o :", expect);
+ try depTokenizer(" foo.o :", expect);
+}
+
test "prereq" {
const expect =
\\target = {foo.o}
@@ -923,9 +963,6 @@ test "error illegal char at position - expecting dollar_sign" {
}
test "error illegal char at position - invalid target" {
- try depTokenizer("foo\t.o",
- \\ERROR: illegal char \x09 at position 3: invalid target
- );
try depTokenizer("foo\n.o",
\\ERROR: illegal char \x0A at position 3: invalid target
);
@@ -963,6 +1000,25 @@ test "error prereq - continuation expecting end-of-line" {
);
}
+test "error illegal char at position - expecting colon" {
+ try depTokenizer("foo\t.o:",
+ \\target = {foo}
+ \\ERROR: illegal char '.' at position 4: expecting ':'
+ );
+ try depTokenizer("foo .o:",
+ \\target = {foo}
+ \\ERROR: illegal char '.' at position 4: expecting ':'
+ );
+ try depTokenizer("foo \n.o:",
+ \\target = {foo}
+ \\ERROR: illegal char \x0A at position 4: expecting ':'
+ );
+ try depTokenizer("foo.o\t\n:",
+ \\target = {foo.o}
+ \\ERROR: illegal char \x0A at position 6: expecting ':'
+ );
+}
+
// - tokenize input, emit textual representation, and compare to expect
fn depTokenizer(input: []const u8, expect: []const u8) !void {
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
diff --git a/lib/std/Build/Module.zig b/lib/std/Build/Module.zig
index f299946731..0bc77b0741 100644
--- a/lib/std/Build/Module.zig
+++ b/lib/std/Build/Module.zig
@@ -164,6 +164,7 @@ pub const IncludeDir = union(enum) {
framework_path_system: LazyPath,
other_step: *Step.Compile,
config_header_step: *Step.ConfigHeader,
+ embed_path: LazyPath,
pub fn appendZigProcessFlags(
include_dir: IncludeDir,
@@ -200,6 +201,9 @@ pub const IncludeDir = union(enum) {
const header_dir_path = full_file_path[0 .. full_file_path.len - config_header.include_path.len];
try zig_args.appendSlice(&.{ "-I", header_dir_path });
},
+ .embed_path => |embed_path| {
+ try zig_args.append(try std.mem.concat(b.allocator, u8, &.{ "--embed-dir=", embed_path.getPath2(b, asking_step) }));
+ },
}
}
};
@@ -511,6 +515,11 @@ pub fn addFrameworkPath(m: *Module, directory_path: LazyPath) void {
@panic("OOM");
}
+pub fn addEmbedPath(m: *Module, lazy_path: LazyPath) void {
+ const b = m.owner;
+ m.include_dirs.append(b.allocator, .{ .embed_path = lazy_path.dupe(b) }) catch @panic("OOM");
+}
+
pub fn addLibraryPath(m: *Module, directory_path: LazyPath) void {
const b = m.owner;
m.lib_paths.append(b.allocator, directory_path.dupe(b)) catch @panic("OOM");
diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig
index cedf398d98..af0e44b8d2 100644
--- a/lib/std/Build/Step.zig
+++ b/lib/std/Build/Step.zig
@@ -202,6 +202,7 @@ pub fn init(options: StepOptions) Step {
.state = .precheck_unstarted,
.max_rss = options.max_rss,
.debug_stack_trace = blk: {
+ if (!std.debug.sys_can_stack_trace) break :blk &.{};
const addresses = arena.alloc(usize, options.owner.debug_stack_frames_count) catch @panic("OOM");
@memset(addresses, 0);
const first_ret_addr = options.first_ret_addr orelse @returnAddress();
diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig
index 289a4ff4f8..5fee8c730b 100644
--- a/lib/std/Build/Step/CheckObject.zig
+++ b/lib/std/Build/Step/CheckObject.zig
@@ -563,7 +563,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void {
src_path.sub_path,
check_object.max_bytes,
null,
- @alignOf(u64),
+ .of(u64),
null,
) catch |err| return step.fail("unable to read '{'}': {s}", .{ src_path, @errorName(err) });
diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig
index 616e8f76b4..ff6e766c58 100644
--- a/lib/std/Build/Step/Compile.zig
+++ b/lib/std/Build/Step/Compile.zig
@@ -167,6 +167,9 @@ discard_local_symbols: bool = false,
/// Position Independent Executable
pie: ?bool = null,
+/// Link Time Optimization mode
+lto: ?std.zig.LtoMode = null,
+
dll_export_fns: ?bool = null,
subsystem: ?std.Target.SubSystem = null,
@@ -185,7 +188,9 @@ force_undefined_symbols: std.StringHashMap(void),
/// Overrides the default stack size
stack_size: ?u64 = null,
+/// Deprecated; prefer using `lto`.
want_lto: ?bool = null,
+
use_llvm: ?bool,
use_lld: ?bool,
@@ -693,6 +698,8 @@ const PkgConfigResult = struct {
/// Run pkg-config for the given library name and parse the output, returning the arguments
/// that should be passed to zig to link the given library.
fn runPkgConfig(compile: *Compile, lib_name: []const u8) !PkgConfigResult {
+ const wl_rpath_prefix = "-Wl,-rpath,";
+
const b = compile.step.owner;
const pkg_name = match: {
// First we have to map the library name to pkg config name. Unfortunately,
@@ -783,6 +790,8 @@ fn runPkgConfig(compile: *Compile, lib_name: []const u8) !PkgConfigResult {
try zig_cflags.appendSlice(&[_][]const u8{ "-D", macro });
} else if (mem.startsWith(u8, arg, "-D")) {
try zig_cflags.append(arg);
+ } else if (mem.startsWith(u8, arg, wl_rpath_prefix)) {
+ try zig_cflags.appendSlice(&[_][]const u8{ "-rpath", arg[wl_rpath_prefix.len..] });
} else if (b.debug_pkg_config) {
return compile.step.fail("unknown pkg-config flag '{s}'", .{arg});
}
@@ -939,6 +948,10 @@ pub fn addConfigHeader(compile: *Compile, config_header: *Step.ConfigHeader) voi
compile.root_module.addConfigHeader(config_header);
}
+pub fn addEmbedPath(compile: *Compile, lazy_path: LazyPath) void {
+ compile.root_module.addEmbedPath(lazy_path);
+}
+
pub fn addLibraryPath(compile: *Compile, directory_path: LazyPath) void {
compile.root_module.addLibraryPath(directory_path);
}
@@ -1681,7 +1694,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
try addFlag(&zig_args, "each-lib-rpath", compile.each_lib_rpath);
- if (compile.build_id) |build_id| {
+ if (compile.build_id orelse b.build_id) |build_id| {
try zig_args.append(switch (build_id) {
.hexstring => |hs| b.fmt("--build-id=0x{s}", .{
std.fmt.fmtSliceHexLower(hs.toSlice()),
@@ -1703,7 +1716,15 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
}
try addFlag(&zig_args, "PIE", compile.pie);
- try addFlag(&zig_args, "lto", compile.want_lto);
+
+ if (compile.lto) |lto| {
+ try zig_args.append(switch (lto) {
+ .full => "-flto=full",
+ .thin => "-flto=thin",
+ .none => "-fno-lto",
+ });
+ } else try addFlag(&zig_args, "lto", compile.want_lto);
+
try addFlag(&zig_args, "sanitize-coverage-trace-pc-guard", compile.sanitize_coverage_trace_pc_guard);
if (compile.subsystem) |subsystem| {
diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig
index a9d4808bc0..3d0b0a7068 100644
--- a/lib/std/Build/Step/Run.zig
+++ b/lib/std/Build/Step/Run.zig
@@ -620,6 +620,35 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
var man = b.graph.cache.obtain();
defer man.deinit();
+ if (run.env_map) |env_map| {
+ const KV = struct { []const u8, []const u8 };
+ var kv_pairs = try std.ArrayList(KV).initCapacity(arena, env_map.count());
+ var iter = env_map.iterator();
+ while (iter.next()) |entry| {
+ kv_pairs.appendAssumeCapacity(.{ entry.key_ptr.*, entry.value_ptr.* });
+ }
+
+ std.mem.sortUnstable(KV, kv_pairs.items, {}, struct {
+ fn lessThan(_: void, kv1: KV, kv2: KV) bool {
+ const k1 = kv1[0];
+ const k2 = kv2[0];
+
+ if (k1.len != k2.len) return k1.len < k2.len;
+
+ for (k1, k2) |c1, c2| {
+ if (c1 == c2) continue;
+ return c1 < c2;
+ }
+ unreachable; // two keys cannot be equal
+ }
+ }.lessThan);
+
+ for (kv_pairs.items) |kv| {
+ man.hash.addBytes(kv[0]);
+ man.hash.addBytes(kv[1]);
+ }
+ }
+
for (run.argv.items) |arg| {
switch (arg) {
.bytes => |bytes| {
diff --git a/lib/std/Build/Watch.zig b/lib/std/Build/Watch.zig
index 2ddb3ca4c2..13540a2b36 100644
--- a/lib/std/Build/Watch.zig
+++ b/lib/std/Build/Watch.zig
@@ -56,7 +56,7 @@ const Os = switch (builtin.os.tag) {
const bytes = lfh.slice();
const new_ptr = try gpa.alignedAlloc(
u8,
- @alignOf(std.os.linux.file_handle),
+ .of(std.os.linux.file_handle),
@sizeOf(std.os.linux.file_handle) + bytes.len,
);
const new_header: *std.os.linux.file_handle = @ptrCast(new_ptr);
@@ -612,8 +612,6 @@ const Os = switch (builtin.os.tag) {
/// -1. Otherwise, it needs to be opened in update(), and will be
/// stored here.
dir_fd: i32,
- /// Number of files being watched by this directory handle.
- ref_count: u32,
}),
const dir_open_flags: posix.O = f: {
@@ -673,11 +671,9 @@ const Os = switch (builtin.os.tag) {
try handles.append(gpa, .{
.rs = .{},
.dir_fd = if (skip_open_dir) -1 else dir_fd,
- .ref_count = 1,
});
- } else {
- handles.items(.ref_count)[gop.index] += 1;
}
+
break :rs &handles.items(.rs)[gop.index];
};
for (files.items) |basename| {
@@ -718,10 +714,6 @@ const Os = switch (builtin.os.tag) {
}
}
- const ref_count_ptr = &handles.items(.ref_count)[i];
- ref_count_ptr.* -= 1;
- if (ref_count_ptr.* > 0) continue;
-
// If the sub_path == "" then this patch has already the
// dir fd that we need to use as the ident to remove the
// event. If it was opened above with openat() then we need
@@ -738,10 +730,10 @@ const Os = switch (builtin.os.tag) {
// index in the udata field.
const last_dir_fd = fd: {
const last_path = w.dir_table.keys()[handles.len - 1];
- const last_dir_fd = if (last_path.sub_path.len != 0)
+ const last_dir_fd = if (last_path.sub_path.len == 0)
last_path.root_dir.handle.fd
else
- handles.items(.dir_fd)[i];
+ handles.items(.dir_fd)[handles.len - 1];
assert(last_dir_fd != -1);
break :fd last_dir_fd;
};