dprint-plugin-exec
dprint-plugin-exec copied to clipboard
Offer statically linked executable
When running the plugin in NixOS:
> ./dprint-plugin-exec
Could not start dynamically linked executable: ./dprint
NixOS cannot run dynamically linked executables intended for generic
linux environments out of the box. For more information, see:
https://nix.dev/permalink/stub-ld
binary release gnu
> ldd dprint-plugin-exec-gnu
linux-vdso.so.1 (0x00007f0c9e7db000)
libgcc_s.so.1 => /nix/store/m2047a1xwgblgkrnbxz0yilkaqfrbf2b-xgcc-14-20241116-libgcc/lib/libgcc_s.so.1 (0x00007f0c9e7a7000)
libpthread.so.0 => /nix/store/rmy663w9p7xb202rcln4jjzmvivznmz8-glibc-2.40-66/lib/libpthread.so.0 (0x00007f0c9e7a2000)
libdl.so.2 => /nix/store/rmy663w9p7xb202rcln4jjzmvivznmz8-glibc-2.40-66/lib/libdl.so.2 (0x00007f0c9e79d000)
libc.so.6 => /nix/store/rmy663w9p7xb202rcln4jjzmvivznmz8-glibc-2.40-66/lib/libc.so.6 (0x00007f0c9e000000)
/lib64/ld-linux-x86-64.so.2 => /nix/store/rmy663w9p7xb202rcln4jjzmvivznmz8-glibc-2.40-66/lib64/ld-linux-x86-64.so.2 (0x00007f0c9e7dd000)
binary release musl (works)
> ldd dprint-plugin-exec-musl
statically linked
build from source (works)
ldd ./target/release/dprint-plugin-exec
linux-vdso.so.1 (0x00007fe5d643b000)
libgcc_s.so.1 => /nix/store/ik84lbv5jvjm1xxvdl8mhg52ry3xycvm-gcc-14-20241116-lib/lib/libgcc_s.so.1 (0x00007fe5d61d2000)
libc.so.6 => /nix/store/rmy663w9p7xb202rcln4jjzmvivznmz8-glibc-2.40-66/lib/libc.so.6 (0x00007fe5d5e00000)
/nix/store/rmy663w9p7xb202rcln4jjzmvivznmz8-glibc-2.40-66/lib/ld-linux-x86-64.so.2 => /nix/store/rmy663w9p7xb202rcln4jjzmvivznmz8-glibc-2.40-66/lib64/ld-linux-x86-64.so.2 (0x00007fe5d643d000)
I'm aware NixOS breaks compatibility with FHS.
Would it be feasible to provide binaries which are statically linked?
Or, is there a way to use musl instead of glibc, when configuring dprint in dprint.json?
Early proof-of-concept of dealing with directly in nix via an overlay, but statically linked would be nice to not have to do this.
I essentially provide an output of a sharable config so all the hashing (config -> plugin.json -> zip) can be done directly in nix so it can be used like below. Not the cleanest, but did get it to work. If we can't get a static binary (and if I can find the time), I can maybe setup a repo with the build artifacts that auto updates on a schedule or via renovate.
If anyone else has the time to champion, feel free to use any of below if it helps.
"extends": [
"/nix/store/r69gr5pgz7dlgw6wc22x2qb72578r48r-dprint-plugin-exec/share/dprint/configs/nix-dprint-plugin-exec-config.json",
],
Magic to make the binary work is using patchelf.
{lib, ...}: final: _: let
rpath = final.lib.makeLibraryPath (with final; [
stdenv.cc.cc.lib
glibc
]);
systemForDownload =
{
"aarch64-darwin" = "aarch64-apple-darwin";
"aarch64-linux" = "aarch64-unknown-linux-gnu";
"x86_64-darwin" = "x86_64-apple-darwin";
"x86_64-linux" = "x86_64-unknown-linux-gnu";
}
.${final.system};
systemForJson =
{
"aarch64-darwin" = "darwin-aarch64";
"aarch64-linux" = "linux-aarch64";
"x86_64-darwin" = "darwin-x86_64";
"x86_64-linux" = "linux-x86_64";
}
.${final.system};
version = "0.5.1";
src = final.fetchzip {
url = "https://github.com/dprint/dprint-plugin-exec/releases/download/${version}/dprint-plugin-exec-${systemForDownload}.zip";
sha256 =
{
"aarch64-darwin" = lib.fakeHash;
"aarch64-linux" = lib.fakeHash;
"x86_64-darwin" = lib.fakeHash;
"x86_64-linux" = "sha256-vclZSLs9TzAk4R9eE0Y9HJIBPe2sHsOj8shC7dMJ8XI=";
}
.${final.system};
};
dprint-plugin-exec-zip = final.stdenv.mkDerivation {
name = "dprint-plugin-exec-zip";
inherit src version;
phases = ["installPhase"];
installPhase = ''
mkdir -p $out
cp $src/dprint-plugin-exec $out/dprint-plugin-exec
chmod +wx $out/dprint-plugin-exec
${
if final.stdenv.hostPlatform.isLinux
then ''
patchelf \
--set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
--set-rpath ${rpath} \
$out/dprint-plugin-exec
''
else ""
}
cd $out
${lib.getExe final.zip} dprint-plugin-exec.zip dprint-plugin-exec
rm dprint-plugin-exec
'';
};
dprint-plugin-exec-json = final.writeTextFile {
name = "plugin.json";
text = builtins.toJSON {
schemaVersion = 2;
kind = "process";
name = "dprint-plugin-exec";
inherit version;
"${systemForJson}" = {
reference = "file://${dprint-plugin-exec-zip}/dprint-plugin-exec.zip";
checksum = builtins.hashFile "sha256" "${dprint-plugin-exec-zip}/dprint-plugin-exec.zip";
};
};
};
dprint-plugin-exec-config = final.writeTextFile {
name = "dprint.json";
text = builtins.toJSON {
plugins = [
"${dprint-plugin-exec-json}@${builtins.hashFile "sha256" "${dprint-plugin-exec-json}"}"
];
};
};
in {
# nix path-info .#dprint-plugin-exec
dprint-plugin-exec = final.stdenvNoCC.mkDerivation {
name = "dprint-plugin-exec";
inherit version;
phases = ["installPhase"];
installPhase = ''
mkdir -p $out/share/dprint/plugins/dprint-plugin-exec $out/share/dprint/configs
ln -s ${dprint-plugin-exec-json} $out/share/dprint/plugins/dprint-plugin-exec/plugin.json
ln -s ${dprint-plugin-exec-zip}/dprint-plugin-exec.zip $out/share/dprint/plugins/dprint-plugin-exec/dprint-plugin-exec.zip
ln -s ${dprint-plugin-exec-config} $out/share/dprint/configs/nix-dprint-plugin-exec-config.json
'';
};
}