aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Bedo <cu@cua0.org>2021-12-20 14:38:24 +1100
committerJustin Bedo <cu@cua0.org>2021-12-20 14:38:24 +1100
commiteebc44e609cc2f901c7ea694d62e36f63cbeae24 (patch)
tree4c7c07991a64c2480dd02490110ae62885c7bc2d
parent6979eda7260b804099a39b27e417d942feb722b9 (diff)
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.
-rw-r--r--default.nix20
-rw-r--r--strip-store-paths/default.nix20
-rw-r--r--strip-store-paths/strip-store-paths.zig57
3 files changed, 87 insertions, 10 deletions
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");
+ }
+ }
+}