diff --git a/CompileCheck.zig b/CompileCheck.zig index 753ff22..52726a8 100644 --- a/CompileCheck.zig +++ b/CompileCheck.zig @@ -146,7 +146,7 @@ fn make(step: *std.Build.Step, options: std.Build.Step.MakeOptions) anyerror!voi const source_path = check.source_path.getPath2(b, step); const result = blk: { - var zig_args: std.ArrayList([]const u8) = .init(b.allocator); + var zig_args: std.array_list.Managed([]const u8) = .init(b.allocator); defer zig_args.deinit(); try zig_args.append(b.graph.zig_exe); try zig_args.append(switch (check.kind) { @@ -170,7 +170,7 @@ fn make(step: *std.Build.Step, options: std.Build.Step.MakeOptions) anyerror!voi .other_step => |other| { switch (other.kind) { .exe => return step.fail("cannot link with an executable build artifact", .{}), - .@"test" => return step.fail("cannot link with a test", .{}), + .@"test", .test_obj => return step.fail("cannot link with a test", .{}), .obj => { try zig_args.append(other.getEmittedBin().getPath2(b, step)); }, @@ -248,7 +248,7 @@ fn make(step: *std.Build.Step, options: std.Build.Step.MakeOptions) anyerror!voi .undeclared_identifier_count = undeclared_identifier_count, } }; }, - inline else => return step.fail("zig {}", .{fmtTerm(result.term)}), + inline else => return step.fail("zig {f}", .{fmtTerm(result.term)}), } } @@ -265,20 +265,18 @@ fn getGeneratedFilePath(compile: *std.Build.Step.Compile, comptime tag_name: []c const generated_file = maybe_path orelse { { - std.debug.lockStdErr(); - defer std.debug.unlockStdErr(); - const stderr = std.io.getStdErr(); - std.Build.dumpBadGetPathHelp(&compile.step, stderr, compile.step.owner, asking_step) catch {}; + const stderr = std.debug.lockStderrWriter(&.{}); + defer std.debug.unlockStderrWriter(); + std.Build.dumpBadGetPathHelp(&compile.step, stderr, .detect(.stderr()), compile.step.owner, asking_step) catch {}; } @panic("missing emit option for " ++ tag_name); }; const path = generated_file.path orelse { { - std.debug.lockStdErr(); - defer std.debug.unlockStdErr(); - const stderr = std.io.getStdErr(); - std.Build.dumpBadGetPathHelp(&compile.step, stderr, compile.step.owner, asking_step) catch {}; + const stderr = std.debug.lockStderrWriter(&.{}); + defer std.debug.unlockStderrWriter(); + std.Build.dumpBadGetPathHelp(&compile.step, stderr, .detect(.stderr()), compile.step.owner, asking_step) catch {}; } @panic(tag_name ++ " is null. Is there a missing step dependency?"); }; @@ -286,17 +284,10 @@ fn getGeneratedFilePath(compile: *std.Build.Step.Compile, comptime tag_name: []c return path; } -fn fmtTerm(term: ?std.process.Child.Term) std.fmt.Formatter(formatTerm) { +fn fmtTerm(term: ?std.process.Child.Term) std.fmt.Alt(?std.process.Child.Term, formatTerm) { return .{ .data = term }; } -fn formatTerm( - term: ?std.process.Child.Term, - comptime fmt: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, -) !void { - _ = fmt; - _ = options; +fn formatTerm(term: ?std.process.Child.Term, writer: *std.Io.Writer) error{WriteFailed}!void { if (term) |t| switch (t) { .Exited => |code| try writer.print("exited with code {}", .{code}), .Signal => |sig| try writer.print("terminated with signal {}", .{sig}), diff --git a/build.zig b/build.zig index 170910d..4f47c08 100644 --- a/build.zig +++ b/build.zig @@ -432,18 +432,12 @@ fn addPythonExe( ) *std.Build.Step.Compile { const exe = b.addExecutable(.{ .name = args.name, - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .target = target, + .optimize = optimize, + }), }); - switch (args.pyconfig.version) { - .@"3.11.13" => { - // workaround dictobject.c memcpy alignment issue - exe.root_module.sanitize_c = false; - }, - .@"3.12.11" => {}, - } - exe.root_module.addCMacro("Py_BUILD_CORE", ""); exe.root_module.addCMacro("_GNU_SOURCE", ""); switch (optimize) { @@ -593,7 +587,15 @@ fn addPythonExe( }, }), }, - .flags = &flags_common, + .flags = concat(b.allocator, &.{ + &flags_common, + switch (args.pyconfig.version) { + // workaround dictobject.c memcpy alignment issue + .@"3.11.13" => &.{"-fno-sanitize=alignment"}, + // tokenizer.c uses pointer overflow in restore_fstring_buffers + .@"3.12.11" => &.{"-fno-sanitize=pointer-overflow"}, + }, + }), }); exe.addCSourceFile(.{ @@ -1235,7 +1237,7 @@ fn addPyconfig( }; const config_header = b.addConfigHeader(.{ - .style = .{ .autoconf = upstream.path("pyconfig.h.in") }, + .style = .{ .autoconf_undef = upstream.path("pyconfig.h.in") }, .include_path = "pyconfig.h", }, .{ .ALIGNOF_LONG = 8, diff --git a/build.zig.zon b/build.zig.zon index 2e8e99b..06fb15a 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,7 +2,7 @@ .name = .cpython, .fingerprint = 0x3224901d1babdd14, .version = "0.0.0", - .minimum_zig_version = "0.14.1", + .minimum_zig_version = "0.15.2", .dependencies = .{ .@"upstream_3.11.13" = .{ .url = "git+https://github.com/python/cpython#498b971ea3673012a1d4b21860b229d55fc6e575", @@ -15,12 +15,12 @@ .lazy = true, }, .zlib = .{ - .url = "https://github.com/allyourcodebase/zlib/archive/6c72830882690c1eb2567a537525c3f432c1da50.tar.gz", - .hash = "zlib-1.3.1-ZZQ7lVgMAACwO4nUUd8GLhsuQ5JQq_VAhlEiENJTUv6h", + .url = "git+https://github.com/allyourcodebase/zlib#c2585c096171b8fbc8e5f78ab6c91b39e3573e15", + .hash = "zlib-1.3.1-ZZQ7lcMNAABPzkWdm_9y0tjlN17kF7czIiTVQ7h10rMR", }, .openssl = .{ - .url = "https://github.com/allyourcodebase/openssl/archive/f348124c5382bcc377f1b3277357cbf2ed2fb8db.tar.gz", - .hash = "openssl-3.3.1-2-TC9C3Se3ZACF5WO_CjoD7Bt_X94oCsAAbbwhOp1rTZBe", + .url = "git+https://github.com/allyourcodebase/openssl#7d4b2590b3b05fbc0e5cc20e2704a968e63503b1", + .hash = "openssl-3.3.2-TC9C3Vy3ZABkts70T3a6QfLYghNUy0tI42ksiW7jRmvd", .lazy = true, }, }, diff --git a/makesetup.zig b/makesetup.zig index 3cea0d5..f607e44 100644 --- a/makesetup.zig +++ b/makesetup.zig @@ -7,7 +7,8 @@ pub fn main() !void { // no need to free if (all_args.len <= 1) { - try std.io.getStdErr().writer().writeAll("usage: makesetup UPSTREAM_SRC OUT_DIR SETUP_FILES...\n"); + var stderr = std.fs.File.stderr().writer(&.{}); + try stderr.interface.writeAll("usage: makesetup UPSTREAM_SRC OUT_DIR SETUP_FILES...\n"); std.process.exit(0xff); } const args = all_args[1..]; @@ -36,51 +37,67 @@ pub fn main() !void { { var file = try out_dir.createFile("config.c", .{}); defer file.close(); - var bw = std.io.bufferedWriter(file.writer()); - const writer = bw.writer(); - try writer.print("/* Generated automatically from {s} by makesetup. */\n", .{config_in_path}); - var lines = std.mem.splitScalar(u8, config_in, '\n'); - while (lines.next()) |line| { - if (std.mem.indexOf(u8, line, "MARKER 1")) |_| { - var it = setup.modules.iterator(); - while (it.next()) |entry| { - if (!entry.value_ptr.enabled) continue; - try writer.print("extern PyObject* PyInit_{s}(void);\n", .{entry.key_ptr.*}); - } - } else if (std.mem.indexOf(u8, line, "MARKER 2")) |_| { - var it = setup.modules.iterator(); - while (it.next()) |entry| { - if (!entry.value_ptr.enabled) continue; - try writer.print(" {{\"{s}\", PyInit_{0s}}},\n", .{entry.key_ptr.*}); - } - } - try writer.writeAll(line); - try writer.writeByte('\n'); - } - try bw.flush(); + var out_file_buf: [4096]u8 = undefined; + var file_writer = file.writer(&out_file_buf); + writeConfigC(setup, config_in_path, config_in, &file_writer.interface) catch |err| switch (err) { + error.WriteFailed => return file_writer.err orelse error.Unexpected, + }; } { var out_file = try out_dir.createFile("module-compile-args.txt", .{}); defer out_file.close(); - var bw = std.io.bufferedWriter(out_file.writer()); - const writer = bw.writer(); + var out_file_buf: [4096]u8 = undefined; + var file_writer = out_file.writer(&out_file_buf); + writeCompileArgs(setup, &file_writer.interface) catch |err| switch (err) { + error.WriteFailed => return file_writer.err orelse error.Unexpected, + }; + } +} - var it = setup.modules.iterator(); - while (it.next()) |entry| { - const module_name = entry.key_ptr.*; - { - const suffix: []const u8 = if (entry.value_ptr.enabled) "" else " (DISABLED)"; - try writer.print("# Module '{s}'{s}\n", .{ module_name, suffix }); +fn writeConfigC( + setup: Setup, + config_in_path: []const u8, + config_in: []const u8, + writer: *std.Io.Writer, +) error{WriteFailed}!void { + try writer.print("/* Generated automatically from {s} by makesetup. */\n", .{config_in_path}); + var lines = std.mem.splitScalar(u8, config_in, '\n'); + while (lines.next()) |line| { + if (std.mem.indexOf(u8, line, "MARKER 1")) |_| { + var it = setup.modules.iterator(); + while (it.next()) |entry| { + if (!entry.value_ptr.enabled) continue; + try writer.print("extern PyObject* PyInit_{s}(void);\n", .{entry.key_ptr.*}); } - const prefix: []const u8 = if (entry.value_ptr.enabled) "" else "# "; - for (entry.value_ptr.compile_args) |compile_arg| switch (compile_arg) { - .source => |src| try writer.print("{s}Modules/{s}\n", .{ prefix, src }), - .include => |inc| try writer.print("{s}-I{s}\n", .{ prefix, inc }), - }; + } else if (std.mem.indexOf(u8, line, "MARKER 2")) |_| { + var it = setup.modules.iterator(); + while (it.next()) |entry| { + if (!entry.value_ptr.enabled) continue; + try writer.print(" {{\"{s}\", PyInit_{0s}}},\n", .{entry.key_ptr.*}); + } + } + try writer.writeAll(line); + try writer.writeByte('\n'); + } + try writer.flush(); +} + +fn writeCompileArgs(setup: Setup, writer: *std.Io.Writer) error{WriteFailed}!void { + var it = setup.modules.iterator(); + while (it.next()) |entry| { + const module_name = entry.key_ptr.*; + { + const suffix: []const u8 = if (entry.value_ptr.enabled) "" else " (DISABLED)"; + try writer.print("# Module '{s}'{s}\n", .{ module_name, suffix }); } - try bw.flush(); + const prefix: []const u8 = if (entry.value_ptr.enabled) "" else "# "; + for (entry.value_ptr.compile_args) |compile_arg| switch (compile_arg) { + .source => |src| try writer.print("{s}Modules/{s}\n", .{ prefix, src }), + .include => |inc| try writer.print("{s}-I{s}\n", .{ prefix, inc }), + }; } + try writer.flush(); } const CompileArg = union(enum) { diff --git a/replace.zig b/replace.zig index ed1f8dd..fe3d38d 100644 --- a/replace.zig +++ b/replace.zig @@ -7,7 +7,8 @@ pub fn main() !void { // no need to free if (all_args.len <= 1) { - try std.io.getStdErr().writer().writeAll("usage: replace IN_FILE OUT_FILE NAME=VALUE...\n"); + var stderr = std.fs.File.stderr().writer(&.{}); + try stderr.interface.writeAll("usage: replace IN_FILE OUT_FILE NAME=VALUE...\n"); std.process.exit(0xff); } const args = all_args[1..]; @@ -17,10 +18,7 @@ pub fn main() !void { const out_path = args[1]; const replacements = args[2..]; - var map: std.StringHashMapUnmanaged(struct { - count: usize, - value: []const u8, - }) = .{}; + var map: std.StringHashMapUnmanaged(MapNode) = .{}; for (replacements) |r| { const eq_index = std.mem.indexOfScalar(u8, r, '=') orelse errExit( "expected NAME=VALUE cmdline arg but got '{s}'", @@ -41,9 +39,38 @@ pub fn main() !void { var out_file = try std.fs.cwd().createFile(out_path, .{}); defer out_file.close(); - var bw = std.io.bufferedWriter(out_file.writer()); - const writer = bw.writer(); + var out_file_buf: [4096]u8 = undefined; + var file_writer = out_file.writer(&out_file_buf); + writeFile(in_path, in, &map, &file_writer.interface) catch |err| switch (err) { + error.WriteFailed => return file_writer.err orelse error.Unexpected, + }; + + var unused_count: usize = 0; + var it = map.iterator(); + while (it.next()) |entry| { + if (entry.value_ptr.count == 0) { + std.log.err("unused variable '{s}'", .{entry.key_ptr.*}); + unused_count += 1; + } + } + if (unused_count != 0) { + std.log.err("{} unused variable(s), the did not appear in template '{s}'", .{ unused_count, in_path }); + std.process.exit(0xff); + } +} + +const MapNode = struct { + count: usize, + value: []const u8, +}; + +fn writeFile( + in_path: []const u8, + in: []const u8, + map: *const std.StringHashMapUnmanaged(MapNode), + writer: *std.Io.Writer, +) error{WriteFailed}!void { var missing_count: usize = 0; var offset: usize = 0; while (true) { @@ -65,21 +92,8 @@ pub fn main() !void { offset = end + 1; } try writer.writeAll(in[offset..]); - try bw.flush(); + try writer.flush(); if (missing_count > 0) errExit("{} missing variable(s) for template '{s}'", .{ missing_count, in_path }); - - var unused_count: usize = 0; - var it = map.iterator(); - while (it.next()) |entry| { - if (entry.value_ptr.count == 0) { - std.log.err("unused variable '{s}'", .{entry.key_ptr.*}); - unused_count += 1; - } - } - if (unused_count != 0) { - std.log.err("{} unused variable(s), the did not appear in template '{s}'", .{ unused_count, in_path }); - std.process.exit(0xff); - } } fn errExit(comptime fmt: []const u8, args: anytype) noreturn {