I installed
rustup
globally, via nixpkgs. Everything else is via this flake that you shared.
When you do nix develop
, your global rustup should get overriden by the one from the flakes. Try running file $(which cargo)
to see if it changes.
I installed
rustup
globally, via nixpkgs. Everything else is via this flake that you shared.
When you do nix develop
, your global rustup should get overriden by the one from the flakes. Try running file $(which cargo)
to see if it changes.
Also try running this command.
I do remember facing the same error, but I don’t remember how I fixed it. I think it got fixed after adding rustup
to the buildInputs
.
Did you remove rustup
from there?
Did you remove
rustup
from there?
Actually no. In fact I even added rustup
to the buildInputs
that were missing it. But didn’t help.
I actually removed my global installation of rustup
. Now everything is installed via flake. Outside of nix develop
there is no cargo or rustup now.
Ooh I think I remember: Run patchelf on ~/.rustup/toolchains/bpf
Okay. I feel like it’s another stupid question.
I did take a look at ~/.rustup/toolchain
and this was the result:
[rollschild@nixos:~/projects/example-helloworld/src/program-rust]$ ls -l ~/.rustup/toolchains/
total 8
lrwxrwxrwx 1 rollschild users 93 Apr 13 20:34 bpf -> /home/rollschild/projects/example-helloworld/src/program-rust/sdk/dependencies/bpf-tools/rust
drwxr-xr-x 7 rollschild users 4096 Apr 12 21:24 nightly-x86_64-unknown-linux-gnu
so here bpf
is already symlinked to the local ./sdk
. So my question is, I know patchelf
sets the dynamic loader, but if bpf
is already symlinked to ./sdk/dependencies/bpf-tools/rust
, will patchelf
make a difference at all? Plus, I’m not really sure how to run this patchelf
, since I would need to run this command on executables, not directories, am I right?
Plus, I’m wondering, if it would be better that we put some of those commands into flake.nix
, such as inside shellHook
, so that we don’t lose it afterwards.
I did find another shell.nix from Discord user @lithdew , whom I didn’t find on Discourse. This user did a PR: cargo-build-bpf: allow sdk path to be set by environment variables, in which he also shared his solana.nix
:
with (import <nixpkgs> { });
let
stdenv = clang7Stdenv;
solana-bpf-tools = stdenv.mkDerivation {
name = "solana-bpf-tools";
version = "v1.15";
src = fetchTarball {
name = "solana-bpf-tools-linux";
url = "https://github.com/solana-labs/bpf-tools/releases/download/${solana-bpf-tools.version}/solana-bpf-tools-linux.tar.bz2";
sha256 = "1bng5b5nr0rfz737di8whl06mz3zwz0kqzv1qhlglhv6v3mqrccp";
};
nativeBuildInputs = [ autoPatchelfHook openssl.dev stdenv.cc.cc ];
installPhase = "cp -R $src $out";
};
solana-bpf-sdk = stdenv.mkDerivation {
name = "solana-bpf-sdk";
version = "v1.6.22";
src = fetchTarball {
name = "solana-bpf-sdk";
url = "https://github.com/solana-labs/solana/releases/download/${solana-bpf-sdk.version}/bpf-sdk.tar.bz2";
sha256 = "1bfih5nxrglmxh0yvgi2mymddfq3b0qcqkz02ifcpflf4kvj0y20";
};
nativeBuildInputs = [ autoPatchelfHook openssl.dev stdenv.cc.cc ];
installPhase = ''
cp -R $src $out
chmod 755 $out
mkdir -p $out $out/dependencies
ln -s ${solana-bpf-tools} $out/dependencies/bpf-tools
'';
};
in
mkShell {
packages = [
solana-bpf-tools
solana-bpf-sdk
rustup
pkgconfig
];
buildInputs = [
openssl.dev
libudev.dev
llvmPackages_7.clang
llvmPackages_7.llvm
llvmPackages_7.lld
];
shellHook = ''
export BPF_SDK_PATH="${solana-bpf-sdk}"
export LIBCLANG_PATH="${llvmPackages_7.libclang.lib}/lib"
export PATH=$PATH:~/Desktop/solana/bin
rm -rf ~/.cache/solana*
mkdir -p ~/.cache/solana/${solana-bpf-tools.version}
ln -s ${solana-bpf-tools} ~/.cache/solana/${solana-bpf-tools.version}/bpf-tools
'';
}
I tried to combine this shell nix with the flake you provided but basically got the same bpf subcommand not found
error. But I posted here anyway for your reference.
I’m trying to run his shell nix standalone in another git repo, see if it makes a difference.
oh and in his PR that I linked above, there is a screenshot showing that he successfully ran cargo build-bpf
, which I’m not sure how. Because it would give me the “read-only file system” error.
Because it would give me the “read-only file system” error.
Their PR patches the cargo-build-bpf binary to not download the sdk to /nix/store/<some-folder>
. That’s how they are able to do that.
I’m not really sure how to run this
patchelf
, since I would need to run this command on executables, not directories, am I right?
I’m so sorry I messed up this bit. It’s not patchelf
, it’s autopatchelf
from here: GitHub - svanderburg/nix-patchtools: Autopatching binary packages to make them work with Nix
I forgot which one I used but I remembered when you mentioned directories.
I think it’s enough to run autopatchelf
on ./sdk
, since the toolchain is symlinked to there.
Okay, I’ve sorta made some progress?
I slightly modified my shellHook
to set the $BPF_SDK_PATH
:
shellHook = ''
mkdir -p ~/projects/example-helloworld/src/program-rust/sdk
export BPF_SDK_PATH="/home/rollschild/projects/example-helloworld/src/program-rust/sdk"
export LIBCLANG_PATH="${llvmPackages_7.libclang.lib}/lib"
rm -rf ~/.cache/solana*
mkdir -p ~/.cache/solana/${solana-bpf-tools-pkg.version}
ln -s ~/projects/example-helloworld/src/program-rust/sdk/dependencies/bpf-tools ~/.cache/solana/${solana-bpf-tools-pkg.version}/bpf-tools
'';
so that cargo build-bpf
no longer fails on the “readonly file system” error.
But I’m still seeing bpf no subcommand
errors.
So I git cloned the autopatchelf
repo and ran nix-build
to build autopatchelf
into the nix-patchtools/result/bin/autopatchelf
. Then I in my current project I ran this command but got the No package found that provides library: librustc_driver-a8aaff3fbd0bfff2.so
error:
[rollschild@nixos:~/projects/example-helloworld/src/program-rust]$ ../../../nix-patchtools/result/bin/autopatchelf sdk/dependencies/bpf-tools/rust/
Patching all ELF binaries in directory: sdk/dependencies/bpf-tools/rust/
Auto patching ELF binary: sdk/dependencies/bpf-tools/rust/bin/rustc
No package found that provides library: librustc_driver-a8aaff3fbd0bfff2.so
which seems weird, because sdk/dependencies/bpf-tools
is just a symlink to ~/.cache/solana/v1.23/bpf-tools
, which looks correct…
I’ll give you the cause of each error messages:
bpf no subcommand
:cargo
doesn’t have a +bpf
subcommand. +<toolchain>
is a rustup
subcommand.cargo
is overriding the rustup
cargo.command not found
: The binary that is being called has an invalid loader path. Fix it using autopatchelf
.read only filesystem
: Solana sdk is trying to download the bpf sdk into /nix/store/
.--bpf-sdk
path.I had messed up a bunch of things like forgetting about autopatchelf
when I gave you the initial instructions. But now that I have given you everything, you should be able to use the flake.nix
I shared in the first post and get it working.
To recap:
flake.nix
. It will make rustup
and cargo build-bpf
available.rustup
. Skip this if you already have installed. Run rustup toolchain list
to see.bpf
toolchain if it is shown in the list, to start from a blank slate. rustup toolchain uninstall bpf
.cargo build-bpf --bpf-sdk ./sdk
. It will download bpf sdk to ./sdk/dependencies
.patchelf
on it. This is normal.autopatchelf ~/.cache/solana
. The stuff that got downloaded in ./sdk
is actually downloaded to ~/.cache/solana
and symlinked from there../sdk
ln -s /nix/store/c11gzzi5ax9b8kmqrizrazjil4m8c4dl-solana-1.10.3/bin/sdk/bpf/env.sh ./sdk/
ln -s /nix/store/c11gzzi5ax9b8kmqrizrazjil4m8c4dl-solana-1.10.3/bin/sdk/bpf/scripts ./sdk/
fd
or find
or ls | grep
in /nix/store
to find the solana
folder and substitute it’s path in place of c11gzz...c4dl-solana-1.10.3
cargo build-bpf --bpf-sdk ./sdk
again. It should work this time.Hi,
Thank you so much for the detailed explanation. I’m still not able to build. I will outline everything I did here.
cd
into this project.flake.nix
using exactly what you provided and git add flake.nix
nix build
and got the following error:error: flake 'git+file:///home/rollschild/projects/example-helloworld' does not provide attribute 'packages.x86_64-linux.default' or 'defaultPackage.x86_64-linux'
flake.nix
and built again and succeeded building: defaultPackage = solana-cli-pkg;
nix develop
and entered the shellrustup toolchain list
and this is the output:[rollschild@nixos:~/projects/example-helloworld]$ rustup toolchain list
nightly-x86_64-unknown-linux-gnu (default)
bpf
rustup toolchain uninstall bpf
sdk/
using mkdir
cargo build-bpf --bpf-sdk ./sdk
and got the cargo command not found
error:[rollschild@nixos:~/projects/example-helloworld/src/program-rust]$ cargo build-bpf --bpf-sdk ./sdk
BPF SDK: /home/rollschild/projects/example-helloworld/src/program-rust/sdk
cargo-build-bpf child: rustup toolchain list -v
cargo-build-bpf child: rustup toolchain link bpf /home/rollschild/projects/example-helloworld/src/program-rust/sdk/dependencies/bpf-tools/rust
cargo-build-bpf child: cargo +bpf build --target bpfel-unknown-unknown --release
error: command failed: 'cargo': No such file or directory (os error 2)
which cargo
and the output was /nix/store/rzb0h2kzbl09q5z8z6d98m5b639pihl1-rustup-1.24.3/bin/cargo
, so looks like it was using rustup
’s binary for cargo, not the standalone cargo
binarycargo not found
error or run autopatchelf
so I just did autopatchelf
:[rollschild@nixos:~/projects/example-helloworld/src/program-rust]$ ../../../nix-patchtools/result/bin/autopatchelf ~/.cache/solana/
Patching all ELF binaries in directory: /home/rollschild/.cache/solana/
Auto patching ELF binary: /home/rollschild/.cache/solana/v1.23/bpf-tools/llvm/bin/llvm-readobj
No package found that provides library: libpthread.so.0
cargo
to the flake.nix
and re-built and re-nix develop
devShell = mkShell {
buildInputs = [
rust-analyzer
solana-cli-pkg
solana-bpf-tools-pkg
cargo-edit
cargo # ADDED HERE
rustup
];
cargo build-bpf --bpf-sdk ./sdk
again I got the classic bpf
error:[rollschild@nixos:~/projects/example-helloworld/src/program-rust]$ cargo build-bpf --bpf-sdk ./sdk
BPF SDK: /home/rollschild/projects/example-helloworld/src/program-rust/sdk
cargo-build-bpf child: rustup toolchain list -v
cargo-build-bpf child: rustup toolchain link bpf /home/rollschild/projects/example-helloworld/src/program-rust/sdk/dependencies/bpf-tools/rust
cargo-build-bpf child: cargo +bpf build --target bpfel-unknown-unknown --release
error: no such subcommand: `+bpf`
Did you mean `b`?
autopatchelf
but got the same No package found that provides library: libpthread.so.0
errorcargo
binary or use the one provided by rustup
? They both failed, as listed above but provided two different kinds of errors.One note is that the ./sdk/dependencies/bpf-tools
is correctly symlinked:
[rollschild@nixos:~/projects/example-helloworld/src/program-rust]$ ls -l ./sdk/dependencies/
total 0
lrwxrwxrwx 1 rollschild users 46 Apr 26 11:54 bpf-tools -> /home/rollschild/.cache/solana/v1.23/bpf-tools
Hi,
Good that you posted the whole thing, I will test it out and get back to you by tomorrow.
Meanwhile,
Regards,
Farseen
Now that bpf-tools
1.25 is out, I modified its version in flake.nix
, 1.23
→ 1.25
and re-nix-develop
and went through all the steps. However, I was not able to see 1.25 at all. I’m still seeing v1.23 and ./sdk/dependencies/bpf-tools
is still symlinked to ~/.cache/solana/v1.23
, which is very weird since I had already removed 1.23 everywhere:
[rollschild@nixos:~/projects/example-helloworld/src/program-rust]$ ls -l sdk/dependencies/
total 0
lrwxrwxrwx 1 rollschild users 46 Apr 26 12:45 bpf-tools -> /home/rollschild/.cache/solana/v1.23/bpf-tools
[rollschild@nixos:~/projects/example-helloworld/src/program-rust]$ ls ~/.cache/solana/
v1.23
[rollschild@nixos:~/projects/example-helloworld/src/program-rust]$ cat ../../flake.nix | grep version
name = "solana-${version}";
version = "1.10.3";
url = "https://github.com/solana-labs/solana/releases/download/v${version}/${filename}";
name = "solana-bpf-tools-${version}";
version = "1.25"; # It's 1.25, no 1.23 at all
url = "https://github.com/solana-labs/bpf-tools/releases/download/v${version}/solana-bpf-tools-linux.tar.bz2";
[rollschild@nixos:~/projects/example-helloworld/src/program-rust]$
Ooh that happens because of how Nix invalidates the store.
Basically, even if you change the URL and keep the sha, it will look at the sha and the sha in the store and decide it has not changed. It won’t download the URL and see if its sha matches with the sha written in the flake.
So, just remove the sha to make it re-download.
Then it will show that sha doesn’t match and show the correct sha. Copy that sha into the flake.nix.
- nix build won’t work with the flake file I posted. Only nix develop will work.
Thanks for reminding me that. I will just do nix develop
from now on.
- cargo from rustup should be used, not the standalone cargo.
Yeah that’s what I thought but my stupid self couldn’t get cargo
working without explicitly putting it into buildInputs
. I ran <path-to-autopatchelf>/autopatchelf ~/.rustup/toolchains/bpf
but it didn’t help.
Thank you so much for troubleshooting this for me.
So, just remove the sha to make it re-download.
Then it will show that sha doesn’t match and show the correct sha. Copy that sha into the flake.nix.
Thanks!!! I will try this.
I re-ran the whole thing and this is what was missing:
libs="/home/farseen/.cache/solana/v1.23/bpf-tools/rust/lib:/nix/store/18fz9jnhmfkzkh6p1iwwwng4i7x4rag7-gcc-10.3.0-lib/lib:/nix/store/9b9ryxskcwh573jwjz6m5l01whkcb39a-zlib-1.2.11/lib:/nix/store/6w8g7njm4mck5dmjxws0z1xnrxvl81xa-glibc-2.34-115/lib:/nix/store/6pcq8w0hnqi9ypd0fl22xhwlxjb6pvir-openssl-1.1.1n/lib" ~/nix-patchtools/result/bin/autopatchelf ./
This is how you should have run autopatchelf
. Sorry that I missed the libs=
part.
Copy-pasting the exact command won’t work though, as the hashes could be different on your system.
You need:
/home/<username>/.cache/solana/v1.23/bpf-tools/rust/lib
/nix/store/<hash>-gcc-10.x.y/lib
/nix/store/<hash>-zlib-1.x.y/lib
/nix/store/<hash>-glibc-2.34-y/lib
/nix/store/<hash>-openssl-1.1.1n/lib
cd /nix/store
and ls | grep <library-name>
to find the actual paths.
Then concatenate them with ‘:’ as separator, put it in libs
env var.
Then run autopatchelf
as before.
Build succeeded. Thanks a lot!!!
I finally put everything I did into a nix flake: GitHub - itsfarseen/solana-flake: Nix flake for Solana development
In addition, I patched cargo build-bpf
to not download BPF Tools to ~/.cache
and use the one provided by the flake instead. Because otherwise we’d have to run autopatchelf
ourselves on ~/.cache/solana
.