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
22 changes: 13 additions & 9 deletions platform-tools-sdk/cargo-build-sbf/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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);
Expand All @@ -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());
Expand Down Expand Up @@ -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}");
Comment on lines +229 to +230
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Can you move these lines under the !config.no_rustup_override branch? generate_toolchain_name won't work properly in nix-like environments

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see what I can do. generate_toolchain_name is outside the if condition because cargo_build_args requires a &str not a String.

Why do you think it won't work correctly? Maybe we could address that instead.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In nix environments, there are a few considerations:

  • rustup doesn't work, so any invocation of cargo with a toolchain fails
  • there's no concept of $HOME

The logic to find the toolchain assumes that things are stored under $HOME, so we should avoid doing that if someone doesn't want to install tools. And if someone doesn't want to use rustup, we shouldn't use any commands that have cargo +{toolchain_name}, and assume that the default rust can compile solana programs.

You can see how cargo-build-sbf is wrapped at https://github.com/arijoon/solana-nix/blob/87bea8cac979d14c758c24d2b9178c44a6e95b39/solana-cli.nix#L132

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet the solution for nix, but I moved the function to inside the if condition: #7024.


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]);
Expand Down Expand Up @@ -323,15 +326,16 @@ fn build_solana(config: Config, manifest_path: Option<PathBuf>) {
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
Expand Down
51 changes: 38 additions & 13 deletions platform-tools-sdk/cargo-build-sbf/src/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> {
let solana = home_dir().join(".cache").join("solana");
Expand Down Expand Up @@ -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")
Expand All @@ -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,
Expand All @@ -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(
Expand All @@ -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);
Expand All @@ -310,16 +334,15 @@ 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"
} else {
"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") {
Expand Down Expand Up @@ -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 +<toolchain> 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
Expand All @@ -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
Expand Down
30 changes: 23 additions & 7 deletions platform-tools-sdk/sbf/scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions programs/sbf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading