From f4d8bdbc0d3a0d8c85d9ca9ee2f9e1d202b0d467 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Thu, 17 Oct 2024 10:13:41 -0400 Subject: [PATCH] Add cross-compilation to CI Updates the README to use cargo target config instead of RUSTFLAGS to avoid setting the linker for ebpf in cargo-in-cargo. --- .github/workflows/ci.yml | 39 ++++++++- README.md | 9 +-- test.sh | 150 ++++++++++++++++++++--------------- {{project-name}}/src/main.rs | 3 +- 4 files changed, 128 insertions(+), 73 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 741e135..0e29f6e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,12 +21,12 @@ concurrency: jobs: build: - runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: + runner: + - ubuntu-latest # x86 rust: - - stable - 1.80.1 program: - kprobe @@ -48,6 +48,15 @@ jobs: - raw_tracepoint - tp_btf - tracepoint + include: + - runner: macos-13 # x86 + rust: 1.80.1 + program: kprobe + - runner: macos-14 # arm64 + rust: 1.80.1 + program: kprobe + + runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v4 @@ -57,6 +66,21 @@ jobs: components: rust-src,rustfmt - uses: dtolnay/rust-toolchain@master + if: runner.os == 'macOS' && runner.arch == 'X64' + with: + toolchain: ${{ matrix.rust }} + targets: x86_64-unknown-linux-musl + components: clippy + + - uses: dtolnay/rust-toolchain@master + if: runner.os == 'macOS' && runner.arch == 'ARM64' + with: + toolchain: ${{ matrix.rust }} + targets: aarch64-unknown-linux-musl + components: clippy + + - uses: dtolnay/rust-toolchain@master + if: runner.os != 'macOS' with: toolchain: ${{ matrix.rust }} components: clippy @@ -65,7 +89,16 @@ jobs: - uses: taiki-e/install-action@v2 with: - tool: bpf-linker,cargo-generate + tool: cargo-generate + + - run: brew install filosottile/musl-cross/musl-cross llvm + if: runner.os == 'macos' + + - run: cargo install bpf-linker --git https://github.com/aya-rs/bpf-linker.git --no-default-features + if: runner.os == 'macos' + + - run: cargo install bpf-linker --git https://github.com/aya-rs/bpf-linker.git + if: runner.os != 'macos' - run: sudo apt update - run: sudo apt install expect diff --git a/README.md b/README.md index cb40246..04946b9 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,10 @@ experience; this compromise necessitates the use of `xtask` to actually build th Cross compilation should work on both Intel and Apple Silicon Macs. -```bash -AYA_BUILD_EBPF=true \ -CC=${ARCH}-linux-musl-gcc \ -RUSTFLAGS="-C linker=${ARCH}-linux-musl-gcc" \ - cargo build --package {{project-name}} --release --target=${ARCH}-unknown-linux-musl +```shell +AYA_BUILD_EBPF=true CC=${ARCH}-linux-musl-gcc cargo build --package {{project-name}} --release \ + --target=${ARCH}-unknown-linux-musl \ + --config=target.${ARCH}-unknown-linux-musl.linker=\"${ARCH}-linux-musl-gcc\" ``` The cross-compiled program `target/${ARCH}-unknown-linux-musl/release/{{project-name}}` can be copied to a Linux server or VM and run there. diff --git a/test.sh b/test.sh index 0d39c59..8dc52a2 100755 --- a/test.sh +++ b/test.sh @@ -3,50 +3,57 @@ set -eux TEMPLATE_DIR=$1 -if [ -z "${TEMPLATE_DIR}" ]; then echo "template dir required"; exit 1; fi +if [ -z "${TEMPLATE_DIR}" ]; then + echo "template dir required" + exit 1 +fi PROG_TYPE=$2 -if [ -z "${PROG_TYPE}" ]; then echo "program type required"; exit 1; fi +if [ -z "${PROG_TYPE}" ]; then + echo "program type required" + exit 1 +fi CRATE_NAME=aya-test-crate case "${PROG_TYPE}" in - "cgroup_sockopt") - ADDITIONAL_ARGS=(-d sockopt_target=getsockopt) - ;; - "classifier"|"cgroup_skb") - ADDITIONAL_ARGS=(-d direction=Ingress) - ;; - "fentry"|"fexit") - ADDITIONAL_ARGS=(-d fn_name=try_to_wake_up) - ;; - "kprobe"|"kretprobe") - ADDITIONAL_ARGS=(-d kprobe=do_unlinkat) - ;; - "lsm") - ADDITIONAL_ARGS=(-d lsm_hook=file_open) - ;; - "raw_tracepoint") - ADDITIONAL_ARGS=(-d tracepoint_name=sys_enter) - ;; - "sk_msg") - ADDITIONAL_ARGS=(-d sock_map=SOCK_MAP) - ;; - "tp_btf") - ADDITIONAL_ARGS=(-d tracepoint_name=net_dev_queue) - ;; - "tracepoint") - ADDITIONAL_ARGS=(-d tracepoint_category=net -d tracepoint_name=net_dev_queue) - ;; - "uprobe"|"uretprobe") - ADDITIONAL_ARGS=(-d uprobe_target=/proc/self/exe -d uprobe_fn_name=main) - ;; - *) - ADDITIONAL_ARGS=() +"cgroup_sockopt") + ADDITIONAL_ARGS=(-d sockopt_target=getsockopt) + ;; +"classifier" | "cgroup_skb") + ADDITIONAL_ARGS=(-d direction=Ingress) + ;; +"fentry" | "fexit") + ADDITIONAL_ARGS=(-d fn_name=try_to_wake_up) + ;; +"kprobe" | "kretprobe") + ADDITIONAL_ARGS=(-d kprobe=do_unlinkat) + ;; +"lsm") + ADDITIONAL_ARGS=(-d lsm_hook=file_open) + ;; +"raw_tracepoint") + ADDITIONAL_ARGS=(-d tracepoint_name=sys_enter) + ;; +"sk_msg") + ADDITIONAL_ARGS=(-d sock_map=SOCK_MAP) + ;; +"tp_btf") + ADDITIONAL_ARGS=(-d tracepoint_name=net_dev_queue) + ;; +"tracepoint") + ADDITIONAL_ARGS=(-d tracepoint_category=net -d tracepoint_name=net_dev_queue) + ;; +"uprobe" | "uretprobe") + ADDITIONAL_ARGS=(-d uprobe_target=/proc/self/exe -d uprobe_fn_name=main) + ;; +*) + ADDITIONAL_ARGS=() + ;; esac TMP_DIR=$(mktemp -d) clean_up() { - # shellcheck disable=SC2317 - rm -rf "${TMP_DIR}" + # shellcheck disable=SC2317 + rm -rf "${TMP_DIR}" } trap clean_up EXIT @@ -54,35 +61,50 @@ pushd "${TMP_DIR}" cargo generate --path "${TEMPLATE_DIR}" -n "${CRATE_NAME}" -d program_type="${PROG_TYPE}" "${ADDITIONAL_ARGS[@]}" pushd "${CRATE_NAME}" -cargo +nightly fmt --all -- --check -cargo build --package "${CRATE_NAME}" -cargo build --package "${CRATE_NAME}" --release -# We cannot run clippy over the whole workspace at once due to feature unification. Since both -# ${CRATE_NAME} and ${CRATE_NAME}-ebpf depend on ${CRATE_NAME}-common and ${CRATE_NAME} activates -# ${CRATE_NAME}-common's aya dependency, we end up trying to compile the panic handler twice: once -# from the bpf program, and again from std via aya. -cargo clippy --exclude "${CRATE_NAME}-ebpf" --all-targets --workspace -- --deny warnings -cargo clippy --package "${CRATE_NAME}-ebpf" --all-targets -- --deny warnings +OS=$(uname) +if [[ "$OS" == "Darwin" ]]; then + ARCH=$(uname -m) + if [[ "$ARCH" == "arm64" ]]; then + ARCH="aarch64" + fi + AYA_BUILD_EBPF=true CC=${ARCH}-linux-musl-gcc cargo build --package "${CRATE_NAME}" --release \ + --target="${ARCH}"-unknown-linux-musl \ + --config=target."${ARCH}"-unknown-linux-musl.linker=\""${ARCH}"-linux-musl-gcc\" -expect << EOF - set timeout 30 ;# Increase timeout if necessary - spawn cargo xtask run - expect { - -re "Waiting for Ctrl-C.*" { - send -- \003 ;# Send Ctrl-C - } - timeout { - puts "Error: Timed out waiting for 'Waiting for Ctrl-C...'" - exit 1 - } - eof { - puts "Error: Process exited prematurely" - exit 1 + echo "You are on macOS" +fi + +if [[ "$OS" == "Linux" ]]; then + cargo +nightly fmt --all -- --check + cargo build --package "${CRATE_NAME}" + cargo build --package "${CRATE_NAME}" --release + # We cannot run clippy over the whole workspace at once due to feature unification. Since both + # ${CRATE_NAME} and ${CRATE_NAME}-ebpf depend on ${CRATE_NAME}-common and ${CRATE_NAME} activates + # ${CRATE_NAME}-common's aya dependency, we end up trying to compile the panic handler twice: once + # from the bpf program, and again from std via aya. + cargo clippy --exclude "${CRATE_NAME}-ebpf" --all-targets --workspace -- --deny warnings + cargo clippy --package "${CRATE_NAME}-ebpf" --all-targets -- --deny warnings + + expect < anyhow::Result<()> { program.attach("{{tracepoint_name}}")?; {%- endcase %} + let ctrl_c = signal::ctrl_c(); println!("Waiting for Ctrl-C..."); - signal::ctrl_c().await?; + ctrl_c.await?; println!("Exiting..."); Ok(())