-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Make nix/unpack-channel.nix a builtin builder #2748
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
Changes from all commits
11da5b2
e60f6bd
045708d
6a9c815
87b7b25
0dbb249
d722e21
afb0218
343ebcc
8110b4e
f738cd4
b7fba16
d14b1c2
d33dd6e
f2bd847
8918bae
88f8063
e6c1d1b
dbc4f9d
949dc84
f553a8b
895ce1b
39954a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,29 +1,13 @@ | ||
| # FIXME: remove this file? | ||
| let | ||
| fromEnv = var: def: | ||
| let val = builtins.getEnv var; in | ||
| if val != "" then val else def; | ||
| in rec { | ||
| shell = "@bash@"; | ||
| coreutils = "@coreutils@"; | ||
| bzip2 = "@bzip2@"; | ||
| gzip = "@gzip@"; | ||
| xz = "@xz@"; | ||
| tar = "@tar@"; | ||
| tarFlags = "@tarFlags@"; | ||
| tr = "@tr@"; | ||
| nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@"; | ||
| nixPrefix = "@prefix@"; | ||
| nixLibexecDir = fromEnv "NIX_LIBEXEC_DIR" "@libexecdir@"; | ||
| nixLocalstateDir = "@localstatedir@"; | ||
| nixSysconfDir = "@sysconfdir@"; | ||
| nixStoreDir = fromEnv "NIX_STORE_DIR" "@storedir@"; | ||
|
|
||
| # If Nix is installed in the Nix store, then automatically add it as | ||
| # a dependency to the core packages. This ensures that they work | ||
| # properly in a chroot. | ||
| chrootDeps = | ||
| if dirOf nixPrefix == builtins.storeDir then | ||
| [ (builtins.storePath nixPrefix) ] | ||
| else | ||
| [ ]; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,39 +1,12 @@ | ||
| with import <nix/config.nix>; | ||
|
|
||
| let | ||
|
|
||
| builder = builtins.toFile "unpack-channel.sh" | ||
| '' | ||
| mkdir $out | ||
| cd $out | ||
| xzpat="\.xz\$" | ||
| gzpat="\.gz\$" | ||
| if [[ "$src" =~ $xzpat ]]; then | ||
| ${xz} -d < $src | ${tar} xf - ${tarFlags} | ||
| elif [[ "$src" =~ $gzpat ]]; then | ||
| ${gzip} -d < $src | ${tar} xf - ${tarFlags} | ||
| else | ||
| ${bzip2} -d < $src | ${tar} xf - ${tarFlags} | ||
| fi | ||
| if [ * != $channelName ]; then | ||
| mv * $out/$channelName | ||
| fi | ||
| ''; | ||
|
|
||
| in | ||
|
|
||
| { name, channelName, src }: | ||
|
|
||
| derivation { | ||
| system = builtins.currentSystem; | ||
| builder = shell; | ||
| args = [ "-e" builder ]; | ||
| inherit name channelName src; | ||
| builder = "builtin:unpack-channel"; | ||
|
|
||
| system = "builtin"; | ||
|
|
||
| PATH = "${nixBinDir}:${coreutils}"; | ||
| inherit name channelName src; | ||
|
|
||
| # No point in doing this remotely. | ||
| preferLocalBuild = true; | ||
|
|
||
| inherit chrootDeps; | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| [package] | ||
| name = "nix-rust" | ||
| version = "0.1.0" | ||
| authors = ["Eelco Dolstra <edolstra@gmail.com>"] | ||
| edition = "2018" | ||
|
|
||
| [lib] | ||
| name = "nixrust" | ||
| crate-type = ["cdylib"] | ||
|
|
||
| [dependencies] | ||
| tar = "0.4" | ||
| libc = "0.2" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| ifeq ($(OPTIMIZE), 1) | ||
| RUST_MODE = --release | ||
| RUST_DIR = release | ||
| else | ||
| RUST_MODE = | ||
| RUST_DIR = debug | ||
| endif | ||
|
|
||
| libnixrust_PATH := $(d)/target/$(RUST_DIR)/libnixrust.$(SO_EXT) | ||
| libnixrust_INSTALL_PATH := $(libdir)/libnixrust.$(SO_EXT) | ||
| libnixrust_LDFLAGS_USE := -L$(d)/target/$(RUST_DIR) -lnixrust -ldl | ||
| libnixrust_LDFLAGS_USE_INSTALLED := -L$(libdir) -lnixrust -ldl | ||
|
|
||
| ifeq ($(OS), Darwin) | ||
| libnixrust_BUILD_FLAGS = NIX_LDFLAGS="-undefined dynamic_lookup" | ||
| else | ||
| libnixrust_LDFLAGS_USE += -Wl,-rpath,$(abspath $(d)/target/$(RUST_DIR)) | ||
| libnixrust_LDFLAGS_USE_INSTALLED += -Wl,-rpath,$(libdir) | ||
| endif | ||
|
|
||
| $(libnixrust_PATH): $(wildcard $(d)/src/*.rs) $(d)/Cargo.toml | ||
| $(trace-gen) cd nix-rust && CARGO_HOME=$$(if [[ -d vendor ]]; then echo vendor; fi) \ | ||
| $(libnixrust_BUILD_FLAGS) \ | ||
| cargo build $(RUST_MODE) $$(if [[ -d vendor ]]; then echo --offline; fi) \ | ||
| && touch target/$(RUST_DIR)/libnixrust.$(SO_EXT) | ||
|
|
||
| $(libnixrust_INSTALL_PATH): $(libnixrust_PATH) | ||
| $(target-gen) cp $^ $@ | ||
| ifeq ($(OS), Darwin) | ||
| install_name_tool -id $@ $@ | ||
| endif | ||
|
|
||
| dist-files += $(d)/vendor | ||
|
|
||
| clean: clean-rust | ||
|
|
||
| clean-rust: | ||
| $(suppress) rm -rfv nix-rust/target |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| #[derive(Debug)] | ||
| pub enum Error { | ||
| IOError(std::io::Error), | ||
| Misc(String), | ||
| Foreign(CppException), | ||
| } | ||
|
|
||
| impl From<std::io::Error> for Error { | ||
| fn from(err: std::io::Error) -> Self { | ||
| Error::IOError(err) | ||
| } | ||
| } | ||
|
|
||
| impl From<Error> for CppException { | ||
| fn from(err: Error) -> Self { | ||
| match err { | ||
| Error::Foreign(ex) => ex, | ||
| Error::Misc(s) => unsafe { make_error(&s) }, | ||
| Error::IOError(err) => unsafe { make_error(&err.to_string()) }, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[repr(C)] | ||
| #[derive(Debug)] | ||
| pub struct CppException(*const libc::c_void); // == std::exception_ptr* | ||
|
|
||
| extern "C" { | ||
| #[allow(improper_ctypes)] // YOLO | ||
| fn make_error(s: &str) -> CppException; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /// A wrapper around Nix's Source class that provides the Read trait. | ||
| #[repr(C)] | ||
| pub struct Source { | ||
| fun: extern "C" fn(this: *mut libc::c_void, data: &mut [u8]) -> usize, | ||
| this: *mut libc::c_void, | ||
| } | ||
|
|
||
| impl std::io::Read for Source { | ||
| fn read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, std::io::Error> { | ||
| let n = (self.fun)(self.this, buf); | ||
| assert!(n <= buf.len()); | ||
| Ok(n) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| mod error; | ||
| mod foreign; | ||
| mod tarfile; | ||
|
|
||
| pub use error::Error; | ||
|
|
||
| pub struct CBox<T> { | ||
| pub ptr: *mut libc::c_void, | ||
| phantom: std::marker::PhantomData<T>, | ||
| } | ||
|
|
||
| impl<T> CBox<T> { | ||
| fn new(t: T) -> Self { | ||
| unsafe { | ||
| let size = std::mem::size_of::<T>(); | ||
| let ptr = libc::malloc(size); | ||
| *(ptr as *mut T) = t; // FIXME: probably UB | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| Self { | ||
| ptr, | ||
| phantom: std::marker::PhantomData, | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[no_mangle] | ||
| pub extern "C" fn unpack_tarfile( | ||
| source: foreign::Source, | ||
| dest_dir: &str, | ||
| ) -> CBox<Result<(), error::CppException>> { | ||
| CBox::new(tarfile::unpack_tarfile(source, dest_dir).map_err(|err| err.into())) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Returning a |
||
| } | ||
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