-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No gzip?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, with this PR, it's now only used during the tests, which I assume cannot be run in a cross-compiled build anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true right now
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 FIXME
s 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
tar
crate to do the parsing of tar files.