From 28f948aa7f38d03e1a2e3160419ac188d10087bd Mon Sep 17 00:00:00 2001 From: Jack May Date: Tue, 21 May 2019 11:22:33 -0700 Subject: [PATCH] Multi rust projects (#4362) --- programs/bpf/build.rs | 7 +++--- programs/bpf/rust/build.sh | 4 ++++ programs/bpf/rust/clean.sh | 4 ++++ programs/bpf/rust/dump.sh | 16 +++++++++++++ programs/bpf/rust/iter/.gitignore | 3 +++ programs/bpf/rust/iter/Cargo.toml | 22 ++++++++++++++++++ programs/bpf/rust/iter/Xargo.toml | 7 ++++++ programs/bpf/rust/iter/src/lib.rs | 23 +++++++++++++++++++ programs/bpf/rust/noop/Xargo.toml | 5 +++- programs/bpf/rust/noop/clean.sh | 5 ---- programs/bpf/rust/noop/dump.sh | 12 ---------- programs/bpf/tests/programs.rs | 22 ++++++++++-------- .../rust/noop => sdk/bpf/rust-utils}/bpf.ld | 0 .../rust/noop => sdk/bpf/rust-utils}/build.sh | 21 +++++++++++++---- sdk/bpf/rust-utils/clean.sh | 16 +++++++++++++ 15 files changed, 132 insertions(+), 35 deletions(-) create mode 100755 programs/bpf/rust/build.sh create mode 100755 programs/bpf/rust/clean.sh create mode 100755 programs/bpf/rust/dump.sh create mode 100644 programs/bpf/rust/iter/.gitignore create mode 100644 programs/bpf/rust/iter/Cargo.toml create mode 100644 programs/bpf/rust/iter/Xargo.toml create mode 100644 programs/bpf/rust/iter/src/lib.rs delete mode 100755 programs/bpf/rust/noop/clean.sh delete mode 100755 programs/bpf/rust/noop/dump.sh rename {programs/bpf/rust/noop => sdk/bpf/rust-utils}/bpf.ld (100%) rename {programs/bpf/rust/noop => sdk/bpf/rust-utils}/build.sh (60%) create mode 100755 sdk/bpf/rust-utils/clean.sh diff --git a/programs/bpf/build.rs b/programs/bpf/build.rs index d6784bac3e..f03928071e 100644 --- a/programs/bpf/build.rs +++ b/programs/bpf/build.rs @@ -67,14 +67,15 @@ fn main() { .expect("Unable to create BPF install directory") .success()); - let rust_programs = ["noop"]; + let rust_programs = ["iter", "noop"]; for program in rust_programs.iter() { println!( - "cargo:warning=(not a warning) Building Rust-based BPF program: solana_bpf_rust_{}", + "cargo:warning=(not a warning) Building Rust-based BPF programs: solana_bpf_rust_{}", program ); assert!(Command::new("./build.sh") - .current_dir(format!("rust/{}", program)) + .current_dir("rust") + .arg(program) .status() .expect(&format!( "Failed to call solana-bpf-rust-{}'s build.sh", diff --git a/programs/bpf/rust/build.sh b/programs/bpf/rust/build.sh new file mode 100755 index 0000000000..cc29ee33ed --- /dev/null +++ b/programs/bpf/rust/build.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +bpf_sdk=../../../sdk/bpf +./"$bpf_sdk"/rust-utils/build.sh "$PWD"/"$1" diff --git a/programs/bpf/rust/clean.sh b/programs/bpf/rust/clean.sh new file mode 100755 index 0000000000..1ac6a7ee42 --- /dev/null +++ b/programs/bpf/rust/clean.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +bpf_sdk=../../../sdk/bpf +./"$bpf_sdk"/rust-utils/clean.sh "$PWD"/"$1" diff --git a/programs/bpf/rust/dump.sh b/programs/bpf/rust/dump.sh new file mode 100755 index 0000000000..031ca256a6 --- /dev/null +++ b/programs/bpf/rust/dump.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +./clean.sh "$1" +./build.sh "$1" + +cd "$1" + +cp ./target/dump.txt ./targetdump-last.txt 2>/dev/null + +set -ex + +ls -la ./target/bpfel-unknown-unknown/release/solana_bpf_rust_"$1".so > ./target/dump_mangled.txt +greadelf -aW ./target/bpfel-unknown-unknown/release/solana_bpf_rust_"$1".so >> ./target/dump_mangled.txt +llvm-objdump -print-imm-hex --source --disassemble ./target/bpfel-unknown-unknown/release/solana_bpf_rust_"$1".so >> ./target/dump_mangled.txt +sed s/://g < ./target/dump_mangled.txt | rustfilt > ./target/dump.txt + diff --git a/programs/bpf/rust/iter/.gitignore b/programs/bpf/rust/iter/.gitignore new file mode 100644 index 0000000000..e13de17f65 --- /dev/null +++ b/programs/bpf/rust/iter/.gitignore @@ -0,0 +1,3 @@ +/target/ + +Cargo.lock diff --git a/programs/bpf/rust/iter/Cargo.toml b/programs/bpf/rust/iter/Cargo.toml new file mode 100644 index 0000000000..087b4d0261 --- /dev/null +++ b/programs/bpf/rust/iter/Cargo.toml @@ -0,0 +1,22 @@ + +# Note: This crate must be built using build.sh + +[package] +name = "solana-bpf-rust-iter" +version = "0.15.0" +description = "Solana BPF iter program written in Rust" +authors = ["Solana Maintainers "] +repository = "https://github.com/solana-labs/solana" +license = "Apache-2.0" +homepage = "https://solana.com/" +edition = "2018" + +[dependencies] +solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust-utils", version = "0.15.0" } + +[workspace] +members = [] + +[lib] +name = "solana_bpf_rust_iter" +crate-type = ["cdylib"] diff --git a/programs/bpf/rust/iter/Xargo.toml b/programs/bpf/rust/iter/Xargo.toml new file mode 100644 index 0000000000..4203d10a3e --- /dev/null +++ b/programs/bpf/rust/iter/Xargo.toml @@ -0,0 +1,7 @@ + + +[dependencies.compiler_builtins] +path = "../../../../sdk/bpf/rust-bpf-sysroot/src/compiler-builtins" + +[target.bpfel-unknown-unknown.dependencies] +alloc = { path = "../../../../sdk/bpf/rust-bpf-sysroot/src/liballoc" } \ No newline at end of file diff --git a/programs/bpf/rust/iter/src/lib.rs b/programs/bpf/rust/iter/src/lib.rs new file mode 100644 index 0000000000..53a1ee936f --- /dev/null +++ b/programs/bpf/rust/iter/src/lib.rs @@ -0,0 +1,23 @@ +//! @brief Example Rust-based BPF program that prints out the parameters passed to it + +#![no_std] + +extern crate solana_sdk_bpf_utils; + +use solana_sdk_bpf_utils::*; + +#[no_mangle] +pub extern "C" fn entrypoint(_input: *mut u8) -> bool { + const ITERS: usize = 100; + let ones = [1_u64; ITERS]; + let mut sum: u64 = 0; + + for v in ones.iter() { + sum += *v; + } + sol_log_64(0xff, 0, 0, 0, sum); + assert_eq!(sum, ITERS as u64); + + sol_log("Success"); + true +} diff --git a/programs/bpf/rust/noop/Xargo.toml b/programs/bpf/rust/noop/Xargo.toml index b5d189bccc..4203d10a3e 100644 --- a/programs/bpf/rust/noop/Xargo.toml +++ b/programs/bpf/rust/noop/Xargo.toml @@ -1,4 +1,7 @@ [dependencies.compiler_builtins] -path = "../../../../sdk/bpf/rust-bpf-sysroot/src/compiler-builtins" \ No newline at end of file +path = "../../../../sdk/bpf/rust-bpf-sysroot/src/compiler-builtins" + +[target.bpfel-unknown-unknown.dependencies] +alloc = { path = "../../../../sdk/bpf/rust-bpf-sysroot/src/liballoc" } \ No newline at end of file diff --git a/programs/bpf/rust/noop/clean.sh b/programs/bpf/rust/noop/clean.sh deleted file mode 100755 index ea95016e3d..0000000000 --- a/programs/bpf/rust/noop/clean.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -cargo clean diff --git a/programs/bpf/rust/noop/dump.sh b/programs/bpf/rust/noop/dump.sh deleted file mode 100755 index f525425920..0000000000 --- a/programs/bpf/rust/noop/dump.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -cp dump.txt dump_last.txt 2>/dev/null - -set -x -set -e - -./clean.sh -./build.sh -ls -la ./target/bpfel-unknown-unknown/release/solana_bpf_rust_noop.so > dump.txt -greadelf -aW ./target/bpfel-unknown-unknown/release/solana_bpf_rust_noop.so | rustfilt >> dump.txt -llvm-objdump -print-imm-hex --source --disassemble ./target/bpfel-unknown-unknown/release/solana_bpf_rust_noop.so >> dump.txt diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index b1af1ba257..85c12fc82f 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -2,7 +2,7 @@ mod bpf { use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; - use solana_runtime::loader_utils::{create_invoke_instruction, load_program}; + use solana_runtime::loader_utils::load_program; use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::native_loader; use std::env; @@ -27,6 +27,7 @@ mod bpf { #[cfg(feature = "bpf_c")] mod bpf_c { use super::*; + use solana_runtime::loader_utils::create_invoke_instruction; use solana_sdk::bpf_loader; use solana_sdk::client::SyncClient; use solana_sdk::signature::KeypairUtil; @@ -93,22 +94,22 @@ mod bpf { } } - // Cannot currently build the Rust BPF program as part - // of the rest of the build due to recursive `cargo build` causing - // a build deadlock. Therefore you must build the Rust programs - // yourself first by calling `make all` in the Rust BPF program's directory #[cfg(feature = "bpf_rust")] mod bpf_rust { use super::*; use solana_sdk::client::SyncClient; - use solana_sdk::signature::KeypairUtil; + use solana_sdk::instruction::{AccountMeta, Instruction}; + use solana_sdk::signature::{Keypair, KeypairUtil}; use std::io::Read; #[test] fn test_program_bpf_rust() { solana_logger::setup(); - let programs = ["solana_bpf_rust_noop"]; + let programs = [ + // Disable due to #4271 "solana_bpf_rust_iter", + "solana_bpf_rust_noop", + ]; for program in programs.iter() { let filename = create_bpf_path(program); println!("Test program: {:?} from {:?}", program, filename); @@ -129,8 +130,11 @@ mod bpf { // Call user program let program_id = load_program(&bank_client, &alice_keypair, &loader_id, elf); - let instruction = - create_invoke_instruction(alice_keypair.pubkey(), program_id, &1u8); + let account_metas = vec![ + AccountMeta::new(alice_keypair.pubkey(), true), + AccountMeta::new(Keypair::new().pubkey(), false), + ]; + let instruction = Instruction::new(program_id, &1u8, account_metas); bank_client .send_instruction(&alice_keypair, instruction) .unwrap(); diff --git a/programs/bpf/rust/noop/bpf.ld b/sdk/bpf/rust-utils/bpf.ld similarity index 100% rename from programs/bpf/rust/noop/bpf.ld rename to sdk/bpf/rust-utils/bpf.ld diff --git a/programs/bpf/rust/noop/build.sh b/sdk/bpf/rust-utils/build.sh similarity index 60% rename from programs/bpf/rust/noop/build.sh rename to sdk/bpf/rust-utils/build.sh index 3220aec38a..a391529188 100755 --- a/programs/bpf/rust/noop/build.sh +++ b/sdk/bpf/rust-utils/build.sh @@ -1,27 +1,38 @@ #!/usr/bin/env bash +if [ "$#" -ne 1 ]; then + echo "Error: Must provide the full path to the project to build" + exit 1 +fi +if [ ! -d "$1" ]; then + echo "Error: Cannot find project: $1" + exit 1 +fi + cd "$(dirname "$0")" +bpf_sdk="$PWD/.." +export XARGO_HOME="$PWD/../../../target/xargo" + +cd "$1" cargo install xargo set -e -bpf_sdk=../../../../sdk/bpf - # Ensure the sdk is installed "$bpf_sdk"/scripts/install.sh export RUSTUP_TOOLCHAIN=bpf -export RUSTFLAGS="$RUSTFLAGS \ +export RUSTFLAGS=" + --emit=llvm-ir \ -C lto=no \ -C opt-level=2 \ - -C link-arg=-Tbpf.ld \ -C link-arg=-z -C link-arg=notext \ + -C link-arg=-T$bpf_sdk/rust-utils/bpf.ld \ -C link-arg=--Bdynamic \ -C link-arg=-shared \ -C link-arg=--entry=entrypoint \ -C linker=$bpf_sdk/llvm-native/bin/ld.lld" -export XARGO_HOME="$PWD/target/xargo" export XARGO_RUST_SRC="$bpf_sdk/rust-bpf-sysroot/src" xargo build --target bpfel-unknown-unknown --release -v diff --git a/sdk/bpf/rust-utils/clean.sh b/sdk/bpf/rust-utils/clean.sh new file mode 100755 index 0000000000..690ba534ea --- /dev/null +++ b/sdk/bpf/rust-utils/clean.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +if [ "$#" -ne 1 ]; then + echo "Error: Must provide the full path to the project to build" + exit 1 +fi +if [ ! -d "$1" ]; then + echo "Error: Cannot find project: $1" + exit 1 +fi + +cd "$1" + +set -ex + +cargo clean