diff --git a/programs/bpf/build.rs b/programs/bpf/build.rs index ed7fd9265..4305c170c 100644 --- a/programs/bpf/build.rs +++ b/programs/bpf/build.rs @@ -57,13 +57,6 @@ fn main() { let install_dir = "target/".to_string() + &env::var("PROFILE").unwrap() + &"/bpf".to_string(); - assert!(Command::new("mkdir") - .arg("-p") - .arg(&install_dir) - .status() - .expect("Unable to create BPF install directory") - .success()); - let rust_programs = [ "128bit", "alloc", @@ -93,22 +86,16 @@ fn main() { "cargo:warning=(not a warning) Building Rust-based BPF programs: solana_bpf_rust_{}", program ); - assert!(Command::new("bash") - .current_dir(format!("rust/{}", program)) - .args(&["../../../../cargo-build-bpf"]) + assert!(Command::new("../../cargo-build-bpf") + .args(&[ + "--manifest-path", + &format!("rust/{}/Cargo.toml", program), + "--bpf-out-dir", + &install_dir + ]) .status() .expect("Error calling cargo-build-bpf from build.rs") .success()); - let src = format!( - "rust/{0}/solana_bpf_rust_{0}.so", - program, - ); - assert!(Command::new("mv") - .arg(&src) - .arg(&install_dir) - .status() - .unwrap_or_else(|_| panic!("Failed to cp {} to {}", src, install_dir)) - .success()); } rerun_if_changed(&[], &["rust", "../../sdk", &install_dir], &["/target/"]); diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 00c47c625..920f8dc87 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -54,7 +54,9 @@ fn load_bpf_program( name: &str, ) -> Pubkey { let path = create_bpf_path(name); - let mut file = File::open(path).unwrap(); + let mut file = File::open(&path).unwrap_or_else(|err| { + panic!("Failed to open {}: {}", path.display(), err); + }); let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); load_program(bank_client, payer_keypair, loader_id, elf) diff --git a/sdk/bpf/scripts/dump.sh b/sdk/bpf/scripts/dump.sh index 8990f17c6..b1dc866bf 100755 --- a/sdk/bpf/scripts/dump.sh +++ b/sdk/bpf/scripts/dump.sh @@ -29,6 +29,11 @@ if ! command -v readelf > /dev/null; then exit 1 fi +set -e +out_dir=$(dirname "$dump") +if [[ ! -d $out_dir ]]; then + mkdir -p "$out_dir" +fi dump_mangled=$dump.mangled ( diff --git a/sdk/bpf/scripts/strip.sh b/sdk/bpf/scripts/strip.sh index 6c579ff08..e80459829 100755 --- a/sdk/bpf/scripts/strip.sh +++ b/sdk/bpf/scripts/strip.sh @@ -14,4 +14,10 @@ fi bpf_sdk=$(cd "$(dirname "$0")/.." && pwd) # shellcheck source=sdk/bpf/env.sh source "$bpf_sdk"/env.sh + +set -e +out_dir=$(dirname "$so_stripped") +if [[ ! -d $out_dir ]]; then + mkdir -p "$out_dir" +fi "$bpf_sdk"/dependencies/llvm-native/bin/llvm-objcopy --strip-all "$so" "$so_stripped" diff --git a/sdk/cargo-build-bpf/src/main.rs b/sdk/cargo-build-bpf/src/main.rs index ae040c353..b08d37289 100644 --- a/sdk/cargo-build-bpf/src/main.rs +++ b/sdk/cargo-build-bpf/src/main.rs @@ -12,6 +12,7 @@ use std::{ struct Config { bpf_sdk: PathBuf, + bpf_out_dir: PathBuf, dump: bool, features: Vec, manifest_path: Option, @@ -22,11 +23,12 @@ impl Default for Config { fn default() -> Self { Self { bpf_sdk: env::current_exe() - .expect("Unable to get current directory") + .expect("Unable to get current executable") .parent() .expect("Unable to get parent directory") .to_path_buf() .join("sdk/bpf"), + bpf_out_dir: env::current_dir().expect("Unable to get current directory"), features: vec![], manifest_path: None, no_default_features: false, @@ -165,8 +167,10 @@ fn build_bpf(config: Config) { if let Some(program_name) = program_name { let program_unstripped_so = target_build_directory.join(&format!("{}.so", program_name)); - let program_dump = PathBuf::from(format!("{}-dump.txt", program_name)); - let program_so = PathBuf::from(format!("{}.so", program_name)); + let program_dump = config + .bpf_out_dir + .join(&format!("{}-dump.txt", program_name)); + let program_so = config.bpf_out_dir.join(&format!("{}.so", program_name)); spawn( &config.bpf_sdk.join("scripts/strip.sh"), @@ -185,7 +189,9 @@ fn build_bpf(config: Config) { } fn main() { - let default_bpf_sdk = format!("{}", Config::default().bpf_sdk.display()); + let default_config = Config::default(); + let default_bpf_sdk = format!("{}", default_config.bpf_sdk.display()); + let default_bpf_out_dir = format!("{}", default_config.bpf_out_dir.display()); let mut args = env::args().collect::>(); // When run as a cargo subcommand, the first program argument is the subcommand name. @@ -234,9 +240,18 @@ fn main() { .takes_value(true) .help("Path to Cargo.toml"), ) + .arg( + Arg::with_name("bpf_out_dir") + .long("bpf-out-dir") + .value_name("DIRECTORY") + .takes_value(true) + .default_value(&default_bpf_out_dir) + .help("Place final BPF build artifacts in this directory"), + ) .get_matches_from(args); let bpf_sdk = value_t_or_exit!(matches, "bpf_sdk", PathBuf); + let bpf_out_dir = value_t_or_exit!(matches, "bpf_out_dir", PathBuf); let config = Config { bpf_sdk: fs::canonicalize(&bpf_sdk).unwrap_or_else(|err| { @@ -247,6 +262,13 @@ fn main() { ); exit(1); }), + bpf_out_dir: if bpf_out_dir.is_absolute() { + bpf_out_dir + } else { + env::current_dir() + .expect("Unable to get current working directory") + .join(bpf_out_dir) + }, dump: matches.is_present("dump"), features: values_t!(matches, "features", String) .ok()