╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Builtin.zig ──────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
254 \\pub const position_independent_executable = {}; 255 \\pub const strip_debug_info = {}; 256 \\pub const code_model: std.lang.CodeModel = .{f}; 257 \\pub const omit_frame_pointer = {}; 258 \\ 259 , .{ 260 std.zig.fmtIdPU(@tagName(target.ofmt)), 261 std.zig.fmtIdPU(@tagName(opts.optimize_mode)), 262 link_libc, 263 opts.link_libcpp, 264 opts.error_tracing, 265 opts.valgrind, 266 opts.sanitize_thread, 267 opts.fuzz, 268 opts.pic, 269 opts.pie, 270 opts.strip, 271 std.zig.fmtIdPU(@tagName(opts.code_model)), 272 opts.omit_frame_pointer, 273 }); 274 275 if (target.os.tag == .wasi) { 276 try buffer.print( 277 \\pub const wasi_exec_model: std.lang.WasiExecModel = .{f}; 278 \\ 279 , .{std.zig.fmtIdPU(@tagName(opts.wasi_exec_model))}); 280 } 281 282 if (opts.is_test) { 283 try buffer.appendSlice( 284 \\pub var test_functions: []const std.lang.TestFn = &.{}; // overwritten later 285 \\ 286 ); 287 } 288 } 289 290 /// This essentially takes the place of `Zcu.PerThread.updateFile`, but for 'builtin' modules. 291 /// Instead of reading the file from disk, its contents are generated in-memory. 292 pub fn populateFile(opts: @This(), gpa: Allocator, file: *File) Allocator.Error!void { 293 assert(file.is_builtin); 294 assert(file.status == .never_loaded); 295 assert(file.source == null); 296 assert(file.tree == null); 297 assert(file.zir == null); 298 299 file.source = try opts.generate(gpa); 300 301 log.debug("parsing and generating 'builtin.zig'", .{}); 302 303 file.tree = try std.zig.Ast.parse(gpa, file.source.?, .{}); 304 assert(file.tree.?.errors.len == 0); // builtin.zig must parse 305 306 file.zir = try AstGen.generate(gpa, file.tree.?); 307 assert(!file.zir.?.hasCompileErrors()); // builtin.zig must not have astgen errors 308 file.status = .success; 309 } 310 311 /// After `populateFile` succeeds, call this function to write the generated file out to disk 312 /// if necessary. This is useful for external tooling such as debuggers. 313 /// Assumes that `file.mod` is correctly set to the builtin module. 314 pub fn updateFileOnDisk(file: *File, comp: *Compilation) !void { 315 assert(file.is_builtin); 316 assert(file.status == .success); 317 assert(file.source != null); 318 319 const root_dir, const sub_path = file.path.openInfo(comp.dirs); 320 const io = comp.io; 321 322 if (root_dir.statFile(io, sub_path, .{})) |stat| { 323 if (stat.size != file.source.?.len) { 324 std.log.warn( 325 "the cached file '{f}' had the wrong size. Expected {d}, found {d}. " ++ 326 "Overwriting with correct file contents now", 327 .{ file.path.fmt(comp), file.source.?.len, stat.size }, 328 ); 329 } else { 330 file.stat = .{ 331 .size = stat.size, 332 .inode = stat.inode, 333 .mtime = stat.mtime, 334 }; 335 return; 336 } 337 } else |err| switch (err) { 338 error.FileNotFound => {}, 339 340 error.WouldBlock => unreachable, // not asking for non-blocking I/O 341 error.BadPathName => unreachable, // it's always "o/digest/builtin.zig" 342 error.NameTooLong => unreachable, // it's always "o/digest/builtin.zig" 343 344 // We don't expect the file to be a pipe, but can't mark `error.PipeBusy` as `unreachable`, 345 // because the user could always replace the file on disk. 346 else => |e| return e, 347 } 348 349 // `make_path` matters because the dir hasn't actually been created yet. 350 var af = try root_dir.createFileAtomic(io, sub_path, .{ .make_path = true, .replace = true }); 351 defer af.deinit(io); 352 try af.file.writeStreamingAll(io, file.source.?); 353 af.replace(io) catch |err| switch (err) { 354 error.AccessDenied => switch (builtin.os.tag) { 355 .windows => { 356 // Very likely happened due to another process or thread 357 // simultaneously creating the same, correct builtin.zig file. 358 // This is not a problem; ignore it. 359 }, 360 else => return err, 361 }, 362 else => return err, 363 }; 364 365 file.stat = .{ 366 .size = file.source.?.len, 367 .inode = 0, // dummy value 368 .mtime = .zero, // dummy value 369 }; 370 } 371 372 const builtin = @import("builtin"); 373 const std = @import("std"); 374 const Allocator = std.mem.Allocator; 375 const Cache = std.Build.Cache; 376 const build_options = @import("build_options"); 377 const Module = @import("Module.zig"); 378 const assert = std.debug.assert; 379 const AstGen = std.zig.AstGen; 380 const File = @import("Zcu.zig").File; 381 const Compilation = @import("Compilation.zig"); 382 const log = std.log.scoped(.builtin); 383