Add cargo bpf tools that invoke newer sbf tools and issue deprecation notice
This commit is contained in:
parent
9425478f86
commit
4dfaf15a46
|
@ -4495,10 +4495,20 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-cargo-build-bpf"
|
name = "solana-cargo-build-bpf"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
dependencies = [
|
||||||
|
"cargo_metadata",
|
||||||
|
"clap 3.1.8",
|
||||||
|
"solana-sdk 1.11.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "solana-cargo-build-sbf"
|
||||||
|
version = "1.11.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bzip2",
|
"bzip2",
|
||||||
"cargo_metadata",
|
"cargo_metadata",
|
||||||
"clap 3.1.8",
|
"clap 3.1.8",
|
||||||
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"solana-download-utils",
|
"solana-download-utils",
|
||||||
|
@ -4514,6 +4524,14 @@ dependencies = [
|
||||||
"clap 3.1.8",
|
"clap 3.1.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "solana-cargo-test-sbf"
|
||||||
|
version = "1.11.0"
|
||||||
|
dependencies = [
|
||||||
|
"cargo_metadata",
|
||||||
|
"clap 3.1.8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-clap-utils"
|
name = "solana-clap-utils"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
|
@ -66,7 +66,9 @@ members = [
|
||||||
"runtime/store-tool",
|
"runtime/store-tool",
|
||||||
"sdk",
|
"sdk",
|
||||||
"sdk/cargo-build-bpf",
|
"sdk/cargo-build-bpf",
|
||||||
|
"sdk/cargo-build-sbf",
|
||||||
"sdk/cargo-test-bpf",
|
"sdk/cargo-test-bpf",
|
||||||
|
"sdk/cargo-test-sbf",
|
||||||
"sdk/gen-headers",
|
"sdk/gen-headers",
|
||||||
"send-transaction-service",
|
"send-transaction-service",
|
||||||
"stake-accounts",
|
"stake-accounts",
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
here=$(dirname "$0")
|
||||||
|
|
||||||
|
maybe_bpf_sdk="--bpf-sdk $here/sdk/bpf"
|
||||||
|
for a in "$@"; do
|
||||||
|
if [[ $a = --bpf-sdk ]]; then
|
||||||
|
maybe_bpf_sdk=
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
if [[ ! -f "$here"/sdk/bpf/syscalls.txt ]]; then
|
||||||
|
"$here"/cargo build --manifest-path "$here"/programs/bpf_loader/gen-syscall-list/Cargo.toml
|
||||||
|
fi
|
||||||
|
if [[ ! -f "$here"/target/debug/cargo-build-sbf ]]; then
|
||||||
|
"$here"/cargo build --manifest-path "$here"/sdk/cargo-build-sbf/Cargo.toml
|
||||||
|
fi
|
||||||
|
exec "$here"/cargo run --manifest-path "$here"/sdk/cargo-build-bpf/Cargo.toml -- $maybe_bpf_sdk "$@"
|
|
@ -2,15 +2,15 @@
|
||||||
|
|
||||||
here=$(dirname "$0")
|
here=$(dirname "$0")
|
||||||
|
|
||||||
maybe_bpf_sdk="--bpf-sdk $here/sdk/bpf"
|
maybe_sbf_sdk="--sbf-sdk $here/sdk/bpf"
|
||||||
for a in "$@"; do
|
for a in "$@"; do
|
||||||
if [[ $a = --bpf-sdk ]]; then
|
if [[ $a = --sbf-sdk ]]; then
|
||||||
maybe_bpf_sdk=
|
maybe_sbf_sdk=
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
if [[ ! -f sdk/bpf/syscalls.txt ]]; then
|
if [[ ! -f "$here"/sdk/bpf/syscalls.txt ]]; then
|
||||||
"$here"/cargo build --manifest-path "$here"/programs/bpf_loader/gen-syscall-list/Cargo.toml
|
"$here"/cargo build --manifest-path "$here"/programs/bpf_loader/gen-syscall-list/Cargo.toml
|
||||||
fi
|
fi
|
||||||
exec "$here"/cargo run --manifest-path "$here"/sdk/cargo-build-bpf/Cargo.toml -- $maybe_bpf_sdk "$@"
|
exec "$here"/cargo run --manifest-path "$here"/sdk/cargo-build-sbf/Cargo.toml -- $maybe_sbf_sdk "$@"
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
here=$(dirname "$0")
|
||||||
|
|
||||||
|
maybe_bpf_sdk="--bpf-sdk $here/sdk/bpf"
|
||||||
|
for a in "$@"; do
|
||||||
|
if [[ $a = --bpf-sdk ]]; then
|
||||||
|
maybe_bpf_sdk=
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
export CARGO_BUILD_BPF="$here"/cargo-build-bpf
|
||||||
|
set -x
|
||||||
|
if [[ ! -f "$here"/target/debug/cargo-build-sbf ]]; then
|
||||||
|
"$here"/cargo build --manifest-path "$here"/sdk/cargo-build-sbf/Cargo.toml
|
||||||
|
fi
|
||||||
|
if [[ ! -f "$here"/target/debug/cargo-test-sbf ]]; then
|
||||||
|
"$here"/cargo build --manifest-path "$here"/sdk/cargo-test-sbf/Cargo.toml
|
||||||
|
fi
|
||||||
|
exec "$here"/cargo run --manifest-path "$here"/sdk/cargo-test-bpf/Cargo.toml -- $maybe_bpf_sdk "$@"
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
here=$(dirname "$0")
|
here=$(dirname "$0")
|
||||||
|
|
||||||
maybe_bpf_sdk="--bpf-sdk $here/sdk/bpf"
|
maybe_sbf_sdk="--sbf-sdk $here/sdk/bpf"
|
||||||
for a in "$@"; do
|
for a in "$@"; do
|
||||||
if [[ $a = --bpf-sdk ]]; then
|
if [[ $a = --sbf-sdk ]]; then
|
||||||
maybe_bpf_sdk=
|
maybe_sbf_sdk=
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
export CARGO_BUILD_BPF="$here"/cargo-build-bpf
|
export CARGO_BUILD_SBF="$here"/cargo-build-sbf
|
||||||
set -x
|
set -x
|
||||||
exec "$here"/cargo run --manifest-path "$here"/sdk/cargo-test-bpf/Cargo.toml -- $maybe_bpf_sdk "$@"
|
exec "$here"/cargo run --manifest-path "$here"/sdk/cargo-test-sbf/Cargo.toml -- $maybe_sbf_sdk "$@"
|
||||||
|
|
|
@ -9,16 +9,16 @@ here="$(dirname "$0")"
|
||||||
|
|
||||||
SBF_TOOLS_VERSION=unknown
|
SBF_TOOLS_VERSION=unknown
|
||||||
|
|
||||||
cargo_build_bpf_main="${here}/../sdk/cargo-build-bpf/src/main.rs"
|
cargo_build_sbf_main="${here}/../sdk/cargo-build-sbf/src/main.rs"
|
||||||
if [[ -f "${cargo_build_bpf_main}" ]]; then
|
if [[ -f "${cargo_build_sbf_main}" ]]; then
|
||||||
version=$(sed -e 's/^.*bpf_tools_version\s*=\s*"\(v[0-9.]\+\)".*/\1/;t;d' "${cargo_build_bpf_main}")
|
version=$(sed -e 's/^.*sbf_tools_version\s*=\s*"\(v[0-9.]\+\)".*/\1/;t;d' "${cargo_build_sbf_main}")
|
||||||
if [[ ${version} != '' ]]; then
|
if [[ ${version} != '' ]]; then
|
||||||
SBF_TOOLS_VERSION="${version}"
|
SBF_TOOLS_VERSION="${version}"
|
||||||
else
|
else
|
||||||
echo '--- unable to parse SBF_TOOLS_VERSION'
|
echo '--- unable to parse SBF_TOOLS_VERSION'
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "--- '${cargo_build_bpf_main}' not present"
|
echo "--- '${cargo_build_sbf_main}' not present"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo SBF_TOOLS_VERSION="${SBF_TOOLS_VERSION}"
|
echo SBF_TOOLS_VERSION="${SBF_TOOLS_VERSION}"
|
||||||
|
|
|
@ -78,7 +78,7 @@ test-stable-bpf)
|
||||||
|
|
||||||
bpf_dump_archive="bpf-dumps.tar.bz2"
|
bpf_dump_archive="bpf-dumps.tar.bz2"
|
||||||
rm -f "$bpf_dump_archive"
|
rm -f "$bpf_dump_archive"
|
||||||
tar cjvf "$bpf_dump_archive" "${bpf_target_path}"/{deploy/*.txt,bpfel-unknown-unknown/release/*.so}
|
tar cjvf "$bpf_dump_archive" "${bpf_target_path}"/{deploy/*.txt,sbf-solana-solana/release/*.so}
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
test-stable-perf)
|
test-stable-perf)
|
||||||
|
|
|
@ -401,6 +401,8 @@ fn default_shared_object_dirs() -> Vec<PathBuf> {
|
||||||
let mut search_path = vec![];
|
let mut search_path = vec![];
|
||||||
if let Ok(bpf_out_dir) = std::env::var("BPF_OUT_DIR") {
|
if let Ok(bpf_out_dir) = std::env::var("BPF_OUT_DIR") {
|
||||||
search_path.push(PathBuf::from(bpf_out_dir));
|
search_path.push(PathBuf::from(bpf_out_dir));
|
||||||
|
} else if let Ok(bpf_out_dir) = std::env::var("SBF_OUT_DIR") {
|
||||||
|
search_path.push(PathBuf::from(bpf_out_dir));
|
||||||
}
|
}
|
||||||
search_path.push(PathBuf::from("tests/fixtures"));
|
search_path.push(PathBuf::from("tests/fixtures"));
|
||||||
if let Ok(dir) = std::env::current_dir() {
|
if let Ok(dir) = std::env::current_dir() {
|
||||||
|
@ -450,7 +452,8 @@ impl Default for ProgramTest {
|
||||||
solana_runtime::system_instruction_processor=trace,\
|
solana_runtime::system_instruction_processor=trace,\
|
||||||
solana_program_test=info",
|
solana_program_test=info",
|
||||||
);
|
);
|
||||||
let prefer_bpf = std::env::var("BPF_OUT_DIR").is_ok();
|
let prefer_bpf =
|
||||||
|
std::env::var("BPF_OUT_DIR").is_ok() || std::env::var("SBF_OUT_DIR").is_ok();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
accounts: vec![],
|
accounts: vec![],
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Cargo.lock
|
|
@ -0,0 +1,22 @@
|
||||||
|
[package]
|
||||||
|
name = "solana-cargo-build-bpf"
|
||||||
|
version = "1.11.0"
|
||||||
|
description = "Compile a local package and all of its dependencies using the Solana SBF SDK"
|
||||||
|
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||||
|
repository = "https://github.com/solana-labs/solana"
|
||||||
|
homepage = "https://solana.com/"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cargo_metadata = "0.14.2"
|
||||||
|
clap = { version = "3.1.5", features = ["cargo", "env"] }
|
||||||
|
solana-sdk = { path = "..", version = "=1.11.0" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
program = []
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "cargo-build-bpf"
|
||||||
|
path = "src/main.rs"
|
|
@ -0,0 +1,55 @@
|
||||||
|
use std::{
|
||||||
|
env,
|
||||||
|
path::PathBuf,
|
||||||
|
process::{exit, Command, Stdio},
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Warning: cargo-build-bpf is deprecated. Please, use cargo-build-sbf");
|
||||||
|
let mut args = env::args()
|
||||||
|
.map(|x| {
|
||||||
|
let s = x;
|
||||||
|
s.replace("--bpf", "--sbf")
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let program = if let Some(arg0) = args.get(0) {
|
||||||
|
let arg0 = arg0.replace("build-bpf", "build-sbf");
|
||||||
|
args.remove(0);
|
||||||
|
PathBuf::from(arg0)
|
||||||
|
} else {
|
||||||
|
PathBuf::from("cargo-build-sbf")
|
||||||
|
};
|
||||||
|
// When run as a cargo subcommand, the first program argument is the subcommand name.
|
||||||
|
// Remove it
|
||||||
|
if let Some(arg1) = args.get(1) {
|
||||||
|
if arg1 == "build-bpf" {
|
||||||
|
args.remove(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print!("cargo-build-bpf child: {}", program.display());
|
||||||
|
for a in &args {
|
||||||
|
print!(" {}", a);
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
let child = Command::new(&program)
|
||||||
|
.args(&args)
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap_or_else(|err| {
|
||||||
|
eprintln!("Failed to execute {}: {}", program.display(), err);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
let output = child.wait_with_output().expect("failed to wait on child");
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
output
|
||||||
|
.stdout
|
||||||
|
.as_slice()
|
||||||
|
.iter()
|
||||||
|
.map(|&c| c as char)
|
||||||
|
.collect::<String>()
|
||||||
|
);
|
||||||
|
let code = output.status.code().unwrap_or(1);
|
||||||
|
exit(code);
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "solana-cargo-build-bpf"
|
name = "solana-cargo-build-sbf"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
description = "Compile a local package and all of its dependencies using the Solana BPF SDK"
|
description = "Compile a local package and all of its dependencies using the Solana SBF SDK"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
|
@ -13,6 +13,7 @@ publish = false
|
||||||
bzip2 = "0.4.3"
|
bzip2 = "0.4.3"
|
||||||
cargo_metadata = "0.14.2"
|
cargo_metadata = "0.14.2"
|
||||||
clap = { version = "3.1.5", features = ["cargo", "env"] }
|
clap = { version = "3.1.5", features = ["cargo", "env"] }
|
||||||
|
log = { version = "0.4.14", features = ["std"] }
|
||||||
regex = "1.5.6"
|
regex = "1.5.6"
|
||||||
solana-download-utils = { path = "../../download-utils", version = "=1.11.0" }
|
solana-download-utils = { path = "../../download-utils", version = "=1.11.0" }
|
||||||
solana-sdk = { path = "..", version = "=1.11.0" }
|
solana-sdk = { path = "..", version = "=1.11.0" }
|
||||||
|
@ -25,5 +26,5 @@ serial_test = "*"
|
||||||
program = []
|
program = []
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "cargo-build-bpf"
|
name = "cargo-build-sbf"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use {
|
use {
|
||||||
bzip2::bufread::BzDecoder,
|
bzip2::bufread::BzDecoder,
|
||||||
clap::{crate_description, crate_name, crate_version, Arg},
|
clap::{crate_description, crate_name, crate_version, Arg},
|
||||||
|
log::*,
|
||||||
regex::Regex,
|
regex::Regex,
|
||||||
solana_download_utils::download_file,
|
solana_download_utils::download_file,
|
||||||
solana_sdk::signature::{write_keypair_file, Keypair},
|
solana_sdk::signature::{write_keypair_file, Keypair},
|
||||||
|
@ -19,9 +20,9 @@ use {
|
||||||
|
|
||||||
struct Config<'a> {
|
struct Config<'a> {
|
||||||
cargo_args: Option<Vec<&'a str>>,
|
cargo_args: Option<Vec<&'a str>>,
|
||||||
bpf_out_dir: Option<PathBuf>,
|
sbf_out_dir: Option<PathBuf>,
|
||||||
bpf_sdk: PathBuf,
|
sbf_sdk: PathBuf,
|
||||||
bpf_tools_version: &'a str,
|
sbf_tools_version: &'a str,
|
||||||
dump: bool,
|
dump: bool,
|
||||||
features: Vec<String>,
|
features: Vec<String>,
|
||||||
generate_child_script_on_failure: bool,
|
generate_child_script_on_failure: bool,
|
||||||
|
@ -36,15 +37,15 @@ impl Default for Config<'_> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
cargo_args: None,
|
cargo_args: None,
|
||||||
bpf_sdk: env::current_exe()
|
sbf_sdk: env::current_exe()
|
||||||
.expect("Unable to get current executable")
|
.expect("Unable to get current executable")
|
||||||
.parent()
|
.parent()
|
||||||
.expect("Unable to get parent directory")
|
.expect("Unable to get parent directory")
|
||||||
.to_path_buf()
|
.to_path_buf()
|
||||||
.join("sdk")
|
.join("sdk")
|
||||||
.join("bpf"),
|
.join("bpf"),
|
||||||
bpf_out_dir: None,
|
sbf_out_dir: None,
|
||||||
bpf_tools_version: "(unknown)",
|
sbf_tools_version: "(unknown)",
|
||||||
dump: false,
|
dump: false,
|
||||||
features: vec![],
|
features: vec![],
|
||||||
generate_child_script_on_failure: false,
|
generate_child_script_on_failure: false,
|
||||||
|
@ -63,18 +64,18 @@ where
|
||||||
S: AsRef<OsStr>,
|
S: AsRef<OsStr>,
|
||||||
{
|
{
|
||||||
let args = args.into_iter().collect::<Vec<_>>();
|
let args = args.into_iter().collect::<Vec<_>>();
|
||||||
print!("cargo-build-bpf child: {}", program.display());
|
let mut msg = format!("cargo-build-sbf child: {}", program.display());
|
||||||
for arg in args.iter() {
|
for arg in args.iter() {
|
||||||
print!(" {}", arg.as_ref().to_str().unwrap_or("?"));
|
msg = msg + &format!(" {}", arg.as_ref().to_str().unwrap_or("?")).to_string();
|
||||||
}
|
}
|
||||||
println!();
|
info!("{}", msg);
|
||||||
|
|
||||||
let child = Command::new(program)
|
let child = Command::new(program)
|
||||||
.args(&args)
|
.args(&args)
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
eprintln!("Failed to execute {}: {}", program.display(), err);
|
error!("Failed to execute {}: {}", program.display(), err);
|
||||||
exit(1);
|
exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -83,9 +84,9 @@ where
|
||||||
if !generate_child_script_on_failure {
|
if !generate_child_script_on_failure {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
eprintln!("cargo-build-bpf exited on command execution failure");
|
error!("cargo-build-sbf exited on command execution failure");
|
||||||
let script_name = format!(
|
let script_name = format!(
|
||||||
"cargo-build-bpf-child-script-{}.sh",
|
"cargo-build-sbf-child-script-{}.sh",
|
||||||
program.file_name().unwrap().to_str().unwrap(),
|
program.file_name().unwrap().to_str().unwrap(),
|
||||||
);
|
);
|
||||||
let file = File::create(&script_name).unwrap();
|
let file = File::create(&script_name).unwrap();
|
||||||
|
@ -99,7 +100,7 @@ where
|
||||||
}
|
}
|
||||||
writeln!(out).unwrap();
|
writeln!(out).unwrap();
|
||||||
out.flush().unwrap();
|
out.flush().unwrap();
|
||||||
eprintln!(
|
error!(
|
||||||
"To rerun the failed command for debugging use {}",
|
"To rerun the failed command for debugging use {}",
|
||||||
script_name,
|
script_name,
|
||||||
);
|
);
|
||||||
|
@ -123,7 +124,7 @@ fn install_if_missing(
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// Check whether the target path is an empty directory. This can
|
// Check whether the target path is an empty directory. This can
|
||||||
// happen if package download failed on previous run of
|
// happen if package download failed on previous run of
|
||||||
// cargo-build-bpf. Remove the target_path directory in this
|
// cargo-build-sbf. Remove the target_path directory in this
|
||||||
// case.
|
// case.
|
||||||
if target_path.is_dir()
|
if target_path.is_dir()
|
||||||
&& target_path
|
&& target_path
|
||||||
|
@ -149,7 +150,7 @@ fn install_if_missing(
|
||||||
fs::create_dir_all(&target_path).map_err(|err| err.to_string())?;
|
fs::create_dir_all(&target_path).map_err(|err| err.to_string())?;
|
||||||
let mut url = String::from(url);
|
let mut url = String::from(url);
|
||||||
url.push('/');
|
url.push('/');
|
||||||
url.push_str(config.bpf_tools_version);
|
url.push_str(config.sbf_tools_version);
|
||||||
url.push('/');
|
url.push('/');
|
||||||
url.push_str(download_file_name);
|
url.push_str(download_file_name);
|
||||||
let download_file_path = target_path.join(download_file_name);
|
let download_file_path = target_path.join(download_file_name);
|
||||||
|
@ -166,8 +167,8 @@ fn install_if_missing(
|
||||||
fs::remove_file(download_file_path).map_err(|err| err.to_string())?;
|
fs::remove_file(download_file_path).map_err(|err| err.to_string())?;
|
||||||
}
|
}
|
||||||
// Make a symbolic link source_path -> target_path in the
|
// Make a symbolic link source_path -> target_path in the
|
||||||
// sdk/bpf/dependencies directory if no valid link found.
|
// sdk/sbf/dependencies directory if no valid link found.
|
||||||
let source_base = config.bpf_sdk.join("dependencies");
|
let source_base = config.sbf_sdk.join("dependencies");
|
||||||
if !source_base.exists() {
|
if !source_base.exists() {
|
||||||
fs::create_dir_all(&source_base).map_err(|err| err.to_string())?;
|
fs::create_dir_all(&source_base).map_err(|err| err.to_string())?;
|
||||||
}
|
}
|
||||||
|
@ -293,7 +294,7 @@ fn postprocess_dump(program_dump: &Path) {
|
||||||
// Check whether the built .so file contains undefined symbols that are
|
// Check whether the built .so file contains undefined symbols that are
|
||||||
// not known to the runtime and warn about them if any.
|
// not known to the runtime and warn about them if any.
|
||||||
fn check_undefined_symbols(config: &Config, program: &Path) {
|
fn check_undefined_symbols(config: &Config, program: &Path) {
|
||||||
let syscalls_txt = config.bpf_sdk.join("syscalls.txt");
|
let syscalls_txt = config.sbf_sdk.join("syscalls.txt");
|
||||||
let file = match File::open(syscalls_txt) {
|
let file = match File::open(syscalls_txt) {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
_ => return,
|
_ => return,
|
||||||
|
@ -308,9 +309,9 @@ fn check_undefined_symbols(config: &Config, program: &Path) {
|
||||||
Regex::new(r"^ *[0-9]+: [0-9a-f]{16} +[0-9a-f]+ +NOTYPE +GLOBAL +DEFAULT +UND +(.+)")
|
Regex::new(r"^ *[0-9]+: [0-9a-f]{16} +[0-9a-f]+ +NOTYPE +GLOBAL +DEFAULT +UND +(.+)")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let readelf = config
|
let readelf = config
|
||||||
.bpf_sdk
|
.sbf_sdk
|
||||||
.join("dependencies")
|
.join("dependencies")
|
||||||
.join("bpf-tools")
|
.join("sbf-tools")
|
||||||
.join("llvm")
|
.join("llvm")
|
||||||
.join("bin")
|
.join("bin")
|
||||||
.join("llvm-readelf");
|
.join("llvm-readelf");
|
||||||
|
@ -322,7 +323,7 @@ fn check_undefined_symbols(config: &Config, program: &Path) {
|
||||||
config.generate_child_script_on_failure,
|
config.generate_child_script_on_failure,
|
||||||
);
|
);
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
println!("{}", output);
|
debug!("{}", output);
|
||||||
}
|
}
|
||||||
let mut unresolved_symbols: Vec<String> = Vec::new();
|
let mut unresolved_symbols: Vec<String> = Vec::new();
|
||||||
for line in output.lines() {
|
for line in output.lines() {
|
||||||
|
@ -336,20 +337,20 @@ fn check_undefined_symbols(config: &Config, program: &Path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !unresolved_symbols.is_empty() {
|
if !unresolved_symbols.is_empty() {
|
||||||
println!(
|
warn!(
|
||||||
"Warning: the following functions are undefined and not known syscalls {:?}.",
|
"The following functions are undefined and not known syscalls {:?}.",
|
||||||
unresolved_symbols
|
unresolved_symbols
|
||||||
);
|
);
|
||||||
println!(" Calling them will trigger a run-time error.");
|
warn!(" Calling them will trigger a run-time error.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check whether custom BPF toolchain is linked, and link it if it is not.
|
// check whether custom SBF toolchain is linked, and link it if it is not.
|
||||||
fn link_bpf_toolchain(config: &Config) {
|
fn link_sbf_toolchain(config: &Config) {
|
||||||
let toolchain_path = config
|
let toolchain_path = config
|
||||||
.bpf_sdk
|
.sbf_sdk
|
||||||
.join("dependencies")
|
.join("dependencies")
|
||||||
.join("bpf-tools")
|
.join("sbf-tools")
|
||||||
.join("rust");
|
.join("rust");
|
||||||
let rustup = PathBuf::from("rustup");
|
let rustup = PathBuf::from("rustup");
|
||||||
let rustup_args = vec!["toolchain", "list", "-v"];
|
let rustup_args = vec!["toolchain", "list", "-v"];
|
||||||
|
@ -359,23 +360,23 @@ fn link_bpf_toolchain(config: &Config) {
|
||||||
config.generate_child_script_on_failure,
|
config.generate_child_script_on_failure,
|
||||||
);
|
);
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
println!("{}", rustup_output);
|
debug!("{}", rustup_output);
|
||||||
}
|
}
|
||||||
let mut do_link = true;
|
let mut do_link = true;
|
||||||
for line in rustup_output.lines() {
|
for line in rustup_output.lines() {
|
||||||
if line.starts_with("bpf") {
|
if line.starts_with("sbf") {
|
||||||
let mut it = line.split_whitespace();
|
let mut it = line.split_whitespace();
|
||||||
let _ = it.next();
|
let _ = it.next();
|
||||||
let path = it.next();
|
let path = it.next();
|
||||||
if path.unwrap() != toolchain_path.to_str().unwrap() {
|
if path.unwrap() != toolchain_path.to_str().unwrap() {
|
||||||
let rustup_args = vec!["toolchain", "uninstall", "bpf"];
|
let rustup_args = vec!["toolchain", "uninstall", "sbf"];
|
||||||
let output = spawn(
|
let output = spawn(
|
||||||
&rustup,
|
&rustup,
|
||||||
&rustup_args,
|
&rustup_args,
|
||||||
config.generate_child_script_on_failure,
|
config.generate_child_script_on_failure,
|
||||||
);
|
);
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
println!("{}", output);
|
debug!("{}", output);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
do_link = false;
|
do_link = false;
|
||||||
|
@ -384,19 +385,19 @@ fn link_bpf_toolchain(config: &Config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if do_link {
|
if do_link {
|
||||||
let rustup_args = vec!["toolchain", "link", "bpf", toolchain_path.to_str().unwrap()];
|
let rustup_args = vec!["toolchain", "link", "sbf", toolchain_path.to_str().unwrap()];
|
||||||
let output = spawn(
|
let output = spawn(
|
||||||
&rustup,
|
&rustup,
|
||||||
&rustup_args,
|
&rustup_args,
|
||||||
config.generate_child_script_on_failure,
|
config.generate_child_script_on_failure,
|
||||||
);
|
);
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
println!("{}", output);
|
debug!("{}", output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_metadata::Package) {
|
fn build_sbf_package(config: &Config, target_directory: &Path, package: &cargo_metadata::Package) {
|
||||||
let program_name = {
|
let program_name = {
|
||||||
let cdylib_targets = package
|
let cdylib_targets = package
|
||||||
.targets
|
.targets
|
||||||
|
@ -412,7 +413,7 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
|
|
||||||
match cdylib_targets.len() {
|
match cdylib_targets.len() {
|
||||||
0 => {
|
0 => {
|
||||||
println!(
|
warn!(
|
||||||
"Note: {} crate does not contain a cdylib target",
|
"Note: {} crate does not contain a cdylib target",
|
||||||
package.name
|
package.name
|
||||||
);
|
);
|
||||||
|
@ -420,7 +421,7 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
}
|
}
|
||||||
1 => Some(cdylib_targets[0].replace('-', "_")),
|
1 => Some(cdylib_targets[0].replace('-', "_")),
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!(
|
error!(
|
||||||
"{} crate contains multiple cdylib targets: {:?}",
|
"{} crate contains multiple cdylib targets: {:?}",
|
||||||
package.name, cdylib_targets
|
package.name, cdylib_targets
|
||||||
);
|
);
|
||||||
|
@ -431,61 +432,59 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
|
|
||||||
let legacy_program_feature_present = package.name == "solana-sdk";
|
let legacy_program_feature_present = package.name == "solana-sdk";
|
||||||
let root_package_dir = &package.manifest_path.parent().unwrap_or_else(|| {
|
let root_package_dir = &package.manifest_path.parent().unwrap_or_else(|| {
|
||||||
eprintln!("Unable to get directory of {}", package.manifest_path);
|
error!("Unable to get directory of {}", package.manifest_path);
|
||||||
exit(1);
|
exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
let bpf_out_dir = config
|
let sbf_out_dir = config
|
||||||
.bpf_out_dir
|
.sbf_out_dir
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_else(|| target_directory.join("deploy"));
|
.unwrap_or_else(|| target_directory.join("deploy"));
|
||||||
|
|
||||||
let target_build_directory = target_directory
|
let target_build_directory = target_directory.join("sbf-solana-solana").join("release");
|
||||||
.join("bpfel-unknown-unknown")
|
|
||||||
.join("release");
|
|
||||||
|
|
||||||
env::set_current_dir(&root_package_dir).unwrap_or_else(|err| {
|
env::set_current_dir(&root_package_dir).unwrap_or_else(|err| {
|
||||||
eprintln!(
|
error!(
|
||||||
"Unable to set current directory to {}: {}",
|
"Unable to set current directory to {}: {}",
|
||||||
root_package_dir, err
|
root_package_dir, err
|
||||||
);
|
);
|
||||||
exit(1);
|
exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
println!("BPF SDK: {}", config.bpf_sdk.display());
|
info!("SBF SDK: {}", config.sbf_sdk.display());
|
||||||
if config.no_default_features {
|
if config.no_default_features {
|
||||||
println!("No default features");
|
info!("No default features");
|
||||||
}
|
}
|
||||||
if !config.features.is_empty() {
|
if !config.features.is_empty() {
|
||||||
println!("Features: {}", config.features.join(" "));
|
info!("Features: {}", config.features.join(" "));
|
||||||
}
|
}
|
||||||
if legacy_program_feature_present {
|
if legacy_program_feature_present {
|
||||||
println!("Legacy program feature detected");
|
info!("Legacy program feature detected");
|
||||||
}
|
}
|
||||||
let bpf_tools_download_file_name = if cfg!(target_os = "windows") {
|
let sbf_tools_download_file_name = if cfg!(target_os = "windows") {
|
||||||
"solana-bpf-tools-windows.tar.bz2"
|
"solana-sbf-tools-windows.tar.bz2"
|
||||||
} else if cfg!(target_os = "macos") {
|
} else if cfg!(target_os = "macos") {
|
||||||
"solana-bpf-tools-osx.tar.bz2"
|
"solana-sbf-tools-osx.tar.bz2"
|
||||||
} else {
|
} else {
|
||||||
"solana-bpf-tools-linux.tar.bz2"
|
"solana-sbf-tools-linux.tar.bz2"
|
||||||
};
|
};
|
||||||
|
|
||||||
let home_dir = PathBuf::from(env::var("HOME").unwrap_or_else(|err| {
|
let home_dir = PathBuf::from(env::var("HOME").unwrap_or_else(|err| {
|
||||||
eprintln!("Can't get home directory path: {}", err);
|
error!("Can't get home directory path: {}", err);
|
||||||
exit(1);
|
exit(1);
|
||||||
}));
|
}));
|
||||||
let package = "bpf-tools";
|
let package = "sbf-tools";
|
||||||
let target_path = home_dir
|
let target_path = home_dir
|
||||||
.join(".cache")
|
.join(".cache")
|
||||||
.join("solana")
|
.join("solana")
|
||||||
.join(config.bpf_tools_version)
|
.join(config.sbf_tools_version)
|
||||||
.join(package);
|
.join(package);
|
||||||
install_if_missing(
|
install_if_missing(
|
||||||
config,
|
config,
|
||||||
package,
|
package,
|
||||||
"https://github.com/solana-labs/bpf-tools/releases/download",
|
"https://github.com/solana-labs/bpf-tools/releases/download",
|
||||||
bpf_tools_download_file_name,
|
sbf_tools_download_file_name,
|
||||||
&target_path,
|
&target_path,
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
|
@ -493,22 +492,22 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
// installation, and it should be removed.
|
// installation, and it should be removed.
|
||||||
let target_path_parent = target_path.parent().expect("Invalid package path");
|
let target_path_parent = target_path.parent().expect("Invalid package path");
|
||||||
fs::remove_dir_all(&target_path_parent).unwrap_or_else(|err| {
|
fs::remove_dir_all(&target_path_parent).unwrap_or_else(|err| {
|
||||||
eprintln!(
|
error!(
|
||||||
"Failed to remove {} while recovering from installation failure: {}",
|
"Failed to remove {} while recovering from installation failure: {}",
|
||||||
target_path_parent.to_string_lossy(),
|
target_path_parent.to_string_lossy(),
|
||||||
err,
|
err,
|
||||||
);
|
);
|
||||||
exit(1);
|
exit(1);
|
||||||
});
|
});
|
||||||
eprintln!("Failed to install bpf-tools: {}", err);
|
error!("Failed to install sbf-tools: {}", err);
|
||||||
exit(1);
|
exit(1);
|
||||||
});
|
});
|
||||||
link_bpf_toolchain(config);
|
link_sbf_toolchain(config);
|
||||||
|
|
||||||
let llvm_bin = config
|
let llvm_bin = config
|
||||||
.bpf_sdk
|
.sbf_sdk
|
||||||
.join("dependencies")
|
.join("dependencies")
|
||||||
.join("bpf-tools")
|
.join("sbf-tools")
|
||||||
.join("llvm")
|
.join("llvm")
|
||||||
.join("bin");
|
.join("bin");
|
||||||
env::set_var("CC", llvm_bin.join("clang"));
|
env::set_var("CC", llvm_bin.join("clang"));
|
||||||
|
@ -517,7 +516,7 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
env::set_var("OBJCOPY", llvm_bin.join("llvm-objcopy"));
|
env::set_var("OBJCOPY", llvm_bin.join("llvm-objcopy"));
|
||||||
|
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
println!(
|
debug!(
|
||||||
"RUSTFLAGS={}",
|
"RUSTFLAGS={}",
|
||||||
env::var("RUSTFLAGS").ok().as_deref().unwrap_or("")
|
env::var("RUSTFLAGS").ok().as_deref().unwrap_or("")
|
||||||
);
|
);
|
||||||
|
@ -525,10 +524,10 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
|
|
||||||
let cargo_build = PathBuf::from("cargo");
|
let cargo_build = PathBuf::from("cargo");
|
||||||
let mut cargo_build_args = vec![
|
let mut cargo_build_args = vec![
|
||||||
"+bpf",
|
"+sbf",
|
||||||
"build",
|
"build",
|
||||||
"--target",
|
"--target",
|
||||||
"bpfel-unknown-unknown",
|
"sbf-solana-solana",
|
||||||
"--release",
|
"--release",
|
||||||
];
|
];
|
||||||
if config.no_default_features {
|
if config.no_default_features {
|
||||||
|
@ -562,18 +561,18 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
config.generate_child_script_on_failure,
|
config.generate_child_script_on_failure,
|
||||||
);
|
);
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
println!("{}", output);
|
debug!("{}", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(program_name) = program_name {
|
if let Some(program_name) = program_name {
|
||||||
let program_unstripped_so = target_build_directory.join(&format!("{}.so", program_name));
|
let program_unstripped_so = target_build_directory.join(&format!("{}.so", program_name));
|
||||||
let program_dump = bpf_out_dir.join(&format!("{}-dump.txt", program_name));
|
let program_dump = sbf_out_dir.join(&format!("{}-dump.txt", program_name));
|
||||||
let program_so = bpf_out_dir.join(&format!("{}.so", program_name));
|
let program_so = sbf_out_dir.join(&format!("{}.so", program_name));
|
||||||
let program_keypair = bpf_out_dir.join(&format!("{}-keypair.json", program_name));
|
let program_keypair = sbf_out_dir.join(&format!("{}-keypair.json", program_name));
|
||||||
|
|
||||||
fn file_older_or_missing(prerequisite_file: &Path, target_file: &Path) -> bool {
|
fn file_older_or_missing(prerequisite_file: &Path, target_file: &Path) -> bool {
|
||||||
let prerequisite_metadata = fs::metadata(prerequisite_file).unwrap_or_else(|err| {
|
let prerequisite_metadata = fs::metadata(prerequisite_file).unwrap_or_else(|err| {
|
||||||
eprintln!(
|
error!(
|
||||||
"Unable to get file metadata for {}: {}",
|
"Unable to get file metadata for {}: {}",
|
||||||
prerequisite_file.display(),
|
prerequisite_file.display(),
|
||||||
err
|
err
|
||||||
|
@ -592,7 +591,7 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
|
|
||||||
if !program_keypair.exists() {
|
if !program_keypair.exists() {
|
||||||
write_keypair_file(&Keypair::new(), &program_keypair).unwrap_or_else(|err| {
|
write_keypair_file(&Keypair::new(), &program_keypair).unwrap_or_else(|err| {
|
||||||
eprintln!(
|
error!(
|
||||||
"Unable to get create {}: {}",
|
"Unable to get create {}: {}",
|
||||||
program_keypair.display(),
|
program_keypair.display(),
|
||||||
err
|
err
|
||||||
|
@ -614,21 +613,21 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
);
|
);
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let output = spawn(
|
let output = spawn(
|
||||||
&config.bpf_sdk.join("scripts").join("strip.sh"),
|
&config.sbf_sdk.join("scripts").join("strip.sh"),
|
||||||
&[&program_unstripped_so, &program_so],
|
&[&program_unstripped_so, &program_so],
|
||||||
config.generate_child_script_on_failure,
|
config.generate_child_script_on_failure,
|
||||||
);
|
);
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
println!("{}", output);
|
debug!("{}", output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.dump && file_older_or_missing(&program_unstripped_so, &program_dump) {
|
if config.dump && file_older_or_missing(&program_unstripped_so, &program_dump) {
|
||||||
let dump_script = config.bpf_sdk.join("scripts").join("dump.sh");
|
let dump_script = config.sbf_sdk.join("scripts").join("dump.sh");
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
eprintln!("Using Bash scripts from within a program is not supported on Windows, skipping `--dump`.");
|
error!("Using Bash scripts from within a program is not supported on Windows, skipping `--dump`.");
|
||||||
eprintln!(
|
error!(
|
||||||
"Please run \"{} {} {}\" from a Bash-supporting shell, then re-run this command to see the processed program dump.",
|
"Please run \"{} {} {}\" from a Bash-supporting shell, then re-run this command to see the processed program dump.",
|
||||||
&dump_script.display(),
|
&dump_script.display(),
|
||||||
&program_unstripped_so.display(),
|
&program_unstripped_so.display(),
|
||||||
|
@ -642,7 +641,7 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
config.generate_child_script_on_failure,
|
config.generate_child_script_on_failure,
|
||||||
);
|
);
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
println!("{}", output);
|
debug!("{}", output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
postprocess_dump(&program_dump);
|
postprocess_dump(&program_dump);
|
||||||
|
@ -650,17 +649,16 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
||||||
|
|
||||||
check_undefined_symbols(config, &program_so);
|
check_undefined_symbols(config, &program_so);
|
||||||
|
|
||||||
println!();
|
info!("To deploy this program:");
|
||||||
println!("To deploy this program:");
|
info!(" $ solana program deploy {}", program_so.display());
|
||||||
println!(" $ solana program deploy {}", program_so.display());
|
info!("The program address will default to this keypair (override with --program-id):");
|
||||||
println!("The program address will default to this keypair (override with --program-id):");
|
info!(" {}", program_keypair.display());
|
||||||
println!(" {}", program_keypair.display());
|
|
||||||
} else if config.dump {
|
} else if config.dump {
|
||||||
println!("Note: --dump is only available for crates with a cdylib target");
|
warn!("Note: --dump is only available for crates with a cdylib target");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_bpf(config: Config, manifest_path: Option<PathBuf>) {
|
fn build_sbf(config: Config, manifest_path: Option<PathBuf>) {
|
||||||
let mut metadata_command = cargo_metadata::MetadataCommand::new();
|
let mut metadata_command = cargo_metadata::MetadataCommand::new();
|
||||||
if let Some(manifest_path) = manifest_path {
|
if let Some(manifest_path) = manifest_path {
|
||||||
metadata_command.manifest_path(manifest_path);
|
metadata_command.manifest_path(manifest_path);
|
||||||
|
@ -670,18 +668,18 @@ fn build_bpf(config: Config, manifest_path: Option<PathBuf>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadata = metadata_command.exec().unwrap_or_else(|err| {
|
let metadata = metadata_command.exec().unwrap_or_else(|err| {
|
||||||
eprintln!("Failed to obtain package metadata: {}", err);
|
error!("Failed to obtain package metadata: {}", err);
|
||||||
exit(1);
|
exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(root_package) = metadata.root_package() {
|
if let Some(root_package) = metadata.root_package() {
|
||||||
if !config.workspace {
|
if !config.workspace {
|
||||||
build_bpf_package(&config, metadata.target_directory.as_ref(), root_package);
|
build_sbf_package(&config, metadata.target_directory.as_ref(), root_package);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let all_bpf_packages = metadata
|
let all_sbf_packages = metadata
|
||||||
.packages
|
.packages
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|package| {
|
.filter(|package| {
|
||||||
|
@ -696,47 +694,47 @@ fn build_bpf(config: Config, manifest_path: Option<PathBuf>) {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for package in all_bpf_packages {
|
for package in all_sbf_packages {
|
||||||
build_bpf_package(&config, metadata.target_directory.as_ref(), package);
|
build_sbf_package(&config, metadata.target_directory.as_ref(), package);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let default_config = Config::default();
|
let default_config = Config::default();
|
||||||
let default_bpf_sdk = format!("{}", default_config.bpf_sdk.display());
|
let default_sbf_sdk = format!("{}", default_config.sbf_sdk.display());
|
||||||
|
|
||||||
let mut args = env::args().collect::<Vec<_>>();
|
let mut args = env::args().collect::<Vec<_>>();
|
||||||
// When run as a cargo subcommand, the first program argument is the subcommand name.
|
// When run as a cargo subcommand, the first program argument is the subcommand name.
|
||||||
// Remove it
|
// Remove it
|
||||||
if let Some(arg1) = args.get(1) {
|
if let Some(arg1) = args.get(1) {
|
||||||
if arg1 == "build-bpf" {
|
if arg1 == "build-sbf" {
|
||||||
args.remove(1);
|
args.remove(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following line is scanned by CI configuration script to
|
// The following line is scanned by CI configuration script to
|
||||||
// separate cargo caches according to the version of sbf-tools.
|
// separate cargo caches according to the version of sbf-tools.
|
||||||
let bpf_tools_version = "v1.27";
|
let sbf_tools_version = "v1.27";
|
||||||
let version = format!("{}\nbpf-tools {}", crate_version!(), bpf_tools_version);
|
let version = format!("{}\nsbf-tools {}", crate_version!(), sbf_tools_version);
|
||||||
let matches = clap::Command::new(crate_name!())
|
let matches = clap::Command::new(crate_name!())
|
||||||
.about(crate_description!())
|
.about(crate_description!())
|
||||||
.version(version.as_str())
|
.version(version.as_str())
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("bpf_out_dir")
|
Arg::new("sbf_out_dir")
|
||||||
.env("BPF_OUT_PATH")
|
.env("SBF_OUT_PATH")
|
||||||
.long("bpf-out-dir")
|
.long("sbf-out-dir")
|
||||||
.value_name("DIRECTORY")
|
.value_name("DIRECTORY")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Place final BPF build artifacts in this directory"),
|
.help("Place final SBF build artifacts in this directory"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("bpf_sdk")
|
Arg::new("sbf_sdk")
|
||||||
.env("BPF_SDK_PATH")
|
.env("SBF_SDK_PATH")
|
||||||
.long("bpf-sdk")
|
.long("sbf-sdk")
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value(&default_bpf_sdk)
|
.default_value(&default_sbf_sdk)
|
||||||
.help("Path to the Solana BPF SDK"),
|
.help("Path to the Solana SBF SDK"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("cargo_args")
|
Arg::new("cargo_args")
|
||||||
|
@ -797,7 +795,7 @@ fn main() {
|
||||||
.long("workspace")
|
.long("workspace")
|
||||||
.takes_value(false)
|
.takes_value(false)
|
||||||
.alias("all")
|
.alias("all")
|
||||||
.help("Build all BPF packages in the workspace"),
|
.help("Build all SBF packages in the workspace"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("jobs")
|
Arg::new("jobs")
|
||||||
|
@ -810,31 +808,31 @@ fn main() {
|
||||||
)
|
)
|
||||||
.get_matches_from(args);
|
.get_matches_from(args);
|
||||||
|
|
||||||
let bpf_sdk: PathBuf = matches.value_of_t_or_exit("bpf_sdk");
|
let sbf_sdk: PathBuf = matches.value_of_t_or_exit("sbf_sdk");
|
||||||
let bpf_out_dir: Option<PathBuf> = matches.value_of_t("bpf_out_dir").ok();
|
let sbf_out_dir: Option<PathBuf> = matches.value_of_t("sbf_out_dir").ok();
|
||||||
|
|
||||||
let config = Config {
|
let config = Config {
|
||||||
cargo_args: matches
|
cargo_args: matches
|
||||||
.values_of("cargo_args")
|
.values_of("cargo_args")
|
||||||
.map(|vals| vals.collect::<Vec<_>>()),
|
.map(|vals| vals.collect::<Vec<_>>()),
|
||||||
bpf_sdk: fs::canonicalize(&bpf_sdk).unwrap_or_else(|err| {
|
sbf_sdk: fs::canonicalize(&sbf_sdk).unwrap_or_else(|err| {
|
||||||
eprintln!(
|
error!(
|
||||||
"BPF SDK path does not exist: {}: {}",
|
"SBF SDK path does not exist: {}: {}",
|
||||||
bpf_sdk.display(),
|
sbf_sdk.display(),
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
exit(1);
|
exit(1);
|
||||||
}),
|
}),
|
||||||
bpf_out_dir: bpf_out_dir.map(|bpf_out_dir| {
|
sbf_out_dir: sbf_out_dir.map(|sbf_out_dir| {
|
||||||
if bpf_out_dir.is_absolute() {
|
if sbf_out_dir.is_absolute() {
|
||||||
bpf_out_dir
|
sbf_out_dir
|
||||||
} else {
|
} else {
|
||||||
env::current_dir()
|
env::current_dir()
|
||||||
.expect("Unable to get current working directory")
|
.expect("Unable to get current working directory")
|
||||||
.join(bpf_out_dir)
|
.join(sbf_out_dir)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
bpf_tools_version,
|
sbf_tools_version,
|
||||||
dump: matches.is_present("dump"),
|
dump: matches.is_present("dump"),
|
||||||
features: matches.values_of_t("features").ok().unwrap_or_default(),
|
features: matches.values_of_t("features").ok().unwrap_or_default(),
|
||||||
generate_child_script_on_failure: matches.is_present("generate_child_script_on_failure"),
|
generate_child_script_on_failure: matches.is_present("generate_child_script_on_failure"),
|
||||||
|
@ -845,5 +843,5 @@ fn main() {
|
||||||
jobs: matches.value_of_t("jobs").ok(),
|
jobs: matches.value_of_t("jobs").ok(),
|
||||||
};
|
};
|
||||||
let manifest_path: Option<PathBuf> = matches.value_of_t("manifest_path").ok();
|
let manifest_path: Option<PathBuf> = matches.value_of_t("manifest_path").ok();
|
||||||
build_bpf(config, manifest_path);
|
build_sbf(config, manifest_path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,15 +20,15 @@ fn run_cargo_build(crate_name: &str, extra_args: &[&str]) -> Output {
|
||||||
.join(crate_name)
|
.join(crate_name)
|
||||||
.join("Cargo.toml");
|
.join("Cargo.toml");
|
||||||
let toml = format!("{}", toml.display());
|
let toml = format!("{}", toml.display());
|
||||||
let mut args = vec!["--bpf-sdk", "../bpf", "--manifest-path", &toml];
|
let mut args = vec!["--sbf-sdk", "../bpf", "--manifest-path", &toml];
|
||||||
for arg in extra_args {
|
for arg in extra_args {
|
||||||
args.push(arg);
|
args.push(arg);
|
||||||
}
|
}
|
||||||
let cargo_build_bpf = root.join("target").join("debug").join("cargo-build-bpf");
|
let cargo_build_sbf = root.join("target").join("debug").join("cargo-build-sbf");
|
||||||
let output = Command::new(cargo_build_bpf)
|
let output = Command::new(cargo_build_sbf)
|
||||||
.args(&args)
|
.args(&args)
|
||||||
.output()
|
.output()
|
||||||
.expect("Error running cargo-build-bpf");
|
.expect("Error running cargo-build-sbf");
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
eprintln!("--- stdout ---");
|
eprintln!("--- stdout ---");
|
||||||
io::stderr().write_all(&output.stdout).unwrap();
|
io::stderr().write_all(&output.stdout).unwrap();
|
||||||
|
@ -51,7 +51,7 @@ fn test_build() {
|
||||||
fn test_dump() {
|
fn test_dump() {
|
||||||
// This test requires rustfilt.
|
// This test requires rustfilt.
|
||||||
assert!(Command::new("cargo")
|
assert!(Command::new("cargo")
|
||||||
.args(&["install", "rustfilt"])
|
.args(&["install", "-f", "rustfilt"])
|
||||||
.status()
|
.status()
|
||||||
.expect("Unable to install rustfilt required for --dump option")
|
.expect("Unable to install rustfilt required for --dump option")
|
||||||
.success());
|
.success());
|
||||||
|
@ -71,7 +71,7 @@ fn test_dump() {
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
fn test_out_dir() {
|
fn test_out_dir() {
|
||||||
let output = run_cargo_build("noop", &["--bpf-out-dir", "tmp_out"]);
|
let output = run_cargo_build("noop", &["--sbf-out-dir", "tmp_out"]);
|
||||||
assert!(output.status.success());
|
assert!(output.status.success());
|
||||||
let cwd = env::current_dir().expect("Unable to get current working directory");
|
let cwd = env::current_dir().expect("Unable to get current working directory");
|
||||||
let dir = cwd.join("tmp_out");
|
let dir = cwd.join("tmp_out");
|
||||||
|
@ -89,7 +89,7 @@ fn test_generate_child_script_on_failre() {
|
||||||
.join("tests")
|
.join("tests")
|
||||||
.join("crates")
|
.join("crates")
|
||||||
.join("fail")
|
.join("fail")
|
||||||
.join("cargo-build-bpf-child-script-cargo.sh");
|
.join("cargo-build-sbf-child-script-cargo.sh");
|
||||||
assert!(scr.exists());
|
assert!(scr.exists());
|
||||||
fs::remove_file(scr).expect("Failed to remove script");
|
fs::remove_file(scr).expect("Failed to remove script");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "fail"
|
name = "fail"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
description = "Solana BPF test program written in Rust"
|
description = "Solana SBF test program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! Example Rust-based BPF noop program
|
//! Example Rust-based SBF noop program
|
||||||
|
|
||||||
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};
|
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "noop"
|
name = "noop"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
description = "Solana BPF test program written in Rust"
|
description = "Solana SBF test program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! Example Rust-based BPF noop program
|
//! Example Rust-based SBF noop program
|
||||||
|
|
||||||
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};
|
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
[package]
|
||||||
|
name = "solana-cargo-test-bpf"
|
||||||
|
version = "1.11.0"
|
||||||
|
description = "Execute all unit and integration tests after building with the Solana SBF SDK"
|
||||||
|
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||||
|
repository = "https://github.com/solana-labs/solana"
|
||||||
|
homepage = "https://solana.com/"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cargo_metadata = "0.14.2"
|
||||||
|
clap = { version = "3.1.5", features = ["cargo"] }
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "cargo-test-bpf"
|
||||||
|
path = "src/main.rs"
|
|
@ -0,0 +1,61 @@
|
||||||
|
use std::{
|
||||||
|
env,
|
||||||
|
path::PathBuf,
|
||||||
|
process::{exit, Command, Stdio},
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Warning: cargo-test-bpf is deprecated. Please, use cargo-test-sbf");
|
||||||
|
let mut args = env::args()
|
||||||
|
.map(|x| {
|
||||||
|
let s = x;
|
||||||
|
s.replace("--bpf", "--sbf")
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if let Ok(cargo_build_bpf) = env::var("CARGO_BUILD_BPF") {
|
||||||
|
let cargo_build_sbf = cargo_build_bpf.replace("build-bpf", "build-sbf");
|
||||||
|
env::set_var("CARGO_BUILD_SBF", cargo_build_sbf);
|
||||||
|
}
|
||||||
|
let program = if let Some(arg0) = args.get(0) {
|
||||||
|
let cargo_test_sbf = arg0.replace("test-bpf", "test-sbf");
|
||||||
|
let cargo_build_sbf = cargo_test_sbf.replace("test-sbf", "build-sbf");
|
||||||
|
env::set_var("CARGO_BUILD_SBF", cargo_build_sbf);
|
||||||
|
args.remove(0);
|
||||||
|
PathBuf::from(cargo_test_sbf)
|
||||||
|
} else {
|
||||||
|
PathBuf::from("cargo-test-sbf")
|
||||||
|
};
|
||||||
|
// When run as a cargo subcommand, the first program argument is the subcommand name.
|
||||||
|
// Remove it
|
||||||
|
if let Some(arg1) = args.get(1) {
|
||||||
|
if arg1 == "test-bpf" {
|
||||||
|
args.remove(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print!("cargo-test-bpf child: {}", program.display());
|
||||||
|
for a in &args {
|
||||||
|
print!(" {}", a);
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
let child = Command::new(&program)
|
||||||
|
.args(&args)
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap_or_else(|err| {
|
||||||
|
eprintln!("Failed to execute {}: {}", program.display(), err);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
let output = child.wait_with_output().expect("failed to wait on child");
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
output
|
||||||
|
.stdout
|
||||||
|
.as_slice()
|
||||||
|
.iter()
|
||||||
|
.map(|&c| c as char)
|
||||||
|
.collect::<String>()
|
||||||
|
);
|
||||||
|
let code = output.status.code().unwrap_or(1);
|
||||||
|
exit(code);
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "solana-cargo-test-bpf"
|
name = "solana-cargo-test-sbf"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
description = "Execute all unit and integration tests after building with the Solana BPF SDK"
|
description = "Execute all unit and integration tests after building with the Solana SBF SDK"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
|
@ -14,5 +14,5 @@ cargo_metadata = "0.14.2"
|
||||||
clap = { version = "3.1.5", features = ["cargo"] }
|
clap = { version = "3.1.5", features = ["cargo"] }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "cargo-test-bpf"
|
name = "cargo-test-sbf"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
|
@ -11,10 +11,10 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
bpf_sdk: Option<String>,
|
sbf_sdk: Option<String>,
|
||||||
bpf_out_dir: Option<String>,
|
sbf_out_dir: Option<String>,
|
||||||
cargo: PathBuf,
|
cargo: PathBuf,
|
||||||
cargo_build_bpf: PathBuf,
|
cargo_build_sbf: PathBuf,
|
||||||
extra_cargo_test_args: Vec<String>,
|
extra_cargo_test_args: Vec<String>,
|
||||||
features: Vec<String>,
|
features: Vec<String>,
|
||||||
generate_child_script_on_failure: bool,
|
generate_child_script_on_failure: bool,
|
||||||
|
@ -30,10 +30,10 @@ struct Config {
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
bpf_sdk: None,
|
sbf_sdk: None,
|
||||||
bpf_out_dir: None,
|
sbf_out_dir: None,
|
||||||
cargo: PathBuf::from("cargo"),
|
cargo: PathBuf::from("cargo"),
|
||||||
cargo_build_bpf: PathBuf::from("cargo-build-bpf"),
|
cargo_build_sbf: PathBuf::from("cargo-build-sbf"),
|
||||||
extra_cargo_test_args: vec![],
|
extra_cargo_test_args: vec![],
|
||||||
features: vec![],
|
features: vec![],
|
||||||
generate_child_script_on_failure: false,
|
generate_child_script_on_failure: false,
|
||||||
|
@ -54,7 +54,7 @@ where
|
||||||
S: AsRef<OsStr>,
|
S: AsRef<OsStr>,
|
||||||
{
|
{
|
||||||
let args = args.into_iter().collect::<Vec<_>>();
|
let args = args.into_iter().collect::<Vec<_>>();
|
||||||
print!("cargo-test-bpf child: {}", program.display());
|
print!("cargo-test-sbf child: {}", program.display());
|
||||||
for arg in args.iter() {
|
for arg in args.iter() {
|
||||||
print!(" {}", arg.as_ref().to_str().unwrap_or("?"));
|
print!(" {}", arg.as_ref().to_str().unwrap_or("?"));
|
||||||
}
|
}
|
||||||
|
@ -73,9 +73,9 @@ where
|
||||||
if !generate_child_script_on_failure {
|
if !generate_child_script_on_failure {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
eprintln!("cargo-test-bpf exited on command execution failure");
|
eprintln!("cargo-test-sbf exited on command execution failure");
|
||||||
let script_name = format!(
|
let script_name = format!(
|
||||||
"cargo-test-bpf-child-script-{}.sh",
|
"cargo-test-sbf-child-script-{}.sh",
|
||||||
program.file_name().unwrap().to_str().unwrap(),
|
program.file_name().unwrap().to_str().unwrap(),
|
||||||
);
|
);
|
||||||
let file = File::create(&script_name).unwrap();
|
let file = File::create(&script_name).unwrap();
|
||||||
|
@ -97,11 +97,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_bpf_package(config: &Config, target_directory: &Path, package: &cargo_metadata::Package) {
|
fn test_sbf_package(config: &Config, target_directory: &Path, package: &cargo_metadata::Package) {
|
||||||
let set_test_bpf_feature = package.features.contains_key("test-bpf");
|
let sbf_out_dir = config
|
||||||
|
.sbf_out_dir
|
||||||
let bpf_out_dir = config
|
|
||||||
.bpf_out_dir
|
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_else(|| format!("{}", target_directory.join("deploy").display()));
|
.unwrap_or_else(|| format!("{}", target_directory.join("deploy").display()));
|
||||||
|
@ -123,22 +121,22 @@ fn test_bpf_package(config: &Config, target_directory: &Path, package: &cargo_me
|
||||||
cargo_args.push(jobs);
|
cargo_args.push(jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut build_bpf_args = cargo_args.clone();
|
let mut build_sbf_args = cargo_args.clone();
|
||||||
if let Some(bpf_sdk) = config.bpf_sdk.as_ref() {
|
if let Some(sbf_sdk) = config.sbf_sdk.as_ref() {
|
||||||
build_bpf_args.push("--bpf-sdk");
|
build_sbf_args.push("--sbf-sdk");
|
||||||
build_bpf_args.push(bpf_sdk);
|
build_sbf_args.push(sbf_sdk);
|
||||||
}
|
}
|
||||||
build_bpf_args.push("--bpf-out-dir");
|
build_sbf_args.push("--sbf-out-dir");
|
||||||
build_bpf_args.push(&bpf_out_dir);
|
build_sbf_args.push(&sbf_out_dir);
|
||||||
|
|
||||||
spawn(
|
spawn(
|
||||||
&config.cargo_build_bpf,
|
&config.cargo_build_sbf,
|
||||||
&build_bpf_args,
|
&build_sbf_args,
|
||||||
config.generate_child_script_on_failure,
|
config.generate_child_script_on_failure,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Pass --bpf-out-dir along to the solana-program-test crate
|
// Pass --sbf-out-dir along to the solana-program-test crate
|
||||||
env::set_var("BPF_OUT_DIR", bpf_out_dir);
|
env::set_var("SBF_OUT_DIR", sbf_out_dir);
|
||||||
|
|
||||||
cargo_args.insert(0, "test");
|
cargo_args.insert(0, "test");
|
||||||
|
|
||||||
|
@ -151,9 +149,13 @@ fn test_bpf_package(config: &Config, target_directory: &Path, package: &cargo_me
|
||||||
cargo_args.push("--no-run");
|
cargo_args.push("--no-run");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the program crate declares the "test-bpf" feature, pass it along to the tests so they can
|
// If the program crate declares the "test-sbf" feature, pass it along to the tests so they can
|
||||||
// distinguish between `cargo test` and `cargo test-bpf`
|
// distinguish between `cargo test` and `cargo test-sbf`
|
||||||
if set_test_bpf_feature {
|
if package.features.contains_key("test-sbf") {
|
||||||
|
cargo_args.push("--features");
|
||||||
|
cargo_args.push("test-sbf");
|
||||||
|
}
|
||||||
|
if package.features.contains_key("test-bpf") {
|
||||||
cargo_args.push("--features");
|
cargo_args.push("--features");
|
||||||
cargo_args.push("test-bpf");
|
cargo_args.push("test-bpf");
|
||||||
}
|
}
|
||||||
|
@ -167,7 +169,7 @@ fn test_bpf_package(config: &Config, target_directory: &Path, package: &cargo_me
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_bpf(config: Config, manifest_path: Option<PathBuf>) {
|
fn test_sbf(config: Config, manifest_path: Option<PathBuf>) {
|
||||||
let mut metadata_command = cargo_metadata::MetadataCommand::new();
|
let mut metadata_command = cargo_metadata::MetadataCommand::new();
|
||||||
if let Some(manifest_path) = manifest_path.as_ref() {
|
if let Some(manifest_path) = manifest_path.as_ref() {
|
||||||
metadata_command.manifest_path(manifest_path);
|
metadata_command.manifest_path(manifest_path);
|
||||||
|
@ -183,12 +185,12 @@ fn test_bpf(config: Config, manifest_path: Option<PathBuf>) {
|
||||||
|
|
||||||
if let Some(root_package) = metadata.root_package() {
|
if let Some(root_package) = metadata.root_package() {
|
||||||
if !config.workspace {
|
if !config.workspace {
|
||||||
test_bpf_package(&config, metadata.target_directory.as_ref(), root_package);
|
test_sbf_package(&config, metadata.target_directory.as_ref(), root_package);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let all_bpf_packages = metadata
|
let all_sbf_packages = metadata
|
||||||
.packages
|
.packages
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|package| {
|
.filter(|package| {
|
||||||
|
@ -203,8 +205,8 @@ fn test_bpf(config: Config, manifest_path: Option<PathBuf>) {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for package in all_bpf_packages {
|
for package in all_sbf_packages {
|
||||||
test_bpf_package(&config, metadata.target_directory.as_ref(), package);
|
test_sbf_package(&config, metadata.target_directory.as_ref(), package);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +215,7 @@ fn main() {
|
||||||
// When run as a cargo subcommand, the first program argument is the subcommand name.
|
// When run as a cargo subcommand, the first program argument is the subcommand name.
|
||||||
// Remove it
|
// Remove it
|
||||||
if let Some(arg1) = args.get(1) {
|
if let Some(arg1) = args.get(1) {
|
||||||
if arg1 == "test-bpf" {
|
if arg1 == "test-sbf" {
|
||||||
args.remove(1);
|
args.remove(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,11 +228,11 @@ fn main() {
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
.trailing_var_arg(true)
|
.trailing_var_arg(true)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("bpf_sdk")
|
Arg::new("sbf_sdk")
|
||||||
.long("bpf-sdk")
|
.long("sbf-sdk")
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Path to the Solana BPF SDK"),
|
.help("Path to the Solana SBF SDK"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("features")
|
Arg::new("features")
|
||||||
|
@ -262,11 +264,11 @@ fn main() {
|
||||||
.help("Path to Cargo.toml"),
|
.help("Path to Cargo.toml"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("bpf_out_dir")
|
Arg::new("sbf_out_dir")
|
||||||
.long("bpf-out-dir")
|
.long("sbf-out-dir")
|
||||||
.value_name("DIRECTORY")
|
.value_name("DIRECTORY")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Place final BPF build artifacts in this directory"),
|
.help("Place final SBF build artifacts in this directory"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("no_run")
|
Arg::new("no_run")
|
||||||
|
@ -298,7 +300,7 @@ fn main() {
|
||||||
.long("workspace")
|
.long("workspace")
|
||||||
.takes_value(false)
|
.takes_value(false)
|
||||||
.alias("all")
|
.alias("all")
|
||||||
.help("Test all BPF packages in the workspace"),
|
.help("Test all SBF packages in the workspace"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("jobs")
|
Arg::new("jobs")
|
||||||
|
@ -320,8 +322,8 @@ fn main() {
|
||||||
.get_matches_from(args);
|
.get_matches_from(args);
|
||||||
|
|
||||||
let mut config = Config {
|
let mut config = Config {
|
||||||
bpf_sdk: matches.value_of_t("bpf_sdk").ok(),
|
sbf_sdk: matches.value_of_t("sbf_sdk").ok(),
|
||||||
bpf_out_dir: matches.value_of_t("bpf_out_dir").ok(),
|
sbf_out_dir: matches.value_of_t("sbf_out_dir").ok(),
|
||||||
extra_cargo_test_args: matches
|
extra_cargo_test_args: matches
|
||||||
.values_of_t("extra_cargo_test_args")
|
.values_of_t("extra_cargo_test_args")
|
||||||
.ok()
|
.ok()
|
||||||
|
@ -338,22 +340,22 @@ fn main() {
|
||||||
..Config::default()
|
..Config::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(cargo_build_bpf) = env::var("CARGO_BUILD_BPF") {
|
if let Ok(cargo_build_sbf) = env::var("CARGO_BUILD_SBF") {
|
||||||
config.cargo_build_bpf = PathBuf::from(cargo_build_bpf);
|
config.cargo_build_sbf = PathBuf::from(cargo_build_sbf);
|
||||||
}
|
}
|
||||||
if let Ok(cargo_build_bpf) = env::var("CARGO") {
|
if let Ok(cargo_build_sbf) = env::var("CARGO") {
|
||||||
config.cargo = PathBuf::from(cargo_build_bpf);
|
config.cargo = PathBuf::from(cargo_build_sbf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clap.rs swallows "--" in the case when the user provides it as the first `extra_cargo_test_args`
|
// clap.rs swallows "--" in the case when the user provides it as the first `extra_cargo_test_args`
|
||||||
//
|
//
|
||||||
// For example, this command-line "cargo-test-bpf -- --nocapture" results in `extra_cargo_test_args` only
|
// For example, this command-line "cargo-test-sbf -- --nocapture" results in `extra_cargo_test_args` only
|
||||||
// containing "--nocapture". This is a problem because `cargo test` will never see the `--`.
|
// containing "--nocapture". This is a problem because `cargo test` will never see the `--`.
|
||||||
//
|
//
|
||||||
// Whereas "cargo-test-bpf testname -- --nocapture" correctly produces a `extra_cargo_test_args`
|
// Whereas "cargo-test-sbf testname -- --nocapture" correctly produces a `extra_cargo_test_args`
|
||||||
// with "testname -- --nocapture".
|
// with "testname -- --nocapture".
|
||||||
//
|
//
|
||||||
// So if the original cargo-test-bpf arguments contain "--" but `extra_cargo_test_args` does
|
// So if the original cargo-test-sbf arguments contain "--" but `extra_cargo_test_args` does
|
||||||
// not, then prepend "--".
|
// not, then prepend "--".
|
||||||
//
|
//
|
||||||
if args_contain_dashash && !config.extra_cargo_test_args.contains(&em_dash) {
|
if args_contain_dashash && !config.extra_cargo_test_args.contains(&em_dash) {
|
||||||
|
@ -361,5 +363,5 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let manifest_path: Option<PathBuf> = matches.value_of_t("manifest_path").ok();
|
let manifest_path: Option<PathBuf> = matches.value_of_t("manifest_path").ok();
|
||||||
test_bpf(config, manifest_path);
|
test_sbf(config, manifest_path);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue