From eebc44e609cc2f901c7ea694d62e36f63cbeae24 Mon Sep 17 00:00:00 2001 From: Justin Bedo Date: Mon, 20 Dec 2021 14:38:24 +1100 Subject: rewrite strip store paths Old version used sed, which is not inplace and causes issues when garbage collection triggers during a build. This patch adds a small rewriter that works in place. --- default.nix | 20 ++++++------ strip-store-paths/default.nix | 20 ++++++++++++ strip-store-paths/strip-store-paths.zig | 57 +++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 strip-store-paths/default.nix create mode 100644 strip-store-paths/strip-store-paths.zig diff --git a/default.nix b/default.nix index 8d262f7..04fd62c 100644 --- a/default.nix +++ b/default.nix @@ -147,17 +147,15 @@ let })); strip = drv: let + strip-store-paths = nixpkgs.callPackage ./strip-store-paths { }; stripCommand = '' - function rewrite { - sed -i 's|[A-Za-z0-9+/]\{32\}-bionix|00000000000000000000000000000000-bionix|g' $1 - } function rewriteOutput { if [ -f ''${!1} ] ; then - rewrite ''${!1} + strip-store-paths ''${!1} else for f in $(find ''${!1} -type f) ; do - rewrite $f + strip-store-paths $f done fi } @@ -167,12 +165,14 @@ let ''; in drv.overrideAttrs (attrs: - if attrs ? buildCommand then { - buildCommand = attrs.buildCommand + stripCommand; - } else { - fixupPhase = (if attrs ? fixupPhase then attrs.fixupPhase else "") + { nativeBuildInputs = attrs.nativeBuildInputs or [ ] ++ [ strip-store-paths ]; } // ( + if attrs ? buildCommand then { + buildCommand = attrs.buildCommand + stripCommand; + } else { + fixupPhase = (if attrs ? fixupPhase then attrs.fixupPhase else "") + stripCommand; - }); + } + )); # splitting/joining splitFile = file: drv: diff --git a/strip-store-paths/default.nix b/strip-store-paths/default.nix new file mode 100644 index 0000000..40fb546 --- /dev/null +++ b/strip-store-paths/default.nix @@ -0,0 +1,20 @@ +{ stdenv, zig }: + +stdenv.mkDerivation { + name = "strip-store-paths"; + nativeBuildInputs = [ zig ]; + src = ./strip-store-paths.zig; + + unpackPhase = '' + cp $src strip-store-paths.zig + ''; + + buildPhase = '' + export HOME=$TMPDIR + zig build-exe -OReleaseFast strip-store-paths.zig + ''; + + installPhase = '' + install -Dm 755 ./strip-store-paths $out/bin/strip-store-paths + ''; +} diff --git a/strip-store-paths/strip-store-paths.zig b/strip-store-paths/strip-store-paths.zig new file mode 100644 index 0000000..58d7504 --- /dev/null +++ b/strip-store-paths/strip-store-paths.zig @@ -0,0 +1,57 @@ +const std = @import("std"); + +pub const File = struct { + ptr: []align(std.mem.page_size) u8, + len: u64, + allocator: *std.mem.Allocator, + + pub fn init(fd: std.os.fd_t, allocator: *std.mem.Allocator) !File { + var stats = try std.os.fstat(fd); + var ptr = try std.os.mmap(null, + @intCast(usize, stats.size), + std.os.PROT_READ | std.os.PROT_WRITE, + std.os.MAP_SHARED, + fd, + 0); + return File { + .ptr = ptr, + .len = @intCast(u64, stats.size), + .allocator = allocator + }; + } + + pub fn deinit(self: *File) void { + std.os.munmap(self.ptr); + self.ptr = undefined; + self.len = 0; + } +}; + +pub fn main() !void { + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + const allocator = &arena.allocator; + + const args = try std.process.argsAlloc(allocator); + if (args.len != 2) { + std.debug.print("usage: {s} file\n", .{args[0]}); + std.os.exit(1); + } + const path = args[1]; + + // mmap input + var fd = try std.os.open(path, std.os.O_RDWR, 0); + var input = try File.init(fd, allocator); + defer input.deinit(); + + // search for /nix/store + var i: usize = 0; + const needle = "/nix/store/"; + while (std.mem.indexOfPos(u8, input.ptr, i, needle)) |idx| { + i = idx + needle.len; + var j = i + 32; // pos of - in a true path + if (j < input.len and input.ptr[j] == '-') { + std.mem.copy(u8, input.ptr[i..], "00000000000000000000000000000000"); + } + } +} -- cgit v1.2.3