Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 35 additions & 26 deletions anchor-cli.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,37 @@
rust-bin,
udev,
crane,
runCommand,
writeShellScriptBin,
version ? "0.31.1",
}:
let
pname = "anchor-cli";

# Anchor IDL generation makes use of rust-nightly
# therefore we want to expose it to the environment to be used
# Due to https://github.com/solana-foundation/anchor/pull/3663
# latest nightly is always preferred when possible, since breakage may occur
# due to differing dependency versions as well
versionsDeps = {
"0.31.1" = {
hash = "sha256-c+UybdZCFL40TNvxn0PHR1ch7VPhhJFDSIScetRpS3o=";
# Unfortunately dependency on nightly compiler seems to be common
# in rust projects
rust-nightly = rust-bin.nightly."2025-04-21".minimal;
rust = rust-bin.stable."1.85.0".default;
rust-nightly = rust-bin.nightly.latest.default;
platform-tools = solana-platform-tools.override { version = "1.45"; };
patches = [ ./patches/anchor-cli/0.31.1.patch ];
};
"0.31.0" = {
hash = "sha256-CaBVdp7RPVmzzEiVazjpDLJxEkIgy1BHCwdH2mYLbGM=";
rust = rust-bin.stable."1.85.0".default;
rust-nightly = rust-bin.nightly.latest.default;
platform-tools = solana-platform-tools.override { version = "1.45"; };
patches = [ ./patches/anchor-cli/0.31.0.patch ];
};
"0.30.1" = {
hash = "sha256-3fLYTJDVCJdi6o0Zd+hb9jcPDKm4M4NzpZ8EUVW/GVw=";
rust = rust-bin.stable."1.78.0".default;
# anchor-syn v0.30.1 still uses the old API
rust-nightly = rust-bin.nightly."2025-04-15".default;
platform-tools = solana-platform-tools.override { version = "1.43"; };
patches = [ ./patches/anchor-cli/0.30.1.patch ];
};
Expand Down Expand Up @@ -89,36 +95,38 @@ let
};

cargoArtifacts = craneLib.buildDepsOnly commonArgs;

# We create a small cargo shim to dispatch to a compatible nightly version when necessary
cargoShim = writeShellScriptBin "cargo" ''
# Check that required env variables are set
if [[ -z "$_NIX_SUPPORT_STABLE_TOOLCHAIN" || -z "$_NIX_SUPPORT_NIGHTLY_TOOLCHAIN" ]]; then
echo "Error: Both _NIX_SUPPORT_STABLE_TOOLCHAIN and _NIX_SUPPORT_NIGHTLY_TOOLCHAIN environment variables must be set." >&2
exit 1
fi

if [[ "$1" == "+nightly" ]]; then
# Shift off +nightly and pass through all remaining args
shift
export PATH="$_NIX_SUPPORT_NIGHTLY_TOOLCHAIN":$PATH
exec cargo "$@"
else
export PATH="$_NIX_SUPPORT_STABLE_TOOLCHAIN":$PATH
exec cargo "$@"
fi
'';
in
craneLib.buildPackage (
commonArgs
// {
inherit cargoArtifacts;

# Ensure anchor has access to Solana's cargo and rust binaries
postInstall = let
# Due to th way anchor is calling cargo if its not wrapped
# with its own toolchain, it'll access solana rust compiler instead
# hence the nightly entry points must be wrapped with the nightly bins
# to guarantee correct usage
# In this case we've limited the nightly bin access to `cargo`
cargo-nightly = runCommand "cargo-nightly" {
nativeBuildInputs = [ makeWrapper ];
} ''
mkdir -p $out/bin

ln -s ${versionDeps.rust-nightly}/bin/cargo $out/bin/cargo

# Wrap cargo nightly so it uses the nightly toolchain only
wrapProgram $out/bin/cargo \
--prefix PATH : "${versionDeps.rust-nightly}/bin"
''
;
in
''
# Ensure anchor has access to Solana's rust binaries and our cargo shim with nightly
postInstall = ''
rust=${versionDeps.platform-tools}/bin/platform-tools-sdk/sbf/dependencies/platform-tools/rust/bin
wrapProgram $out/bin/anchor \
--prefix PATH : "$rust" ${if versionDeps ? rust-nightly then "--set RUST_NIGHTLY_BIN \"${cargo-nightly}/bin\"" else ""}
--prefix PATH : "${cargoShim}/bin" \
--set _NIX_SUPPORT_STABLE_TOOLCHAIN "$rust" \
--set _NIX_SUPPORT_NIGHTLY_TOOLCHAIN "${versionDeps.rust-nightly}/bin"
'';

cargoExtraArgs = "-p ${pname}";
Expand All @@ -130,6 +138,7 @@ craneLib.buildPackage (

passthru = {
otherVersions = builtins.attrNames versionsDeps;
rustNightly = versionDeps.rust-nightly._version;
};
}
)
27 changes: 7 additions & 20 deletions patches/anchor-cli/0.30.1.patch
Original file line number Diff line number Diff line change
Expand Up @@ -114,31 +114,18 @@ index 9befe845..7a9ae066 100644
}
}
diff --git a/idl/src/build.rs b/idl/src/build.rs
index 96dc3db2..d28a34b5 100644
index 96dc3db2..02d754c9 100644
--- a/idl/src/build.rs
+++ b/idl/src/build.rs
@@ -60,16 +60,14 @@ pub fn build_idl(

/// Build IDL.
fn build(program_path: &Path, resolution: bool, skip_lint: bool, no_docs: bool) -> Result<Idl> {
- // `nightly` toolchain is currently required for building the IDL.
- let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
- .map(|toolchain| format!("+{}", toolchain))
- .unwrap_or_else(|_| "+nightly".to_string());
+ let mut command = Command::new("cargo");
@@ -65,8 +65,6 @@ fn build(program_path: &Path, resolution: bool, skip_lint: bool, no_docs: bool)
.map(|toolchain| format!("+{}", toolchain))
.unwrap_or_else(|_| "+nightly".to_string());

- install_toolchain_if_needed(&toolchain)?;
+ if let Ok(toolchain) = std::env::var("RUSTUP_TOOLCHAIN") {
+ command.arg(&format!("+{}", toolchain));
+ }

- let output = Command::new("cargo")
+ let output = command
-
let output = Command::new("cargo")
.args([
- &toolchain,
"test",
"__anchor_private_print_idl",
"--features",
&toolchain,
@@ -202,23 +200,6 @@ fn build(program_path: &Path, resolution: bool, skip_lint: bool, no_docs: bool)
idl.ok_or_else(|| anyhow!("IDL doesn't exist"))
}
Expand Down
29 changes: 8 additions & 21 deletions patches/anchor-cli/0.31.0.patch
Original file line number Diff line number Diff line change
Expand Up @@ -152,31 +152,18 @@ index 3404b032..34b08dac 100644
}
}
diff --git a/idl/src/build.rs b/idl/src/build.rs
index ccd89745..a4edf8a5 100644
index ccd89745..83028bf4 100644
--- a/idl/src/build.rs
+++ b/idl/src/build.rs
@@ -138,15 +138,12 @@ fn build(
no_docs: bool,
cargo_args: &[String],
) -> Result<Idl> {
- // `nightly` toolchain is currently required for building the IDL.
- let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
- .map(|toolchain| format!("+{}", toolchain))
- .unwrap_or_else(|_| "+nightly".to_string());
-
@@ -143,7 +143,6 @@ fn build(
.map(|toolchain| format!("+{}", toolchain))
.unwrap_or_else(|_| "+nightly".to_string());

- install_toolchain_if_needed(&toolchain)?;
- let output = Command::new("cargo")
+ let mut command = Command::new("cargo");
+ if let Ok(toolchain) = std::env::var("RUSTUP_TOOLCHAIN") {
+ command.arg(&format!("+{}", toolchain));
+ }
+ let output = command
let output = Command::new("cargo")
.args([
- &toolchain,
"test",
"__anchor_private_print_idl",
"--features",
@@ -283,23 +280,6 @@ fn build(
&toolchain,
@@ -283,23 +282,6 @@ fn build(
idl.ok_or_else(|| anyhow!("IDL doesn't exist"))
}

Expand Down
31 changes: 7 additions & 24 deletions patches/anchor-cli/0.31.1.patch
Original file line number Diff line number Diff line change
Expand Up @@ -152,35 +152,18 @@ index 3404b032..34b08dac 100644
}
}
diff --git a/idl/src/build.rs b/idl/src/build.rs
index ccd89745..3c958377 100644
index ccd89745..83028bf4 100644
--- a/idl/src/build.rs
+++ b/idl/src/build.rs
@@ -139,14 +139,18 @@ fn build(
cargo_args: &[String],
) -> Result<Idl> {
// `nightly` toolchain is currently required for building the IDL.
- let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
- .map(|toolchain| format!("+{}", toolchain))
- .unwrap_or_else(|_| "+nightly".to_string());
+ let cargo_path = std::env::var("RUST_NIGHTLY_BIN")
+ .map(|bin| format!("{}/cargo", bin))
+ .unwrap_or_else(|_| "cargo".to_string());
@@ -143,7 +143,6 @@ fn build(
.map(|toolchain| format!("+{}", toolchain))
.unwrap_or_else(|_| "+nightly".to_string());

- install_toolchain_if_needed(&toolchain)?;
- let output = Command::new("cargo")
+ eprintln!("Cargo at {}", cargo_path);
+
+ let mut command = Command::new(cargo_path);
+ if let Ok(toolchain) = std::env::var("RUSTUP_TOOLCHAIN") {
+ command.arg(&format!("+{}", toolchain));
+ }
+ let output = command
let output = Command::new("cargo")
.args([
- &toolchain,
"test",
"__anchor_private_print_idl",
"--features",
@@ -283,23 +287,6 @@ fn build(
&toolchain,
@@ -283,23 +282,6 @@ fn build(
idl.ok_or_else(|| anyhow!("IDL doesn't exist"))
}

Expand Down
Loading