Skip to content

[pyth_oracle] Improve build.rs robustness and expose types. #343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions program/c/makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
OUT_DIR := ./target
# Use the OUT_DIR env variable as the output directory if available, otherwise
# default to ./target
OUT_DIR := $(if $(OUT_DIR),$(OUT_DIR),./target)
SOLANA := $(shell dirname $(shell which cargo-build-bpf))

ifneq ("$(wildcard $(SOLANA)/sdk/bpf/c/bpf.mk)","")
Expand All @@ -9,11 +11,18 @@ else
include $(SOLANA)/sdk/sbf/c/sbf.mk
endif


# Bundle C code compiled to bpf for use by rust
.PHONY: cpyth-bpf
cpyth-bpf:
# Bundle C code compiled to bpf for use by rust
bash -c "ar rcs target/libcpyth-bpf.a target/**/*.o"
bash -c "ar rcs $(OUT_DIR)/libcpyth-bpf.a target/**/*.o"


# 2-Stage Contract Build
#
# 1) Compile C code to system architecture for use by rust's cargo test
# 2) Bundle C code compiled to system architecture for use by rust's cargo test
.PHONY: cpyth-native
cpyth-native:
# Compile C code to system architecture for use by rust's cargo test
gcc -c ./src/oracle/native/upd_aggregate.c -o ./target/cpyth-native.o -fPIC
# Bundle C code compiled to system architecture for use by rust's cargo test
ar rcs target/libcpyth-native.a ./target/cpyth-native.o
gcc -c ./src/oracle/native/upd_aggregate.c -o $(OUT_DIR)/cpyth-native.o -fPIC
ar rcs $(OUT_DIR)/libcpyth-native.a $(OUT_DIR)/cpyth-native.o
1 change: 1 addition & 0 deletions program/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ test-generator = "0.3.1"

[features]
debug = []
library = []

[lib]
crate-type = ["cdylib", "lib"]
28 changes: 27 additions & 1 deletion program/rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,33 @@ use {
};

fn main() {
println!("cargo:rustc-link-search=./program/c/target");
// Cargo exposes ENV variables for feature flags that can be used to determine whether to do a
// self-contained build that compiles the C components automatically.
if std::env::var("CARGO_FEATURE_LIBRARY").is_ok() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any reason not to do this for both build paths? this seems like a great simplification of the current build process.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason, this is the correct way to do it. But I wasn't sure how many things would break and this was a safe small PR to get a review on. I can make it the default and check anywhere that might break / has been relying on relative paths. I just didn't plan to do it in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get this merged and I can make it the default

// OUT_DIR is the path cargo provides to a build directory under `target/` specifically for
// isolated build artifacts. We use this to build the C program and then link against the
// resulting static library. This allows building the program when used as a dependency of
// another crate.
let out_dir = std::env::var("OUT_DIR").unwrap();
let out_dir = PathBuf::from(out_dir);

// We must forward OUT_DIR as an env variable to the make script otherwise it will output
// its artifacts to the wrong place.
std::process::Command::new("make")
.env("VERBOSE", "1")
.env("OUT_DIR", out_dir.display().to_string())
.current_dir("../c")
.args(["cpyth-native"])
.status()
.expect("Failed to build C program");

// Emit instructions for cargo to link against the built static library.
println!("cargo:rustc-link-lib=static=cpyth-native");
println!("cargo:rustc-link-search={}", out_dir.display());
} else {
// Otherwise fall back to the old relative-path C style build we used to have.
println!("cargo:rustc-link-search=./program/c/target");
}

// Generate and write bindings
let bindings = Builder::default()
Expand Down
19 changes: 19 additions & 0 deletions program/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,25 @@ mod tests;
#[cfg(feature = "debug")]
mod log;

// When compiled in `library` mode the on-chain definitions provided by this library are
// exported. This is useful when other libraries wish to directly utilise the exact Solana specific
// on-chain definitions of the Pyth program.
//
// While we have `pyth-sdk-rs` which exposes a more friendly interface, this is still useful when a
// downstream user wants to confirm for example that they can compile against the binary interface
// of this program for their specific solana version.
#[cfg(feature = "library")]
pub use accounts::{
AccountHeader,
MappingAccount,
PermissionAccount,
PriceAccount,
PriceComponent,
PriceEma,
PriceInfo,
ProductAccount,
PythAccount,
};
use {
crate::error::OracleError,
processor::process_instruction,
Expand Down