-
Notifications
You must be signed in to change notification settings - Fork 237
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
build(nix): create si-fs-standalone Nix pkg for a Nix-free binary #5472
Conversation
Signed-off-by: Fletcher Nichol <[email protected]>
Signed-off-by: Fletcher Nichol <[email protected]>
Signed-off-by: Fletcher Nichol <[email protected]>
This change introduces a new Nix derivation helper (`standaloneBinaryDerivation`) which uses a `binDerivation`-built package and prepares its main binary to be runnable without the full Nix package closure. Note that at the moment, this very much depends on the dynamic libraries at play and whether or not the executing system has the correct versions. At the moment, we're targetting the `si-fs` binary which only depends on `libc` and `libgcc`. Future work will attempt to make these binaries more flexible and portable where possible. Signed-off-by: Fletcher Nichol <[email protected]>
Dependency Review✅ No vulnerabilities or OpenSSF Scorecard issues found.OpenSSF Scorecard
Scanned Files |
I was testing this directly with
or possibly with some more helpful calls to
|
The |
postFixup = | ||
"" | ||
+ pkgs.lib.optionalString (pkgs.stdenv.isDarwin) '' | ||
nix_lib="$(otool -L "$out/bin/$name" \ | ||
| grep libiconv.dylib \ | ||
| awk '{print $1}' | ||
)" | ||
install_name_tool \ | ||
-change \ | ||
"$nix_lib" \ | ||
/usr/lib/libiconv.2.dylib \ | ||
"$out/bin/$name" \ | ||
2>/dev/null | ||
'' | ||
+ pkgs.lib.optionalString (pkgs.stdenv.isLinux) '' | ||
patchelf \ | ||
--set-interpreter "${systemInterpreter}" \ | ||
--remove-rpath \ | ||
"$out/bin/${bin}" | ||
''; | ||
dontPatchELF = true; | ||
dontAutoPatchELF = true; |
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.
To clarify my understanding, the idea here is to undo the autopatching done in the binDerivation to just use the system's libc bits, yeah? Out of curiostiy, why do we need a separate derivation for this?
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.
Essentially yeah. The default in Nix is to use patchelf
to hardcode the linker path, set RPATH
(i.e. where to look for libs), etc., and that's what we want to un-do. At some level I need a way to specify that I only want certain package targets to mangle themselves like this, not all packages (as we are relying on properly built Nix packages in our omnibus packages). At the moment this other derivation is using the output of a prior built package, but I may change this in the future to build is entirely (i.e. perform the buck2 build
) but may play with which libs are present at build time (that is, can we provide an older Glibc at build time to help with backwards compat, etc).
And how did I arrive here? I partially resurrected the tricks and strategies used for the old launcher (
Lines 241 to 286 in 5534c19
# Builds a standalone binary that is divorced from the Nix build and | |
# runtime environment | |
si-binary = buck2Derivation { | |
pathPrefix = "bin"; | |
pkgName = "si"; | |
stdBuildPhase = '' | |
# TODO(fnichol): we currently have a dynamically linked library of | |
# libc++abi being looked for in a `/nix/store` path when this | |
# binary is compiled on macOS, so for the meantime until this is | |
# fixed, we're going to perform a Cargo build of the binary (it | |
# does not suffer from this issue). | |
cargo build --bin "$name" --release | |
cp -pv "target/release/$name" "build/$name-$system" | |
''; | |
installPhase = '' | |
mkdir -pv "$out/bin" | |
cp -pv "build/$name-$system" "$out/bin/$name" | |
''; | |
dontPatchELF = true; | |
dontAutoPatchELF = true; | |
postFixup = | |
"" | |
+ pkgs.lib.optionalString (pkgs.stdenv.isDarwin) '' | |
nix_lib="$(otool -L "$out/bin/$name" \ | |
| grep libiconv.dylib \ | |
| awk '{print $1}' | |
)" | |
install_name_tool \ | |
-change \ | |
"$nix_lib" \ | |
/usr/lib/libiconv.2.dylib \ | |
"$out/bin/$name" \ | |
2>/dev/null | |
'' | |
+ pkgs.lib.optionalString (pkgs.stdenv.isLinux) '' | |
patchelf \ | |
--set-interpreter "${systemInterpreter}" \ | |
--remove-rpath \ | |
"$out/bin/$name" | |
'' | |
+ '' | |
mkdir -pv "$out/tarballs" | |
tar cvf "$out/tarballs/$name-$system.tar" -C "$out/bin" "$name" | |
gzip -9 "$out/tarballs/$name-$system.tar" | |
''; | |
}; |
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.
Ah, okay. Totally makes sense.
This change introduces a new Nix derivation helper
(
standaloneBinaryDerivation
) which uses abinDerivation
-builtpackage and prepares its main binary to be runnable without the full Nix
package closure.
Note that at the moment, this very much depends on the
dynamic libraries at play and whether or not the executing system has
the correct versions. At the moment, we're targetting the
si-fs
binarywhich only depends on
libc
andlibgcc
. Future work will attempt tomake these binaries more flexible and portable where possible.