diff --git a/platform-tools-sdk/cargo-build-sbf/src/main.rs b/platform-tools-sdk/cargo-build-sbf/src/main.rs index ebd41b2f735aa8..7b0d9ad430b317 100644 --- a/platform-tools-sdk/cargo-build-sbf/src/main.rs +++ b/platform-tools-sdk/cargo-build-sbf/src/main.rs @@ -6,7 +6,7 @@ use { crate::{ post_processing::post_process, toolchain::{ - corrupted_toolchain, get_base_rust_version, install_tools, + corrupted_toolchain, generate_toolchain_name, get_base_rust_version, install_tools, DEFAULT_PLATFORM_TOOLS_VERSION, }, utils::{rust_target_triple, spawn}, @@ -134,7 +134,7 @@ fn prepare_environment( config: &Config, package: Option<&cargo_metadata::Package>, metadata: &cargo_metadata::Metadata, -) { +) -> String { let root_dir = if let Some(package) = package { &package.manifest_path.parent().unwrap_or_else(|| { error!("Unable to get directory of {}", package.manifest_path); @@ -149,10 +149,10 @@ fn prepare_environment( exit(1); }); - install_tools(config, package, metadata); + install_tools(config, package, metadata) } -fn invoke_cargo(config: &Config) { +fn invoke_cargo(config: &Config, validated_toolchain_version: String) { let target_triple = rust_target_triple(config); info!("Solana SDK: {}", config.sbf_sdk.display()); @@ -226,8 +226,11 @@ fn invoke_cargo(config: &Config) { let cargo_build = PathBuf::from("cargo"); let mut cargo_build_args = vec![]; + let toolchain_name = generate_toolchain_name(validated_toolchain_version.as_str()); + let toolchain_argument = format!("+{toolchain_name}"); + if !config.no_rustup_override { - cargo_build_args.push("+solana"); + cargo_build_args.push(toolchain_argument.as_str()); }; cargo_build_args.append(&mut vec!["build", "--release", "--target", &target_triple]); @@ -323,15 +326,16 @@ fn build_solana(config: Config, manifest_path: Option) { if let Some(root_package) = metadata.root_package() { if !config.workspace { let program_name = generate_program_name(root_package); - prepare_environment(&config, Some(root_package), &metadata); - invoke_cargo(&config); + let validated_toolchain_version = + prepare_environment(&config, Some(root_package), &metadata); + invoke_cargo(&config, validated_toolchain_version); post_process(&config, target_dir.as_ref(), program_name); return; } } - prepare_environment(&config, None, &metadata); - invoke_cargo(&config); + let validated_toolchain_version = prepare_environment(&config, None, &metadata); + invoke_cargo(&config, validated_toolchain_version); let all_sbf_packages = metadata .packages diff --git a/platform-tools-sdk/cargo-build-sbf/src/toolchain.rs b/platform-tools-sdk/cargo-build-sbf/src/toolchain.rs index 956809f6501814..3bc553e9fc66c8 100644 --- a/platform-tools-sdk/cargo-build-sbf/src/toolchain.rs +++ b/platform-tools-sdk/cargo-build-sbf/src/toolchain.rs @@ -19,6 +19,7 @@ use { }; pub(crate) const DEFAULT_PLATFORM_TOOLS_VERSION: &str = "v1.50"; +pub(crate) const DEFAULT_RUST_VERSION: &str = "1.84.1"; fn find_installed_platform_tools() -> Vec { let solana = home_dir().join(".cache").join("solana"); @@ -232,8 +233,25 @@ pub(crate) fn corrupted_toolchain(config: &Config) -> bool { || !cargo.try_exists().unwrap_or(false) } +pub(crate) fn generate_toolchain_name(requested_toolchain_version: &str) -> String { + if requested_toolchain_version == DEFAULT_PLATFORM_TOOLS_VERSION { + return format!("{DEFAULT_RUST_VERSION}-sbpf-solana-{DEFAULT_PLATFORM_TOOLS_VERSION}"); + } + + let rustc_version_string = get_base_rust_version(requested_toolchain_version); + // The version string has the format 'rustc 1.84.1' + let mut it = rustc_version_string.split_whitespace(); + // Jump 'rustc' + let _ = it.next(); + format!( + "{}-sbpf-solana-{}", + it.next().unwrap(), + requested_toolchain_version + ) +} + // check whether custom solana toolchain is linked, and link it if it is not. -fn link_solana_toolchain(config: &Config) { +fn link_solana_toolchain(config: &Config, requested_toolchain_version: &str) { let toolchain_path = config .sbf_sdk .join("dependencies") @@ -249,14 +267,19 @@ fn link_solana_toolchain(config: &Config) { if config.verbose { debug!("{}", rustup_output); } + let requested_toolchain_name = generate_toolchain_name(requested_toolchain_version); let mut do_link = true; for line in rustup_output.lines() { - if line.starts_with("solana") { - let mut it = line.split_whitespace(); - let _ = it.next(); - let path = it.next(); - if path.unwrap() != toolchain_path.to_str().unwrap() { - let rustup_args = vec!["toolchain", "uninstall", "solana"]; + let substrings: Vec<&str> = line.split(' ').collect(); + let installed_toolchain_name = *substrings.first().unwrap(); + if installed_toolchain_name.contains("solana") { + // Paths are always the last item in the output of 'rust toolchain list -v' + let path = substrings.last(); + if *path.unwrap() != toolchain_path.to_str().unwrap() + || requested_toolchain_name != installed_toolchain_name + { + // The toolchain name is always the first item in the output + let rustup_args = vec!["toolchain", "uninstall", installed_toolchain_name]; let output = spawn( &rustup, rustup_args, @@ -271,11 +294,12 @@ fn link_solana_toolchain(config: &Config) { break; } } + if do_link { let rustup_args = vec![ "toolchain", "link", - "solana", + requested_toolchain_name.as_str(), toolchain_path.to_str().unwrap(), ]; let output = spawn( @@ -293,7 +317,7 @@ pub(crate) fn install_tools( config: &Config, package: Option<&cargo_metadata::Package>, metadata: &cargo_metadata::Metadata, -) { +) -> String { let platform_tools_version = config.platform_tools_version.unwrap_or_else(|| { let workspace_tools_version = metadata.workspace_metadata.get("solana").and_then(|v| v.get("tools-version")).and_then(|v| v.as_str()); let package_tools_version = package.map(|p| p.metadata.get("solana").and_then(|v| v.get("tools-version")).and_then(|v| v.as_str())).unwrap_or(None); @@ -310,6 +334,8 @@ pub(crate) fn install_tools( } }); + let platform_tools_version = + validate_platform_tools_version(platform_tools_version, DEFAULT_PLATFORM_TOOLS_VERSION); if !config.skip_tools_install { let arch = if cfg!(target_arch = "aarch64") { "aarch64" @@ -317,9 +343,6 @@ pub(crate) fn install_tools( "x86_64" }; - let platform_tools_version = - validate_platform_tools_version(platform_tools_version, DEFAULT_PLATFORM_TOOLS_VERSION); - let platform_tools_download_file_name = if cfg!(target_os = "windows") { format!("platform-tools-windows-{arch}.tar.bz2") } else if cfg!(target_os = "macos") { @@ -360,7 +383,7 @@ pub(crate) fn install_tools( let target_triple = rust_target_triple(config); check_solana_target_installed(&target_triple); } else { - link_solana_toolchain(config); + link_solana_toolchain(config, &platform_tools_version); // RUSTC variable overrides cargo + mechanism of // selecting the rust compiler and makes cargo run a rust compiler // other than the one linked in Solana toolchain. We have to prevent @@ -372,6 +395,8 @@ pub(crate) fn install_tools( env::remove_var("RUSTC") } } + + platform_tools_version } // allow user to set proper `rustc` into RUSTC or into PATH diff --git a/platform-tools-sdk/sbf/scripts/install.sh b/platform-tools-sdk/sbf/scripts/install.sh index f7e8f609b93cc3..8f6df516cbedff 100755 --- a/platform-tools-sdk/sbf/scripts/install.sh +++ b/platform-tools-sdk/sbf/scripts/install.sh @@ -109,30 +109,46 @@ if [[ ! -e criterion-$version.md || ! -e criterion ]]; then fi # Install platform tools -version=v1.50 -if [[ ! -e platform-tools-$version.md || ! -e platform-tools ]]; then +tools_version=v1.50 +rust_version=1.84.1 +if [[ ! -e platform-tools-$tools_version.md || ! -e platform-tools ]]; then ( set -e rm -rf platform-tools* job="download \ https://github.com/anza-xyz/platform-tools/releases/download \ - $version \ + $tools_version \ platform-tools-${machine}-${arch}.tar.bz2 \ platform-tools" - get $version platform-tools "$job" + get $tools_version platform-tools "$job" ) exitcode=$? if [[ $exitcode -ne 0 ]]; then exit 1 fi - touch platform-tools-$version.md + touch platform-tools-$tools_version.md set -ex ./platform-tools/rust/bin/rustc --version ./platform-tools/rust/bin/rustc --print sysroot + + if [[ "${BASH_VERSINFO[0]}" -lt 4 ]]; then + # MacOS has an outdated version of bash and does not support the safer 'mapfile' alternative + toolchains=() + while IFS='' read -r line; do toolchains+=("$line"); done < <(rustup toolchain list) + else + mapfile -t toolchains < <(rustup toolchain list) + fi + set +e - rustup toolchain uninstall solana + for item in "${toolchains[@]}" + do + if [[ $item == *"solana"* ]]; then + rustup toolchain uninstall "$item" + fi + done set -e - rustup toolchain link solana platform-tools/rust + + rustup toolchain link "$rust_version-sbpf-solana-$tools_version" platform-tools/rust fi exit 0 diff --git a/programs/sbf/Makefile b/programs/sbf/Makefile index 9b2ae919aef1b2..d92c21b8c3b0bf 100755 --- a/programs/sbf/Makefile +++ b/programs/sbf/Makefile @@ -30,11 +30,11 @@ test-version: $(MAKE) test-all rust-v0: - cargo +solana build --release --target sbpf-solana-solana --workspace ; \ + cargo +1.84.1-sbpf-solana-v1.50 build --release --target sbpf-solana-solana --workspace ; \ cp -r target/sbpf-solana-solana/release/* target/deploy rust-new: - RUSTFLAGS="-C instrument-coverage=no" cargo +solana build --release --target sbpf$(VER)-solana-solana --workspace ; \ + RUSTFLAGS="-C instrument-coverage=no" cargo +1.84.1-sbpf-solana-v1.50 build --release --target sbpf$(VER)-solana-solana --workspace ; \ cp -r target/sbpf$(VER)-solana-solana/release/* target/deploy .PHONY: test-v3