| ... | ... | @@ -1,9 +1,3 @@ |
| 1 | | const std = @import("../std.zig"); |
| 2 | | const ConfigHeaderStep = @This(); |
| 3 | | const Step = std.Build.Step; |
| 4 | | |
| 5 | | pub const base_id: Step.Id = .config_header; |
| 6 | | |
| 7 | 1 | pub const Style = union(enum) { |
| 8 | 2 | /// The configure format supported by autotools. It uses `#undef foo` to |
| 9 | 3 | /// mark lines that can be substituted with different values. |
| ... | ... | @@ -41,6 +35,8 @@ style: Style, |
| 41 | 35 | max_bytes: usize, |
| 42 | 36 | include_path: []const u8, |
| 43 | 37 | |
| 38 | pub const base_id: Step.Id = .config_header; |
| 39 | |
| 44 | 40 | pub const Options = struct { |
| 45 | 41 | style: Style = .blank, |
| 46 | 42 | max_bytes: usize = 2 * 1024 * 1024, |
| ... | ... | @@ -162,23 +158,15 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 162 | 158 | const b = step.owner; |
| 163 | 159 | const self = @fieldParentPtr(ConfigHeaderStep, "step", step); |
| 164 | 160 | const gpa = b.allocator; |
| 161 | const arena = b.allocator; |
| 165 | 162 | |
| 166 | | // The cache is used here not really as a way to speed things up - because writing |
| 167 | | // the data to a file would probably be very fast - but as a way to find a canonical |
| 168 | | // location to put build artifacts. |
| 163 | var man = b.cache.obtain(); |
| 164 | defer man.deinit(); |
| 169 | 165 | |
| 170 | | // If, for example, a hard-coded path was used as the location to put ConfigHeaderStep |
| 171 | | // files, then two ConfigHeaderStep executing in parallel might clobber each other. |
| 172 | | |
| 173 | | // TODO port the cache system from the compiler to zig std lib. Until then |
| 174 | | // we construct the path directly, and no "cache hit" detection happens; |
| 175 | | // the files are always written. |
| 176 | | // Note there is very similar code over in WriteFileStep |
| 177 | | const Hasher = std.crypto.auth.siphash.SipHash128(1, 3); |
| 178 | 166 | // Random bytes to make ConfigHeaderStep unique. Refresh this with new |
| 179 | 167 | // random bytes when ConfigHeaderStep implementation is modified in a |
| 180 | 168 | // non-backwards-compatible way. |
| 181 | | var hash = Hasher.init("PGuDTpidxyMqnkGM"); |
| 169 | man.hash.add(@as(u32, 0xdef08d23)); |
| 182 | 170 | |
| 183 | 171 | var output = std.ArrayList(u8).init(gpa); |
| 184 | 172 | defer output.deinit(); |
| ... | ... | @@ -191,13 +179,13 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 191 | 179 | .autoconf => |file_source| { |
| 192 | 180 | try output.appendSlice(c_generated_line); |
| 193 | 181 | const src_path = file_source.getPath(b); |
| 194 | | const contents = try std.fs.cwd().readFileAlloc(gpa, src_path, self.max_bytes); |
| 182 | const contents = try std.fs.cwd().readFileAlloc(arena, src_path, self.max_bytes); |
| 195 | 183 | try render_autoconf(step, contents, &output, self.values, src_path); |
| 196 | 184 | }, |
| 197 | 185 | .cmake => |file_source| { |
| 198 | 186 | try output.appendSlice(c_generated_line); |
| 199 | 187 | const src_path = file_source.getPath(b); |
| 200 | | const contents = try std.fs.cwd().readFileAlloc(gpa, src_path, self.max_bytes); |
| 188 | const contents = try std.fs.cwd().readFileAlloc(arena, src_path, self.max_bytes); |
| 201 | 189 | try render_cmake(step, contents, &output, self.values, src_path); |
| 202 | 190 | }, |
| 203 | 191 | .blank => { |
| ... | ... | @@ -210,39 +198,40 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 210 | 198 | }, |
| 211 | 199 | } |
| 212 | 200 | |
| 213 | | hash.update(output.items); |
| 201 | man.hash.addBytes(output.items); |
| 214 | 202 | |
| 215 | | var digest: [16]u8 = undefined; |
| 216 | | hash.final(&digest); |
| 217 | | var hash_basename: [digest.len * 2]u8 = undefined; |
| 218 | | _ = std.fmt.bufPrint( |
| 219 | | &hash_basename, |
| 220 | | "{s}", |
| 221 | | .{std.fmt.fmtSliceHexLower(&digest)}, |
| 222 | | ) catch unreachable; |
| 203 | if (try step.cacheHit(&man)) { |
| 204 | const digest = man.final(); |
| 205 | self.output_file.path = try b.cache_root.join(arena, &.{ |
| 206 | "o", &digest, self.include_path, |
| 207 | }); |
| 208 | return; |
| 209 | } |
| 223 | 210 | |
| 224 | | const output_dir = try b.cache_root.join(gpa, &.{ "o", &hash_basename }); |
| 211 | const digest = man.final(); |
| 225 | 212 | |
| 226 | 213 | // If output_path has directory parts, deal with them. Example: |
| 227 | 214 | // output_dir is zig-cache/o/HASH |
| 228 | 215 | // output_path is libavutil/avconfig.h |
| 229 | 216 | // We want to open directory zig-cache/o/HASH/libavutil/ |
| 230 | 217 | // but keep output_dir as zig-cache/o/HASH for -I include |
| 231 | | const sub_dir_path = if (std.fs.path.dirname(self.include_path)) |d| |
| 232 | | try std.fs.path.join(gpa, &.{ output_dir, d }) |
| 233 | | else |
| 234 | | output_dir; |
| 218 | const sub_path = try std.fs.path.join(arena, &.{ "o", &digest, self.include_path }); |
| 219 | const sub_path_dirname = std.fs.path.dirname(sub_path).?; |
| 235 | 220 | |
| 236 | | var dir = std.fs.cwd().makeOpenPath(sub_dir_path, .{}) catch |err| { |
| 237 | | return step.fail("unable to make path '{s}': {s}", .{ output_dir, @errorName(err) }); |
| 221 | b.cache_root.handle.makePath(sub_path_dirname) catch |err| { |
| 222 | return step.fail("unable to make path '{}{s}': {s}", .{ |
| 223 | b.cache_root, sub_path_dirname, @errorName(err), |
| 224 | }); |
| 238 | 225 | }; |
| 239 | | defer dir.close(); |
| 240 | 226 | |
| 241 | | try dir.writeFile(std.fs.path.basename(self.include_path), output.items); |
| 227 | b.cache_root.handle.writeFile(sub_path, output.items) catch |err| { |
| 228 | return step.fail("unable to write file '{}{s}': {s}", .{ |
| 229 | b.cache_root, sub_path, @errorName(err), |
| 230 | }); |
| 231 | }; |
| 242 | 232 | |
| 243 | | self.output_file.path = try std.fs.path.join(b.allocator, &.{ |
| 244 | | output_dir, self.include_path, |
| 245 | | }); |
| 233 | self.output_file.path = try b.cache_root.join(arena, &.{sub_path}); |
| 234 | try man.writeManifest(); |
| 246 | 235 | } |
| 247 | 236 | |
| 248 | 237 | fn render_autoconf( |
| ... | ... | @@ -442,3 +431,7 @@ fn renderValueNasm(output: *std.ArrayList(u8), name: []const u8, value: Value) ! |
| 442 | 431 | }, |
| 443 | 432 | } |
| 444 | 433 | } |
| 434 | |
| 435 | const std = @import("../std.zig"); |
| 436 | const ConfigHeaderStep = @This(); |
| 437 | const Step = std.Build.Step; |