diff options
Diffstat (limited to 'lib/std/Build')
| -rw-r--r-- | lib/std/Build/Cache/DepTokenizer.zig | 64 | ||||
| -rw-r--r-- | lib/std/Build/Module.zig | 9 | ||||
| -rw-r--r-- | lib/std/Build/Step.zig | 1 | ||||
| -rw-r--r-- | lib/std/Build/Step/CheckObject.zig | 2 | ||||
| -rw-r--r-- | lib/std/Build/Step/Compile.zig | 25 | ||||
| -rw-r--r-- | lib/std/Build/Step/Run.zig | 29 | ||||
| -rw-r--r-- | lib/std/Build/Watch.zig | 16 |
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; }; |
