From b04f2a15a04f4af302b54577d9761d3be8e2f85b Mon Sep 17 00:00:00 2001 From: Jon C Date: Fri, 6 Sep 2024 13:10:36 +0200 Subject: [PATCH] helloworld: Add C implementation --- .github/workflows/main.yml | 32 +++++++++++++++++++++++++ README.md | 37 ++++++++++++++++++++++++++-- helloworld/c/Makefile | 49 ++++++++++++++++++++++++++++++++++++++ helloworld/c/src/main.c | 9 +++++++ test-c.sh | 9 +++++++ 5 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 helloworld/c/Makefile create mode 100644 helloworld/c/src/main.c create mode 100755 test-c.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a32c2f6..c0689bc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -70,3 +70,35 @@ jobs: - name: Build and test program run: cd ${{ matrix.program }} && cargo test-sbf + + c-test: + name: Run tests against C implementations + strategy: + matrix: + program: [helloworld] + fail-fast: false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: rust-${{ hashFiles('./Cargo.lock') }} + + - name: Install Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.78.0 + + - name: Install Rust build deps + run: ./install-rust-build-deps.sh + + - name: Install Solana + run: | + ./install-solana.sh + echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH + + - name: Build and test program + run: ./test-c.sh ${{ matrix.program }} diff --git a/README.md b/README.md index e2d71b8..1fa10ee 100644 --- a/README.md +++ b/README.md @@ -60,13 +60,46 @@ cd helloworld/zig ```console cd .. -SBF_OUT_DIR="./zig/zig-out/lib" cargo test" +SBF_OUT_DIR="./zig/zig-out/lib" cargo test ``` * OR use the helper from the root of this repo to build and test ```console -./test-zig helloworld +./test-zig.sh helloworld +``` + +### C + +* Install Solana tools + +```console +./install-solana.sh +``` + +* Go to a program directory + +```console +cd helloworld/c +``` + +* Build a program + +```console +make +``` + +* Test it + +```console +cd .. +SBF_OUT_DIR="./c/out" cargo test +``` + +* OR use the helper from the root of this repo to build and test + +```console +./test-c.sh helloworld ``` ## Current Programs diff --git a/helloworld/c/Makefile b/helloworld/c/Makefile new file mode 100644 index 0000000..5600985 --- /dev/null +++ b/helloworld/c/Makefile @@ -0,0 +1,49 @@ +LOCAL_PATH := /home/$(USER)/.local/share/solana/install/active_release/bin/sdk/sbf/c/ + +.PHONY: all clean + +SRC_DIR ?= ./src +OUT_DIR ?= ./out + +all: $(OUT_DIR)/solana_program_rosetta_helloworld.so + +clean: + rm -rf $(OUT_DIR) + +LLVM_DIR = $(LOCAL_PATH)../dependencies/platform-tools/llvm +LLVM_SYSTEM_INC_DIRS := $(LLVM_DIR)/lib/clang/17/include +STD_INC_DIRS := $(LLVM_DIR)/include +STD_LIB_DIRS := $(LLVM_DIR)/lib + +CC := $(LLVM_DIR)/bin/clang +LLD := $(LLVM_DIR)/bin/ld.lld + +SYSTEM_INC_DIRS := \ + $(LOCAL_PATH)inc \ + $(LLVM_SYSTEM_INC_DIRS) \ + +C_FLAGS := \ + -Werror \ + -O2 \ + -fno-builtin \ + -std=c17 \ + $(addprefix -isystem,$(SYSTEM_INC_DIRS)) \ + $(addprefix -I,$(STD_INC_DIRS)) \ + -target sbf \ + -fPIC + +SBF_LLD_FLAGS := \ + -z notext \ + -shared \ + --Bdynamic \ + $(LOCAL_PATH)sbf.ld \ + --entry entrypoint \ + -L $(STD_LIB_DIRS) \ + -lc \ + +$(OUT_DIR)/main.o: $(SRC_DIR)/main.c + mkdir -p $(OUT_DIR) + $(CC) $(C_FLAGS) -o $(OUT_DIR)/main.o -c $(SRC_DIR)/main.c + +$(OUT_DIR)/solana_program_rosetta_helloworld.so: $(OUT_DIR)/main.o + $(LLD) $(SBF_LLD_FLAGS) -o $(OUT_DIR)/solana_program_rosetta_helloworld.so $(OUT_DIR)/main.o diff --git a/helloworld/c/src/main.c b/helloworld/c/src/main.c new file mode 100644 index 0000000..7584de9 --- /dev/null +++ b/helloworld/c/src/main.c @@ -0,0 +1,9 @@ +/** + * @brief C-based Helloworld BPF program + */ +#include + +extern uint64_t entrypoint(const uint8_t *input) { + sol_log("Hello world!"); + return SUCCESS; +} diff --git a/test-c.sh b/test-c.sh new file mode 100755 index 0000000..35b972d --- /dev/null +++ b/test-c.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +PROGRAM_NAME="$1" +ROOT_DIR="$(cd "$(dirname "$0")"; pwd)" +set -e +PROGRAM_DIR=$ROOT_DIR/$PROGRAM_NAME +cd $PROGRAM_DIR/c +make +SBF_OUT_DIR="$PROGRAM_DIR/c/out" cargo test --manifest-path "$PROGRAM_DIR/Cargo.toml"