Update rust example to use BPF enabled infrastructure (#2974)
This commit is contained in:
@ -51,7 +51,9 @@ test-stable-perf)
|
|||||||
_ make -C programs/bpf/c tests
|
_ make -C programs/bpf/c tests
|
||||||
|
|
||||||
# Must be built out of band
|
# Must be built out of band
|
||||||
_ make -C programs/bpf/rust/noop/ all
|
_ pushd programs/bpf/rust/noop
|
||||||
|
./build.sh
|
||||||
|
popd
|
||||||
|
|
||||||
_ cargo test --manifest-path programs/Cargo.toml --no-default-features --features="$PROGRAM_FEATURES"
|
_ cargo test --manifest-path programs/Cargo.toml --no-default-features --features="$PROGRAM_FEATURES"
|
||||||
_ cargo test --manifest-path programs/native/bpf_loader/Cargo.toml --no-default-features --features="$PROGRAM_FEATURES"
|
_ cargo test --manifest-path programs/native/bpf_loader/Cargo.toml --no-default-features --features="$PROGRAM_FEATURES"
|
||||||
|
1
programs/bpf/rust/noop/.gitignore
vendored
1
programs/bpf/rust/noop/.gitignore
vendored
@ -1,4 +1,3 @@
|
|||||||
/out/
|
|
||||||
/target/
|
/target/
|
||||||
|
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
# Note: This crate must be built using the makefile, try `make help` instead of `cargo build`
|
# Note: This crate must be built using build.sh
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-noop"
|
name = "solana-bpf-rust-noop"
|
||||||
@ -11,7 +11,15 @@ license = "Apache-2.0"
|
|||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
heapless = { version = "0.4.0", default-features = false }
|
# byteorder = { version = "1.3.1", default-features = false }
|
||||||
|
# heapless = { version = "0.4.0", default-features = false }
|
||||||
|
# byte = { version = "0.2", default-features = false }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "solana_bpf_rust_noop"
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
|
||||||
|
4
programs/bpf/rust/noop/Xargo.toml
Normal file
4
programs/bpf/rust/noop/Xargo.toml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
[dependencies.compiler_builtins]
|
||||||
|
path = "../../../../sdk/bpf/rust-bpf-sysroot/src/compiler-builtins"
|
25
programs/bpf/rust/noop/build.sh
Executable file
25
programs/bpf/rust/noop/build.sh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cargo install xargo
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Ensure the sdk is installed
|
||||||
|
../../../../sdk/bpf/scripts/install.sh
|
||||||
|
rustup override set bpf
|
||||||
|
|
||||||
|
export RUSTFLAGS="$RUSTFLAGS \
|
||||||
|
-C lto=no \
|
||||||
|
-C opt-level=2 \
|
||||||
|
-C link-arg=-Tbpf.ld \
|
||||||
|
-C link-arg=-z -C link-arg=notext \
|
||||||
|
-C link-arg=--Bdynamic \
|
||||||
|
-C link-arg=-shared \
|
||||||
|
-C link-arg=--entry=entrypoint \
|
||||||
|
-C linker=../../../../sdk/bpf/llvm-native/bin/ld.lld"
|
||||||
|
export XARGO_HOME="$PWD/target/xargo"
|
||||||
|
export XARGO_RUST_SRC="../../../../sdk/bpf/rust-bpf-sysroot/src"
|
||||||
|
# export XARGO_RUST_SRC="../../../../../rust-bpf-sysroot/src"
|
||||||
|
xargo build --target bpfel-unknown-unknown --release -v
|
||||||
|
|
||||||
|
{ { set +x; } 2>/dev/null; echo Success; }
|
5
programs/bpf/rust/noop/clean.sh
Executable file
5
programs/bpf/rust/noop/clean.sh
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
cargo clean
|
12
programs/bpf/rust/noop/dump.sh
Executable file
12
programs/bpf/rust/noop/dump.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/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
|
@ -1,146 +0,0 @@
|
|||||||
LOCAL_PATH := $(dir $(lastword $(MAKEFILE_LIST)))
|
|
||||||
SDK_PATH := $(abspath $(LOCAL_PATH)/../../../../sdk/bpf)
|
|
||||||
INSTALL_SH := $(abspath $(SDK_PATH)/scripts/install.sh)
|
|
||||||
|
|
||||||
all:
|
|
||||||
.PHONY: help all install dump clean
|
|
||||||
|
|
||||||
ifneq ($(V),1)
|
|
||||||
_@ :=@
|
|
||||||
endif
|
|
||||||
|
|
||||||
TARGET_NAME := solana_bpf_rust_noop
|
|
||||||
SRC_DIR ?= ./src
|
|
||||||
OUT_DIR ?= ./out
|
|
||||||
INSTALL_DIR ?= ./out
|
|
||||||
CARGO_OUT_DIR ?=$(LOCAL_PATH)target/release
|
|
||||||
|
|
||||||
ifeq ($(DOCKER),1)
|
|
||||||
$(warning DOCKER=1 is experimential and may not work as advertised)
|
|
||||||
LLVM_DIR = $(SDK_PATH)/llvm-docker
|
|
||||||
LLVM_SYSTEM_INC_DIRS := /usr/local/lib/clang/8.0.0/include
|
|
||||||
else
|
|
||||||
LLVM_DIR = $(SDK_PATH)/llvm-native
|
|
||||||
LLVM_SYSTEM_INC_DIRS := $(LLVM_DIR)/lib/clang/8.0.0/include
|
|
||||||
endif
|
|
||||||
|
|
||||||
CARGO := cargo
|
|
||||||
ifdef LLVM_DIR
|
|
||||||
LLC := $(LLVM_DIR)/bin/llc
|
|
||||||
LLD := $(LLVM_DIR)/bin/ld.lld
|
|
||||||
OBJ_COPY := $(LLVM_DIR)/bin/llvm-objcopy
|
|
||||||
OBJ_DUMP := $(LLVM_DIR)/bin/llvm-objdump
|
|
||||||
endif
|
|
||||||
|
|
||||||
CARGO_FLAGS := \
|
|
||||||
+nightly \
|
|
||||||
-vv rustc \
|
|
||||||
-vv \
|
|
||||||
--release \
|
|
||||||
-- \
|
|
||||||
--emit=llvm-ir \
|
|
||||||
-C panic=abort \
|
|
||||||
|
|
||||||
LLC_FLAGS := \
|
|
||||||
-march=bpf \
|
|
||||||
-filetype=obj \
|
|
||||||
|
|
||||||
LLD_FLAGS := \
|
|
||||||
-z notext \
|
|
||||||
-shared \
|
|
||||||
--Bdynamic \
|
|
||||||
$(LOCAL_PATH)bpf.ld \
|
|
||||||
--entry entrypoint \
|
|
||||||
|
|
||||||
OBJ_COPY_FLAGS := \
|
|
||||||
--remove-section .eh_frame \
|
|
||||||
|
|
||||||
OBJ_DUMP_FLAGS := \
|
|
||||||
-color \
|
|
||||||
-source \
|
|
||||||
-disassemble \
|
|
||||||
|
|
||||||
help:
|
|
||||||
@echo ''
|
|
||||||
@echo 'solana-bpf-rust-noop makefile'
|
|
||||||
@echo ''
|
|
||||||
@echo 'This makefile will build the solana-bpf-rust-noop crate into a BPF shared object'
|
|
||||||
@echo ''
|
|
||||||
@echo 'This makefile is not run as part of the Solana workspace. Doing so'
|
|
||||||
@echo 'would result in a cargo deadlock since this makefile also calls cargo with parameters'
|
|
||||||
@echo 'required to build the BPF program from Rust.'
|
|
||||||
@echo ''
|
|
||||||
@echo 'Note: Rust BPF programs are tested as part of the Solana integration tests when'
|
|
||||||
@echo ' feature "bpf_rust" is enabled. The solana-bpf-rust-noop crate must be built'
|
|
||||||
@echo ' with this makefile first before bulding Solana.'
|
|
||||||
@echo ''
|
|
||||||
@echo ' Here is a sample command that will run this BPF program:'
|
|
||||||
@echo ''
|
|
||||||
@echo ' export RUST_LOG=solana_bpf_loader=info; cargo test --features="bpf_rust" -- --nocapture test_program_bpf_rust'
|
|
||||||
@echo ''
|
|
||||||
@echo 'User settings'
|
|
||||||
@echo ' - The following setting are overridable on the command line, default values shown:'
|
|
||||||
@echo ' - Show commands while building: V=1'
|
|
||||||
@echo ' V=$(V)'
|
|
||||||
@echo ' - Location to place output files:'
|
|
||||||
@echo ' OUT_DIR=$(OUT_DIR)'
|
|
||||||
@echo ' - Location to install the final shared object:'
|
|
||||||
@echo ' INSTALL_DIR=$(INSTALL_DIR)'
|
|
||||||
@echo ' - Location of LLVM:'
|
|
||||||
@echo ' LLVM_DIR=$(LLVM_DIR)'
|
|
||||||
@echo ''
|
|
||||||
@echo 'Usage:'
|
|
||||||
@echo ' - make help - This help message'
|
|
||||||
@echo ' - make all - Build $(OUT_DIR)/$(TARGET_NAME).so'
|
|
||||||
@echo ' - make dump - Dumps the contents of $(OUT_DIR)/$(TARGET_NAME).so to stdout, requires greadelf and rustfilt'
|
|
||||||
@echo ''
|
|
||||||
|
|
||||||
.PHONY: $(INSTALL_SH)
|
|
||||||
$(INSTALL_SH):
|
|
||||||
$(_@)$(INSTALL_SH)
|
|
||||||
|
|
||||||
.PRECIOUS: $(OUT_DIR)/%.ll
|
|
||||||
$(OUT_DIR)/%.ll: $(SRC_DIR)/*
|
|
||||||
@echo "[cargo] $@ ($<)"
|
|
||||||
$(_@)mkdir -p $(OUT_DIR)
|
|
||||||
$(_@)rm -f $(CARGO_OUT_DIR)/deps/$(TARGET_NAME)-*.ll
|
|
||||||
$(_@)export CARGO_INCREMENTAL=0; $(CARGO) $(CARGO_FLAGS)
|
|
||||||
$(_@)cp $(CARGO_OUT_DIR)/deps/$(TARGET_NAME)-*.ll $(OUT_DIR)/$(TARGET_NAME).ll
|
|
||||||
|
|
||||||
.PRECIOUS: $(OUT_DIR)/%.o
|
|
||||||
$(OUT_DIR)/%.o: $(OUT_DIR)/%.ll $(INSTALL_SH)
|
|
||||||
@echo "[llc] $@ ($<)"
|
|
||||||
$(_@)$(LLC) $(LLC_FLAGS) -o $@ $<
|
|
||||||
$(_@)$(OBJ_COPY) $(OBJ_COPY_FLAGS) $@
|
|
||||||
|
|
||||||
.PRECIOUS: $(OUT_DIR)/%.so
|
|
||||||
$(OUT_DIR)/%.so: $(OUT_DIR)/%.o $(INSTALL_SH)
|
|
||||||
@echo "[lld] $@ ($<)"
|
|
||||||
$(_@)$(LLD) $(LLD_FLAGS) -o $@ $<
|
|
||||||
|
|
||||||
-include $(wildcard $(OUT_DIR)/$(TARGET_NAME).d)
|
|
||||||
|
|
||||||
define \n
|
|
||||||
|
|
||||||
|
|
||||||
endef
|
|
||||||
|
|
||||||
all: $(OUT_DIR)/$(TARGET_NAME).so
|
|
||||||
|
|
||||||
# Warning: Do not build as part of install (e.g. install must not depend
|
|
||||||
# on $(TARGET_NAME).so) doing so will deadlock cargo due to recrusive
|
|
||||||
# calls to cargo
|
|
||||||
install:
|
|
||||||
$(_@)mkdir -p $(INSTALL_DIR)
|
|
||||||
$(_@)cp $(OUT_DIR)/$(TARGET_NAME).so $(INSTALL_DIR)
|
|
||||||
|
|
||||||
dump: $(OUT_DIR)/$(TARGET_NAME).so
|
|
||||||
$(_@)greadelf -aW $(OUT_DIR)/$(TARGET_NAME).so | rustfilt
|
|
||||||
$(_@)$(OBJ_DUMP) -disassemble -source $(OUT_DIR)/$(TARGET_NAME).so | rustfilt
|
|
||||||
|
|
||||||
test:
|
|
||||||
cargo test -- --test-threads 1
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(_@)rm -rf $(OUT_DIR)
|
|
||||||
cargo clean
|
|
@ -7,6 +7,17 @@ mod solana_sdk;
|
|||||||
|
|
||||||
use solana_sdk::*;
|
use solana_sdk::*;
|
||||||
|
|
||||||
|
struct SStruct {
|
||||||
|
x: u64,
|
||||||
|
y: u64,
|
||||||
|
z: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn return_sstruct() -> SStruct {
|
||||||
|
SStruct { x: 1, y: 2, z: 3 }
|
||||||
|
}
|
||||||
|
|
||||||
fn process(ka: &mut [SolKeyedAccount], data: &[u8], info: &SolClusterInfo) -> bool {
|
fn process(ka: &mut [SolKeyedAccount], data: &[u8], info: &SolClusterInfo) -> bool {
|
||||||
sol_log("Tick height:");
|
sol_log("Tick height:");
|
||||||
sol_log_64(info.tick_height, 0, 0, 0, 0);
|
sol_log_64(info.tick_height, 0, 0, 0, 0);
|
||||||
@ -18,5 +29,27 @@ fn process(ka: &mut [SolKeyedAccount], data: &[u8], info: &SolClusterInfo) -> bo
|
|||||||
// programs will have specific requirements so they can do their work.
|
// programs will have specific requirements so they can do their work.
|
||||||
sol_log("Account keys and instruction input data:");
|
sol_log("Account keys and instruction input data:");
|
||||||
sol_log_params(ka, data);
|
sol_log_params(ka, data);
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test - use core methods, unwrap
|
||||||
|
|
||||||
|
// valid bytes, in a stack-allocated array
|
||||||
|
let sparkle_heart = [240, 159, 146, 150];
|
||||||
|
|
||||||
|
let result_str = core::str::from_utf8(&sparkle_heart).unwrap();
|
||||||
|
|
||||||
|
sol_log_64(0, 0, 0, 0, result_str.len() as u64);
|
||||||
|
sol_log(result_str);
|
||||||
|
assert_eq!("💖", result_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test - struct return
|
||||||
|
let s = return_sstruct();
|
||||||
|
sol_log_64(0, 0, s.x, s.y, s.z);
|
||||||
|
assert_eq!(s.x + s.y + s.z, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
sol_log("Success");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,80 @@
|
|||||||
//! @brief Solana Rust-based BPF program utility functions and types
|
//! @brief Solana Rust-based BPF program utility functions and types
|
||||||
|
|
||||||
extern crate heapless;
|
// extern crate heapless;
|
||||||
|
|
||||||
use self::heapless::consts::*;
|
// use self::heapless::consts::*;
|
||||||
use self::heapless::String; // fixed capacity `std::Vec` // type level integer used to specify capacity
|
// use self::heapless::String; // fixed capacity `std::Vec` // type level integer used to specify capacity
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use self::tests::process;
|
use self::tests::process;
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
|
use core::panic::PanicInfo;
|
||||||
use core::slice::from_raw_parts;
|
use core::slice::from_raw_parts;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use process;
|
use process;
|
||||||
|
|
||||||
|
// Panic handling
|
||||||
|
extern "C" {
|
||||||
|
pub fn sol_panic_() -> !;
|
||||||
|
}
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(_info: &PanicInfo) -> ! {
|
||||||
|
sol_log("Panic!");
|
||||||
|
// TODO rashes! sol_log(_info.payload().downcast_ref::<&str>().unwrap());
|
||||||
|
if let Some(location) = _info.location() {
|
||||||
|
if !location.file().is_empty() {
|
||||||
|
// TODO location.file() returns empty str, if we get here its been fixed
|
||||||
|
sol_log(location.file());
|
||||||
|
sol_log("location.file() is fixed!!");
|
||||||
|
unsafe {
|
||||||
|
sol_panic_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sol_log_64(0, 0, 0, location.line() as u64, location.column() as u64);
|
||||||
|
} else {
|
||||||
|
sol_log("Panic! but could not get location information");
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
sol_panic_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn sol_log_(message: *const u8);
|
fn sol_log_(message: *const u8);
|
||||||
}
|
}
|
||||||
/// Helper function that prints a string to stdout
|
/// Helper function that prints a string to stdout
|
||||||
|
#[inline(never)] // stack intensive, block inline so everyone does not incur
|
||||||
pub fn sol_log(message: &str) {
|
pub fn sol_log(message: &str) {
|
||||||
let mut c_string: String<U256> = String::new();
|
// TODO This is extremely slow, do something better
|
||||||
if message.len() < 256 {
|
let mut buf: [u8; 128] = [0; 128];
|
||||||
if c_string.push_str(message).is_err() {
|
for (i, b) in message.as_bytes().iter().enumerate() {
|
||||||
c_string
|
if i >= 126 {
|
||||||
.push_str("Attempted to log a malformed string\0")
|
break;
|
||||||
.is_ok();
|
|
||||||
}
|
}
|
||||||
if c_string.push('\0').is_err() {
|
buf[i] = *b;
|
||||||
c_string.push_str("Failed to log string\0").is_ok();
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
c_string
|
|
||||||
.push_str("Attempted to log a string that is too long\0")
|
|
||||||
.is_ok();
|
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
sol_log_(c_string.as_bytes().as_ptr());
|
sol_log_(buf.as_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let mut c_string: String<U256> = String::new();
|
||||||
|
// if message.len() < 256 {
|
||||||
|
// if c_string.push_str(message).is_err() {
|
||||||
|
// c_string
|
||||||
|
// .push_str("Attempted to log a malformed string\0")
|
||||||
|
// .is_ok();
|
||||||
|
// }
|
||||||
|
// if c_string.push('\0').is_err() {
|
||||||
|
// c_string.push_str("Failed to log string\0").is_ok();
|
||||||
|
// };
|
||||||
|
// } else {
|
||||||
|
// c_string
|
||||||
|
// .push_str("Attempted to log a string that is too long\0")
|
||||||
|
// .is_ok();
|
||||||
|
// }
|
||||||
|
// unsafe {
|
||||||
|
// sol_log_(message.as_ptr());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -60,43 +60,50 @@ fn main() {
|
|||||||
|
|
||||||
let bpf_rust = !env::var("CARGO_FEATURE_BPF_RUST").is_err();
|
let bpf_rust = !env::var("CARGO_FEATURE_BPF_RUST").is_err();
|
||||||
if bpf_rust {
|
if bpf_rust {
|
||||||
let install_dir = "INSTALL_DIR=../../../../target/".to_string()
|
let install_dir =
|
||||||
+ &env::var("PROFILE").unwrap()
|
"../../../../target/".to_string() + &env::var("PROFILE").unwrap() + &"/bpf".to_string();
|
||||||
+ &"/bpf".to_string();
|
|
||||||
|
|
||||||
if !Path::new("../../bpf/rust/noop/out/solana_bpf_rust_noop.so").is_file() {
|
if !Path::new(
|
||||||
|
"../../bpf/rust/noop/target/bpfel-unknown-unknown/release/solana_bpf_rust_noop.so",
|
||||||
|
)
|
||||||
|
.is_file()
|
||||||
|
{
|
||||||
// Cannot build Rust BPF programs as part of main build because
|
// Cannot build Rust BPF programs as part of main build because
|
||||||
// to build it requires calling Cargo with different parameters which
|
// to build it requires calling Cargo with different parameters which
|
||||||
// would deadlock due to recursive cargo calls
|
// would deadlock due to recursive cargo calls
|
||||||
panic!(
|
panic!(
|
||||||
"solana_bpf_rust_noop.so not found, you must manually run \
|
"solana_bpf_rust_noop.so not found, you must manually run \
|
||||||
`make all` in programs/bpf/rust/noop to build it"
|
`build.sh` in programs/bpf/rust/noop to build it"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
rerun_if_changed(
|
rerun_if_changed(
|
||||||
&[
|
&[
|
||||||
"../../bpf/rust/noop/bpf.ld",
|
"../../bpf/rust/noop/bpf.ld",
|
||||||
"../../bpf/rust/noop/makefile",
|
"../../bpf/rust/noop/build.sh",
|
||||||
"../../bpf/rust/noop/out/solana_bpf_rust_noop.so",
|
"../../bpf/rust/noop/Cargo.toml",
|
||||||
|
"../../bpf/rust/noop/target/bpfel-unknown-unknown/release/solana_bpf_rust_noop.so",
|
||||||
],
|
],
|
||||||
&[],
|
&["../../bpf/rust/noop/src"],
|
||||||
);
|
);
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"cargo:warning=(not a warning) Installing Rust-based BPF program: solana_bpf_rust_noop"
|
"cargo:warning=(not a warning) Installing Rust-based BPF program: solana_bpf_rust_noop"
|
||||||
);
|
);
|
||||||
let status = Command::new("make")
|
let status = Command::new("mkdir")
|
||||||
.current_dir("../../bpf/rust/noop")
|
.current_dir("../../bpf/rust/noop")
|
||||||
.arg("install")
|
.arg("-p")
|
||||||
.arg("V=1")
|
|
||||||
.arg("OUT_DIR=out")
|
|
||||||
.arg(&install_dir)
|
.arg(&install_dir)
|
||||||
.status()
|
.status()
|
||||||
.expect(
|
.expect("Unable to create BPF install directory");
|
||||||
"solana_bpf_rust_noop.so not found, you must manually run \
|
assert!(status.success());
|
||||||
`make all` in its program directory",
|
|
||||||
);
|
let status = Command::new("cp")
|
||||||
|
.current_dir("../../bpf/rust/noop")
|
||||||
|
.arg("target/bpfel-unknown-unknown/release/solana_bpf_rust_noop.so")
|
||||||
|
.arg(&install_dir)
|
||||||
|
.status()
|
||||||
|
.expect("Failed to copy solana_rust_bpf_noop.so to install directory");
|
||||||
assert!(status.success());
|
assert!(status.success());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user