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]]
|
||||
name = "solana-cargo-build-bpf"
|
||||
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 = [
|
||||
"bzip2",
|
||||
"cargo_metadata",
|
||||
"clap 3.1.8",
|
||||
"log",
|
||||
"regex",
|
||||
"serial_test",
|
||||
"solana-download-utils",
|
||||
|
@ -4514,6 +4524,14 @@ dependencies = [
|
|||
"clap 3.1.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-cargo-test-sbf"
|
||||
version = "1.11.0"
|
||||
dependencies = [
|
||||
"cargo_metadata",
|
||||
"clap 3.1.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-clap-utils"
|
||||
version = "1.11.0"
|
||||
|
|
|
@ -66,7 +66,9 @@ members = [
|
|||
"runtime/store-tool",
|
||||
"sdk",
|
||||
"sdk/cargo-build-bpf",
|
||||
"sdk/cargo-build-sbf",
|
||||
"sdk/cargo-test-bpf",
|
||||
"sdk/cargo-test-sbf",
|
||||
"sdk/gen-headers",
|
||||
"send-transaction-service",
|
||||
"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")
|
||||
|
||||
maybe_bpf_sdk="--bpf-sdk $here/sdk/bpf"
|
||||
maybe_sbf_sdk="--sbf-sdk $here/sdk/bpf"
|
||||
for a in "$@"; do
|
||||
if [[ $a = --bpf-sdk ]]; then
|
||||
maybe_bpf_sdk=
|
||||
if [[ $a = --sbf-sdk ]]; then
|
||||
maybe_sbf_sdk=
|
||||
fi
|
||||
done
|
||||
|
||||
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
|
||||
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")
|
||||
|
||||
maybe_bpf_sdk="--bpf-sdk $here/sdk/bpf"
|
||||
maybe_sbf_sdk="--sbf-sdk $here/sdk/bpf"
|
||||
for a in "$@"; do
|
||||
if [[ $a = --bpf-sdk ]]; then
|
||||
maybe_bpf_sdk=
|
||||
if [[ $a = --sbf-sdk ]]; then
|
||||
maybe_sbf_sdk=
|
||||
fi
|
||||
done
|
||||
|
||||
export CARGO_BUILD_BPF="$here"/cargo-build-bpf
|
||||
export CARGO_BUILD_SBF="$here"/cargo-build-sbf
|
||||
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
|
||||
|
||||
cargo_build_bpf_main="${here}/../sdk/cargo-build-bpf/src/main.rs"
|
||||
if [[ -f "${cargo_build_bpf_main}" ]]; then
|
||||
version=$(sed -e 's/^.*bpf_tools_version\s*=\s*"\(v[0-9.]\+\)".*/\1/;t;d' "${cargo_build_bpf_main}")
|
||||
cargo_build_sbf_main="${here}/../sdk/cargo-build-sbf/src/main.rs"
|
||||
if [[ -f "${cargo_build_sbf_main}" ]]; then
|
||||
version=$(sed -e 's/^.*sbf_tools_version\s*=\s*"\(v[0-9.]\+\)".*/\1/;t;d' "${cargo_build_sbf_main}")
|
||||
if [[ ${version} != '' ]]; then
|
||||
SBF_TOOLS_VERSION="${version}"
|
||||
else
|
||||
echo '--- unable to parse SBF_TOOLS_VERSION'
|
||||
fi
|
||||
else
|
||||
echo "--- '${cargo_build_bpf_main}' not present"
|
||||
echo "--- '${cargo_build_sbf_main}' not present"
|
||||
fi
|
||||
|
||||
echo SBF_TOOLS_VERSION="${SBF_TOOLS_VERSION}"
|
||||
|
|
|
@ -78,7 +78,7 @@ test-stable-bpf)
|
|||
|
||||
bpf_dump_archive="bpf-dumps.tar.bz2"
|
||||
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
|
||||
;;
|
||||
test-stable-perf)
|
||||
|
|
|
@ -401,6 +401,8 @@ fn default_shared_object_dirs() -> Vec<PathBuf> {
|
|||
let mut search_path = vec![];
|
||||
if let Ok(bpf_out_dir) = std::env::var("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"));
|
||||
if let Ok(dir) = std::env::current_dir() {
|
||||
|
@ -450,7 +452,8 @@ impl Default for ProgramTest {
|
|||
solana_runtime::system_instruction_processor=trace,\
|
||||
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 {
|
||||
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]
|
||||
name = "solana-cargo-build-bpf"
|
||||
name = "solana-cargo-build-sbf"
|
||||
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>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
|
@ -13,6 +13,7 @@ publish = false
|
|||
bzip2 = "0.4.3"
|
||||
cargo_metadata = "0.14.2"
|
||||
clap = { version = "3.1.5", features = ["cargo", "env"] }
|
||||
log = { version = "0.4.14", features = ["std"] }
|
||||
regex = "1.5.6"
|
||||
solana-download-utils = { path = "../../download-utils", version = "=1.11.0" }
|
||||
solana-sdk = { path = "..", version = "=1.11.0" }
|
||||
|
@ -25,5 +26,5 @@ serial_test = "*"
|
|||
program = []
|
||||
|
||||
[[bin]]
|
||||
name = "cargo-build-bpf"
|
||||
name = "cargo-build-sbf"
|
||||
path = "src/main.rs"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use {
|
||||
bzip2::bufread::BzDecoder,
|
||||
clap::{crate_description, crate_name, crate_version, Arg},
|
||||
log::*,
|
||||
regex::Regex,
|
||||
solana_download_utils::download_file,
|
||||
solana_sdk::signature::{write_keypair_file, Keypair},
|
||||
|
@ -19,9 +20,9 @@ use {
|
|||
|
||||
struct Config<'a> {
|
||||
cargo_args: Option<Vec<&'a str>>,
|
||||
bpf_out_dir: Option<PathBuf>,
|
||||
bpf_sdk: PathBuf,
|
||||
bpf_tools_version: &'a str,
|
||||
sbf_out_dir: Option<PathBuf>,
|
||||
sbf_sdk: PathBuf,
|
||||
sbf_tools_version: &'a str,
|
||||
dump: bool,
|
||||
features: Vec<String>,
|
||||
generate_child_script_on_failure: bool,
|
||||
|
@ -36,15 +37,15 @@ impl Default for Config<'_> {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
cargo_args: None,
|
||||
bpf_sdk: env::current_exe()
|
||||
sbf_sdk: env::current_exe()
|
||||
.expect("Unable to get current executable")
|
||||
.parent()
|
||||
.expect("Unable to get parent directory")
|
||||
.to_path_buf()
|
||||
.join("sdk")
|
||||
.join("bpf"),
|
||||
bpf_out_dir: None,
|
||||
bpf_tools_version: "(unknown)",
|
||||
sbf_out_dir: None,
|
||||
sbf_tools_version: "(unknown)",
|
||||
dump: false,
|
||||
features: vec![],
|
||||
generate_child_script_on_failure: false,
|
||||
|
@ -63,18 +64,18 @@ where
|
|||
S: AsRef<OsStr>,
|
||||
{
|
||||
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() {
|
||||
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)
|
||||
.args(&args)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap_or_else(|err| {
|
||||
eprintln!("Failed to execute {}: {}", program.display(), err);
|
||||
error!("Failed to execute {}: {}", program.display(), err);
|
||||
exit(1);
|
||||
});
|
||||
|
||||
|
@ -83,9 +84,9 @@ where
|
|||
if !generate_child_script_on_failure {
|
||||
exit(1);
|
||||
}
|
||||
eprintln!("cargo-build-bpf exited on command execution failure");
|
||||
error!("cargo-build-sbf exited on command execution failure");
|
||||
let script_name = format!(
|
||||
"cargo-build-bpf-child-script-{}.sh",
|
||||
"cargo-build-sbf-child-script-{}.sh",
|
||||
program.file_name().unwrap().to_str().unwrap(),
|
||||
);
|
||||
let file = File::create(&script_name).unwrap();
|
||||
|
@ -99,7 +100,7 @@ where
|
|||
}
|
||||
writeln!(out).unwrap();
|
||||
out.flush().unwrap();
|
||||
eprintln!(
|
||||
error!(
|
||||
"To rerun the failed command for debugging use {}",
|
||||
script_name,
|
||||
);
|
||||
|
@ -123,7 +124,7 @@ fn install_if_missing(
|
|||
) -> Result<(), String> {
|
||||
// Check whether the target path is an empty directory. This can
|
||||
// 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.
|
||||
if target_path.is_dir()
|
||||
&& target_path
|
||||
|
@ -149,7 +150,7 @@ fn install_if_missing(
|
|||
fs::create_dir_all(&target_path).map_err(|err| err.to_string())?;
|
||||
let mut url = String::from(url);
|
||||
url.push('/');
|
||||
url.push_str(config.bpf_tools_version);
|
||||
url.push_str(config.sbf_tools_version);
|
||||
url.push('/');
|
||||
url.push_str(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())?;
|
||||
}
|
||||
// Make a symbolic link source_path -> target_path in the
|
||||
// sdk/bpf/dependencies directory if no valid link found.
|
||||
let source_base = config.bpf_sdk.join("dependencies");
|
||||
// sdk/sbf/dependencies directory if no valid link found.
|
||||
let source_base = config.sbf_sdk.join("dependencies");
|
||||
if !source_base.exists() {
|
||||
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
|
||||
// not known to the runtime and warn about them if any.
|
||||
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) {
|
||||
Ok(x) => x,
|
||||
_ => 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 +(.+)")
|
||||
.unwrap();
|
||||
let readelf = config
|
||||
.bpf_sdk
|
||||
.sbf_sdk
|
||||
.join("dependencies")
|
||||
.join("bpf-tools")
|
||||
.join("sbf-tools")
|
||||
.join("llvm")
|
||||
.join("bin")
|
||||
.join("llvm-readelf");
|
||||
|
@ -322,7 +323,7 @@ fn check_undefined_symbols(config: &Config, program: &Path) {
|
|||
config.generate_child_script_on_failure,
|
||||
);
|
||||
if config.verbose {
|
||||
println!("{}", output);
|
||||
debug!("{}", output);
|
||||
}
|
||||
let mut unresolved_symbols: Vec<String> = Vec::new();
|
||||
for line in output.lines() {
|
||||
|
@ -336,20 +337,20 @@ fn check_undefined_symbols(config: &Config, program: &Path) {
|
|||
}
|
||||
}
|
||||
if !unresolved_symbols.is_empty() {
|
||||
println!(
|
||||
"Warning: the following functions are undefined and not known syscalls {:?}.",
|
||||
warn!(
|
||||
"The following functions are undefined and not known syscalls {:?}.",
|
||||
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.
|
||||
fn link_bpf_toolchain(config: &Config) {
|
||||
// check whether custom SBF toolchain is linked, and link it if it is not.
|
||||
fn link_sbf_toolchain(config: &Config) {
|
||||
let toolchain_path = config
|
||||
.bpf_sdk
|
||||
.sbf_sdk
|
||||
.join("dependencies")
|
||||
.join("bpf-tools")
|
||||
.join("sbf-tools")
|
||||
.join("rust");
|
||||
let rustup = PathBuf::from("rustup");
|
||||
let rustup_args = vec!["toolchain", "list", "-v"];
|
||||
|
@ -359,23 +360,23 @@ fn link_bpf_toolchain(config: &Config) {
|
|||
config.generate_child_script_on_failure,
|
||||
);
|
||||
if config.verbose {
|
||||
println!("{}", rustup_output);
|
||||
debug!("{}", rustup_output);
|
||||
}
|
||||
let mut do_link = true;
|
||||
for line in rustup_output.lines() {
|
||||
if line.starts_with("bpf") {
|
||||
if line.starts_with("sbf") {
|
||||
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", "bpf"];
|
||||
let rustup_args = vec!["toolchain", "uninstall", "sbf"];
|
||||
let output = spawn(
|
||||
&rustup,
|
||||
&rustup_args,
|
||||
config.generate_child_script_on_failure,
|
||||
);
|
||||
if config.verbose {
|
||||
println!("{}", output);
|
||||
debug!("{}", output);
|
||||
}
|
||||
} else {
|
||||
do_link = false;
|
||||
|
@ -384,19 +385,19 @@ fn link_bpf_toolchain(config: &Config) {
|
|||
}
|
||||
}
|
||||
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(
|
||||
&rustup,
|
||||
&rustup_args,
|
||||
config.generate_child_script_on_failure,
|
||||
);
|
||||
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 cdylib_targets = package
|
||||
.targets
|
||||
|
@ -412,7 +413,7 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
|||
|
||||
match cdylib_targets.len() {
|
||||
0 => {
|
||||
println!(
|
||||
warn!(
|
||||
"Note: {} crate does not contain a cdylib target",
|
||||
package.name
|
||||
);
|
||||
|
@ -420,7 +421,7 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
|||
}
|
||||
1 => Some(cdylib_targets[0].replace('-', "_")),
|
||||
_ => {
|
||||
eprintln!(
|
||||
error!(
|
||||
"{} crate contains multiple 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 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);
|
||||
});
|
||||
|
||||
let bpf_out_dir = config
|
||||
.bpf_out_dir
|
||||
let sbf_out_dir = config
|
||||
.sbf_out_dir
|
||||
.as_ref()
|
||||
.cloned()
|
||||
.unwrap_or_else(|| target_directory.join("deploy"));
|
||||
|
||||
let target_build_directory = target_directory
|
||||
.join("bpfel-unknown-unknown")
|
||||
.join("release");
|
||||
let target_build_directory = target_directory.join("sbf-solana-solana").join("release");
|
||||
|
||||
env::set_current_dir(&root_package_dir).unwrap_or_else(|err| {
|
||||
eprintln!(
|
||||
error!(
|
||||
"Unable to set current directory to {}: {}",
|
||||
root_package_dir, err
|
||||
);
|
||||
exit(1);
|
||||
});
|
||||
|
||||
println!("BPF SDK: {}", config.bpf_sdk.display());
|
||||
info!("SBF SDK: {}", config.sbf_sdk.display());
|
||||
if config.no_default_features {
|
||||
println!("No default features");
|
||||
info!("No default features");
|
||||
}
|
||||
if !config.features.is_empty() {
|
||||
println!("Features: {}", config.features.join(" "));
|
||||
info!("Features: {}", config.features.join(" "));
|
||||
}
|
||||
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") {
|
||||
"solana-bpf-tools-windows.tar.bz2"
|
||||
let sbf_tools_download_file_name = if cfg!(target_os = "windows") {
|
||||
"solana-sbf-tools-windows.tar.bz2"
|
||||
} else if cfg!(target_os = "macos") {
|
||||
"solana-bpf-tools-osx.tar.bz2"
|
||||
"solana-sbf-tools-osx.tar.bz2"
|
||||
} 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| {
|
||||
eprintln!("Can't get home directory path: {}", err);
|
||||
error!("Can't get home directory path: {}", err);
|
||||
exit(1);
|
||||
}));
|
||||
let package = "bpf-tools";
|
||||
let package = "sbf-tools";
|
||||
let target_path = home_dir
|
||||
.join(".cache")
|
||||
.join("solana")
|
||||
.join(config.bpf_tools_version)
|
||||
.join(config.sbf_tools_version)
|
||||
.join(package);
|
||||
install_if_missing(
|
||||
config,
|
||||
package,
|
||||
"https://github.com/solana-labs/bpf-tools/releases/download",
|
||||
bpf_tools_download_file_name,
|
||||
sbf_tools_download_file_name,
|
||||
&target_path,
|
||||
)
|
||||
.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.
|
||||
let target_path_parent = target_path.parent().expect("Invalid package path");
|
||||
fs::remove_dir_all(&target_path_parent).unwrap_or_else(|err| {
|
||||
eprintln!(
|
||||
error!(
|
||||
"Failed to remove {} while recovering from installation failure: {}",
|
||||
target_path_parent.to_string_lossy(),
|
||||
err,
|
||||
);
|
||||
exit(1);
|
||||
});
|
||||
eprintln!("Failed to install bpf-tools: {}", err);
|
||||
error!("Failed to install sbf-tools: {}", err);
|
||||
exit(1);
|
||||
});
|
||||
link_bpf_toolchain(config);
|
||||
link_sbf_toolchain(config);
|
||||
|
||||
let llvm_bin = config
|
||||
.bpf_sdk
|
||||
.sbf_sdk
|
||||
.join("dependencies")
|
||||
.join("bpf-tools")
|
||||
.join("sbf-tools")
|
||||
.join("llvm")
|
||||
.join("bin");
|
||||
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"));
|
||||
|
||||
if config.verbose {
|
||||
println!(
|
||||
debug!(
|
||||
"RUSTFLAGS={}",
|
||||
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 mut cargo_build_args = vec![
|
||||
"+bpf",
|
||||
"+sbf",
|
||||
"build",
|
||||
"--target",
|
||||
"bpfel-unknown-unknown",
|
||||
"sbf-solana-solana",
|
||||
"--release",
|
||||
];
|
||||
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,
|
||||
);
|
||||
if config.verbose {
|
||||
println!("{}", output);
|
||||
debug!("{}", output);
|
||||
}
|
||||
|
||||
if let Some(program_name) = 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_so = bpf_out_dir.join(&format!("{}.so", program_name));
|
||||
let program_keypair = bpf_out_dir.join(&format!("{}-keypair.json", program_name));
|
||||
let program_dump = sbf_out_dir.join(&format!("{}-dump.txt", program_name));
|
||||
let program_so = sbf_out_dir.join(&format!("{}.so", 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 {
|
||||
let prerequisite_metadata = fs::metadata(prerequisite_file).unwrap_or_else(|err| {
|
||||
eprintln!(
|
||||
error!(
|
||||
"Unable to get file metadata for {}: {}",
|
||||
prerequisite_file.display(),
|
||||
err
|
||||
|
@ -592,7 +591,7 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
|||
|
||||
if !program_keypair.exists() {
|
||||
write_keypair_file(&Keypair::new(), &program_keypair).unwrap_or_else(|err| {
|
||||
eprintln!(
|
||||
error!(
|
||||
"Unable to get create {}: {}",
|
||||
program_keypair.display(),
|
||||
err
|
||||
|
@ -614,21 +613,21 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
|
|||
);
|
||||
#[cfg(not(windows))]
|
||||
let output = spawn(
|
||||
&config.bpf_sdk.join("scripts").join("strip.sh"),
|
||||
&config.sbf_sdk.join("scripts").join("strip.sh"),
|
||||
&[&program_unstripped_so, &program_so],
|
||||
config.generate_child_script_on_failure,
|
||||
);
|
||||
if config.verbose {
|
||||
println!("{}", output);
|
||||
debug!("{}", output);
|
||||
}
|
||||
}
|
||||
|
||||
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)]
|
||||
{
|
||||
eprintln!("Using Bash scripts from within a program is not supported on Windows, skipping `--dump`.");
|
||||
eprintln!(
|
||||
error!("Using Bash scripts from within a program is not supported on Windows, skipping `--dump`.");
|
||||
error!(
|
||||
"Please run \"{} {} {}\" from a Bash-supporting shell, then re-run this command to see the processed program dump.",
|
||||
&dump_script.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,
|
||||
);
|
||||
if config.verbose {
|
||||
println!("{}", output);
|
||||
debug!("{}", output);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
println!();
|
||||
println!("To deploy this program:");
|
||||
println!(" $ solana program deploy {}", program_so.display());
|
||||
println!("The program address will default to this keypair (override with --program-id):");
|
||||
println!(" {}", program_keypair.display());
|
||||
info!("To deploy this program:");
|
||||
info!(" $ solana program deploy {}", program_so.display());
|
||||
info!("The program address will default to this keypair (override with --program-id):");
|
||||
info!(" {}", program_keypair.display());
|
||||
} 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();
|
||||
if let Some(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| {
|
||||
eprintln!("Failed to obtain package metadata: {}", err);
|
||||
error!("Failed to obtain package metadata: {}", err);
|
||||
exit(1);
|
||||
});
|
||||
|
||||
if let Some(root_package) = metadata.root_package() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
let all_bpf_packages = metadata
|
||||
let all_sbf_packages = metadata
|
||||
.packages
|
||||
.iter()
|
||||
.filter(|package| {
|
||||
|
@ -696,47 +694,47 @@ fn build_bpf(config: Config, manifest_path: Option<PathBuf>) {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for package in all_bpf_packages {
|
||||
build_bpf_package(&config, metadata.target_directory.as_ref(), package);
|
||||
for package in all_sbf_packages {
|
||||
build_sbf_package(&config, metadata.target_directory.as_ref(), package);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
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<_>>();
|
||||
// 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" {
|
||||
if arg1 == "build-sbf" {
|
||||
args.remove(1);
|
||||
}
|
||||
}
|
||||
|
||||
// The following line is scanned by CI configuration script to
|
||||
// separate cargo caches according to the version of sbf-tools.
|
||||
let bpf_tools_version = "v1.27";
|
||||
let version = format!("{}\nbpf-tools {}", crate_version!(), bpf_tools_version);
|
||||
let sbf_tools_version = "v1.27";
|
||||
let version = format!("{}\nsbf-tools {}", crate_version!(), sbf_tools_version);
|
||||
let matches = clap::Command::new(crate_name!())
|
||||
.about(crate_description!())
|
||||
.version(version.as_str())
|
||||
.arg(
|
||||
Arg::new("bpf_out_dir")
|
||||
.env("BPF_OUT_PATH")
|
||||
.long("bpf-out-dir")
|
||||
Arg::new("sbf_out_dir")
|
||||
.env("SBF_OUT_PATH")
|
||||
.long("sbf-out-dir")
|
||||
.value_name("DIRECTORY")
|
||||
.takes_value(true)
|
||||
.help("Place final BPF build artifacts in this directory"),
|
||||
.help("Place final SBF build artifacts in this directory"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("bpf_sdk")
|
||||
.env("BPF_SDK_PATH")
|
||||
.long("bpf-sdk")
|
||||
Arg::new("sbf_sdk")
|
||||
.env("SBF_SDK_PATH")
|
||||
.long("sbf-sdk")
|
||||
.value_name("PATH")
|
||||
.takes_value(true)
|
||||
.default_value(&default_bpf_sdk)
|
||||
.help("Path to the Solana BPF SDK"),
|
||||
.default_value(&default_sbf_sdk)
|
||||
.help("Path to the Solana SBF SDK"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("cargo_args")
|
||||
|
@ -797,7 +795,7 @@ fn main() {
|
|||
.long("workspace")
|
||||
.takes_value(false)
|
||||
.alias("all")
|
||||
.help("Build all BPF packages in the workspace"),
|
||||
.help("Build all SBF packages in the workspace"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("jobs")
|
||||
|
@ -810,31 +808,31 @@ fn main() {
|
|||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let bpf_sdk: PathBuf = matches.value_of_t_or_exit("bpf_sdk");
|
||||
let bpf_out_dir: Option<PathBuf> = matches.value_of_t("bpf_out_dir").ok();
|
||||
let sbf_sdk: PathBuf = matches.value_of_t_or_exit("sbf_sdk");
|
||||
let sbf_out_dir: Option<PathBuf> = matches.value_of_t("sbf_out_dir").ok();
|
||||
|
||||
let config = Config {
|
||||
cargo_args: matches
|
||||
.values_of("cargo_args")
|
||||
.map(|vals| vals.collect::<Vec<_>>()),
|
||||
bpf_sdk: fs::canonicalize(&bpf_sdk).unwrap_or_else(|err| {
|
||||
eprintln!(
|
||||
"BPF SDK path does not exist: {}: {}",
|
||||
bpf_sdk.display(),
|
||||
sbf_sdk: fs::canonicalize(&sbf_sdk).unwrap_or_else(|err| {
|
||||
error!(
|
||||
"SBF SDK path does not exist: {}: {}",
|
||||
sbf_sdk.display(),
|
||||
err
|
||||
);
|
||||
exit(1);
|
||||
}),
|
||||
bpf_out_dir: bpf_out_dir.map(|bpf_out_dir| {
|
||||
if bpf_out_dir.is_absolute() {
|
||||
bpf_out_dir
|
||||
sbf_out_dir: sbf_out_dir.map(|sbf_out_dir| {
|
||||
if sbf_out_dir.is_absolute() {
|
||||
sbf_out_dir
|
||||
} else {
|
||||
env::current_dir()
|
||||
.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"),
|
||||
features: matches.values_of_t("features").ok().unwrap_or_default(),
|
||||
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(),
|
||||
};
|
||||
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("Cargo.toml");
|
||||
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 {
|
||||
args.push(arg);
|
||||
}
|
||||
let cargo_build_bpf = root.join("target").join("debug").join("cargo-build-bpf");
|
||||
let output = Command::new(cargo_build_bpf)
|
||||
let cargo_build_sbf = root.join("target").join("debug").join("cargo-build-sbf");
|
||||
let output = Command::new(cargo_build_sbf)
|
||||
.args(&args)
|
||||
.output()
|
||||
.expect("Error running cargo-build-bpf");
|
||||
.expect("Error running cargo-build-sbf");
|
||||
if !output.status.success() {
|
||||
eprintln!("--- stdout ---");
|
||||
io::stderr().write_all(&output.stdout).unwrap();
|
||||
|
@ -51,7 +51,7 @@ fn test_build() {
|
|||
fn test_dump() {
|
||||
// This test requires rustfilt.
|
||||
assert!(Command::new("cargo")
|
||||
.args(&["install", "rustfilt"])
|
||||
.args(&["install", "-f", "rustfilt"])
|
||||
.status()
|
||||
.expect("Unable to install rustfilt required for --dump option")
|
||||
.success());
|
||||
|
@ -71,7 +71,7 @@ fn test_dump() {
|
|||
#[test]
|
||||
#[serial]
|
||||
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());
|
||||
let cwd = env::current_dir().expect("Unable to get current working directory");
|
||||
let dir = cwd.join("tmp_out");
|
||||
|
@ -89,7 +89,7 @@ fn test_generate_child_script_on_failre() {
|
|||
.join("tests")
|
||||
.join("crates")
|
||||
.join("fail")
|
||||
.join("cargo-build-bpf-child-script-cargo.sh");
|
||||
.join("cargo-build-sbf-child-script-cargo.sh");
|
||||
assert!(scr.exists());
|
||||
fs::remove_file(scr).expect("Failed to remove script");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "fail"
|
||||
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>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
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};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "noop"
|
||||
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>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
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};
|
||||
|
||||
|
|
|
@ -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]
|
||||
name = "solana-cargo-test-bpf"
|
||||
name = "solana-cargo-test-sbf"
|
||||
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>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
|
@ -14,5 +14,5 @@ cargo_metadata = "0.14.2"
|
|||
clap = { version = "3.1.5", features = ["cargo"] }
|
||||
|
||||
[[bin]]
|
||||
name = "cargo-test-bpf"
|
||||
name = "cargo-test-sbf"
|
||||
path = "src/main.rs"
|
||||
|
|
|
@ -11,10 +11,10 @@ use {
|
|||
};
|
||||
|
||||
struct Config {
|
||||
bpf_sdk: Option<String>,
|
||||
bpf_out_dir: Option<String>,
|
||||
sbf_sdk: Option<String>,
|
||||
sbf_out_dir: Option<String>,
|
||||
cargo: PathBuf,
|
||||
cargo_build_bpf: PathBuf,
|
||||
cargo_build_sbf: PathBuf,
|
||||
extra_cargo_test_args: Vec<String>,
|
||||
features: Vec<String>,
|
||||
generate_child_script_on_failure: bool,
|
||||
|
@ -30,10 +30,10 @@ struct Config {
|
|||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
bpf_sdk: None,
|
||||
bpf_out_dir: None,
|
||||
sbf_sdk: None,
|
||||
sbf_out_dir: None,
|
||||
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![],
|
||||
features: vec![],
|
||||
generate_child_script_on_failure: false,
|
||||
|
@ -54,7 +54,7 @@ where
|
|||
S: AsRef<OsStr>,
|
||||
{
|
||||
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() {
|
||||
print!(" {}", arg.as_ref().to_str().unwrap_or("?"));
|
||||
}
|
||||
|
@ -73,9 +73,9 @@ where
|
|||
if !generate_child_script_on_failure {
|
||||
exit(1);
|
||||
}
|
||||
eprintln!("cargo-test-bpf exited on command execution failure");
|
||||
eprintln!("cargo-test-sbf exited on command execution failure");
|
||||
let script_name = format!(
|
||||
"cargo-test-bpf-child-script-{}.sh",
|
||||
"cargo-test-sbf-child-script-{}.sh",
|
||||
program.file_name().unwrap().to_str().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) {
|
||||
let set_test_bpf_feature = package.features.contains_key("test-bpf");
|
||||
|
||||
let bpf_out_dir = config
|
||||
.bpf_out_dir
|
||||
fn test_sbf_package(config: &Config, target_directory: &Path, package: &cargo_metadata::Package) {
|
||||
let sbf_out_dir = config
|
||||
.sbf_out_dir
|
||||
.as_ref()
|
||||
.cloned()
|
||||
.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);
|
||||
}
|
||||
|
||||
let mut build_bpf_args = cargo_args.clone();
|
||||
if let Some(bpf_sdk) = config.bpf_sdk.as_ref() {
|
||||
build_bpf_args.push("--bpf-sdk");
|
||||
build_bpf_args.push(bpf_sdk);
|
||||
let mut build_sbf_args = cargo_args.clone();
|
||||
if let Some(sbf_sdk) = config.sbf_sdk.as_ref() {
|
||||
build_sbf_args.push("--sbf-sdk");
|
||||
build_sbf_args.push(sbf_sdk);
|
||||
}
|
||||
build_bpf_args.push("--bpf-out-dir");
|
||||
build_bpf_args.push(&bpf_out_dir);
|
||||
build_sbf_args.push("--sbf-out-dir");
|
||||
build_sbf_args.push(&sbf_out_dir);
|
||||
|
||||
spawn(
|
||||
&config.cargo_build_bpf,
|
||||
&build_bpf_args,
|
||||
&config.cargo_build_sbf,
|
||||
&build_sbf_args,
|
||||
config.generate_child_script_on_failure,
|
||||
);
|
||||
|
||||
// Pass --bpf-out-dir along to the solana-program-test crate
|
||||
env::set_var("BPF_OUT_DIR", bpf_out_dir);
|
||||
// Pass --sbf-out-dir along to the solana-program-test crate
|
||||
env::set_var("SBF_OUT_DIR", sbf_out_dir);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
// If the program crate declares the "test-bpf" feature, pass it along to the tests so they can
|
||||
// distinguish between `cargo test` and `cargo test-bpf`
|
||||
if set_test_bpf_feature {
|
||||
// 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-sbf`
|
||||
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("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();
|
||||
if let Some(manifest_path) = manifest_path.as_ref() {
|
||||
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 !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;
|
||||
}
|
||||
}
|
||||
|
||||
let all_bpf_packages = metadata
|
||||
let all_sbf_packages = metadata
|
||||
.packages
|
||||
.iter()
|
||||
.filter(|package| {
|
||||
|
@ -203,8 +205,8 @@ fn test_bpf(config: Config, manifest_path: Option<PathBuf>) {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for package in all_bpf_packages {
|
||||
test_bpf_package(&config, metadata.target_directory.as_ref(), package);
|
||||
for package in all_sbf_packages {
|
||||
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.
|
||||
// Remove it
|
||||
if let Some(arg1) = args.get(1) {
|
||||
if arg1 == "test-bpf" {
|
||||
if arg1 == "test-sbf" {
|
||||
args.remove(1);
|
||||
}
|
||||
}
|
||||
|
@ -226,11 +228,11 @@ fn main() {
|
|||
.version(crate_version!())
|
||||
.trailing_var_arg(true)
|
||||
.arg(
|
||||
Arg::new("bpf_sdk")
|
||||
.long("bpf-sdk")
|
||||
Arg::new("sbf_sdk")
|
||||
.long("sbf-sdk")
|
||||
.value_name("PATH")
|
||||
.takes_value(true)
|
||||
.help("Path to the Solana BPF SDK"),
|
||||
.help("Path to the Solana SBF SDK"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("features")
|
||||
|
@ -262,11 +264,11 @@ fn main() {
|
|||
.help("Path to Cargo.toml"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("bpf_out_dir")
|
||||
.long("bpf-out-dir")
|
||||
Arg::new("sbf_out_dir")
|
||||
.long("sbf-out-dir")
|
||||
.value_name("DIRECTORY")
|
||||
.takes_value(true)
|
||||
.help("Place final BPF build artifacts in this directory"),
|
||||
.help("Place final SBF build artifacts in this directory"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("no_run")
|
||||
|
@ -298,7 +300,7 @@ fn main() {
|
|||
.long("workspace")
|
||||
.takes_value(false)
|
||||
.alias("all")
|
||||
.help("Test all BPF packages in the workspace"),
|
||||
.help("Test all SBF packages in the workspace"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("jobs")
|
||||
|
@ -320,8 +322,8 @@ fn main() {
|
|||
.get_matches_from(args);
|
||||
|
||||
let mut config = Config {
|
||||
bpf_sdk: matches.value_of_t("bpf_sdk").ok(),
|
||||
bpf_out_dir: matches.value_of_t("bpf_out_dir").ok(),
|
||||
sbf_sdk: matches.value_of_t("sbf_sdk").ok(),
|
||||
sbf_out_dir: matches.value_of_t("sbf_out_dir").ok(),
|
||||
extra_cargo_test_args: matches
|
||||
.values_of_t("extra_cargo_test_args")
|
||||
.ok()
|
||||
|
@ -338,22 +340,22 @@ fn main() {
|
|||
..Config::default()
|
||||
};
|
||||
|
||||
if let Ok(cargo_build_bpf) = env::var("CARGO_BUILD_BPF") {
|
||||
config.cargo_build_bpf = PathBuf::from(cargo_build_bpf);
|
||||
if let Ok(cargo_build_sbf) = env::var("CARGO_BUILD_SBF") {
|
||||
config.cargo_build_sbf = PathBuf::from(cargo_build_sbf);
|
||||
}
|
||||
if let Ok(cargo_build_bpf) = env::var("CARGO") {
|
||||
config.cargo = PathBuf::from(cargo_build_bpf);
|
||||
if let Ok(cargo_build_sbf) = env::var("CARGO") {
|
||||
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`
|
||||
//
|
||||
// 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 `--`.
|
||||
//
|
||||
// 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".
|
||||
//
|
||||
// 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 "--".
|
||||
//
|
||||
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();
|
||||
test_bpf(config, manifest_path);
|
||||
test_sbf(config, manifest_path);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue