Make nix/unpack-channel.nix a builtin builder#2748
Conversation
| auto source = sinkToSource([&](Sink & sink) { | ||
| auto decompressor = | ||
| hasSuffix(src, ".bz2") ? makeDecompressionSink("bzip2", sink) : | ||
| hasSuffix(src, ".xz") ? makeDecompressionSink("xz", sink) : |
There was a problem hiding this comment.
Yeah, we currently lack gzip support in compression.cc. Probably not a big deal since our channels don't use it, but it would be nice to add.
| [path of cat, mkdir, etc.]), | ||
| coreutils=$withval, coreutils=$(dirname $cat)) | ||
| AC_SUBST(coreutils) | ||
| AC_SUBST(coreutils, [$(dirname $(type -p cat))]) |
There was a problem hiding this comment.
For cross compilation purposes, it is nice to let this be a flag. These should just be runtime deps AFAICT. See NixOS/nixpkgs#58104
There was a problem hiding this comment.
Well, with this PR, it's now only used during the tests, which I assume cannot be run in a cross-compiled build anyway?
|
This is blocking on getting Nix working well on a number of Linux distros. As an employee of a Nix-based company, it'd be really nice if this landed so I can go back to doing work on my machine, which I haven't been able to for a while now. |
|
@lovesegfault (I'm unaffiliated with Nix, but...) If your company is that dependent on Nix, maybe it could fund some dedicated time from the Nix developers on this issue? |
|
@Janiczek We definitely should, I'll see what I can do. |
|
I think this fixes NixOS/nixpkgs#58104 as I understand it. Thanks for this! |
This was the last function using a shell script, so this allows us to get rid of tar, coreutils, bash etc.
This is no longer needed.
We can now convert Rust Errors to C++ exceptions. At the Rust->C++ FFI boundary, Result<T, Error> will cause Error to be converted to and thrown as a C++ exception.
In particular, these are emitted by 'git archive' (in fetchGit).
Also, fetchGit now runs in O(1) memory since we pipe the output of 'git archive' directly into unpackTarball() (rather than first reading it all into memory).
https://hydra.nixos.org/build/107467517 Seems that on i686-linux, gcc and rustc disagree on how to return 1-word structs: gcc has the caller pass a pointer to the result, while rustc has the callee return the result in a register. Work around this by using a bare pointer.
This is a hack to fix the build on macOS, which was failing because libnixrust.a contains compiler builtins that clash with libclang_rt.osx.a. There's probably a better solution... https://hydra.nixos.org/build/107473280
puckipedia
left a comment
There was a problem hiding this comment.
I know that the code's been merged for more than a week now, but I still felt the need to post some opinions; I didn't actually assume this code would be merged any time, as i did not regard it as production-ready, with many of the FIXMEs strewn about.
| unsafe { | ||
| let size = std::mem::size_of::<T>(); | ||
| let ptr = libc::malloc(size); | ||
| *(ptr as *mut T) = t; // FIXME: probably UB |
There was a problem hiding this comment.
This is indeed UB, as you're dereferencing an arbitrary value (which could be illegal for this T); this could cause double-frees, arbitrary UAFs, segfaults, etc.
|
|
||
| extern "C" { | ||
| #[allow(improper_ctypes)] // YOLO | ||
| fn make_error(s: &str) -> CppException; |
There was a problem hiding this comment.
Fat pointers are, afaik, not FFI-safe at all, and may just do the entire wrong thing.
| namespace rust { | ||
|
|
||
| // Depending on the internal representation of Rust slices is slightly | ||
| // evil... |
There was a problem hiding this comment.
It is. There's zero guarantee that the internal representation of a slice will look like this.
| } | ||
| }; | ||
|
|
||
| /* C++ representation of Rust's Result<T, CppException>. */ |
There was a problem hiding this comment.
Note that there's no guarantee that the enum actually is represented like this; Rust does a lot of niche filling and depending on the type of T the tag might just disappear.
| source: foreign::Source, | ||
| dest_dir: &str, | ||
| ) -> CBox<Result<(), error::CppException>> { | ||
| CBox::new(tarfile::unpack_tarfile(source, dest_dir).map_err(|err| err.into())) |
There was a problem hiding this comment.
Returning a CBox<Result<(), error::CppException>> seems kind of useless, why not just return a pointer to a CppException directly? This also saves allocations in the best case, and is actually FFI-safe.
|
Is this merged to the flakes branch? I can't seem to be able to fetch flakes that aren't already in the store. Getting the suspicious-looking: |
|
CC @edef1c |
This rewrites the builder of
<nix/unpack-channel.nix>in C++ and Rust. Previously the builder was a shell script. Since this was the only builder that was still a shell script, this allows us to get rid of the dependency on bash, coreutils, tar, xz, bzip2 etc., reducing Nix's closure size.This is mostly an experiment in using Rust in Nix. It uses the
tarcrate to do the parsing of tar files.