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