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. Rewrite test.sh in python.reviewable/pr131/r1
parent
20ce988ecf
commit
dc7c2cbd0d
@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import platform
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from typing import TypedDict
|
||||
|
||||
if platform.system() == "Linux":
|
||||
import asyncio
|
||||
|
||||
|
||||
class SubprocessArgs(TypedDict, total=False):
|
||||
cwd: str
|
||||
env: dict[str, str]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate and build a Rust project using cargo."
|
||||
)
|
||||
parser.add_argument("template_dir", help="Template directory")
|
||||
parser.add_argument("program_type", help="Program type")
|
||||
args = parser.parse_args()
|
||||
|
||||
match args.program_type:
|
||||
case "cgroup_sockopt":
|
||||
additional_args = ["-d", "sockopt_target=getsockopt"]
|
||||
case "classifier", "cgroup_skb":
|
||||
additional_args = ["-d", "direction=Ingress"]
|
||||
case "fentry", "fexit":
|
||||
additional_args = ["-d", "fn_name=try_to_wake_up"]
|
||||
case "kprobe", "kretprobe":
|
||||
additional_args = ["-d", "kprobe=do_unlinkat"]
|
||||
case "lsm":
|
||||
additional_args = ["-d", "lsm_hook=file_open"]
|
||||
case "raw_tracepoint":
|
||||
additional_args = ["-d", "tracepoint_name=sys_enter"]
|
||||
case "sk_msg":
|
||||
additional_args = ["-d", "sock_map=SOCK_MAP"]
|
||||
case "tp_btf":
|
||||
additional_args = ["-d", "tracepoint_name=net_dev_queue"]
|
||||
case "tracepoint":
|
||||
additional_args = [
|
||||
"-d",
|
||||
"tracepoint_category=net",
|
||||
"-d",
|
||||
"tracepoint_name=net_dev_queue",
|
||||
]
|
||||
case "uprobe", "uretprobe":
|
||||
additional_args = [
|
||||
"-d",
|
||||
"uprobe_target=/proc/self/exe",
|
||||
"-d",
|
||||
"uprobe_fn_name=main",
|
||||
]
|
||||
case _:
|
||||
additional_args = []
|
||||
|
||||
CRATE_NAME = "aya-test-crate"
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
cmds: list[tuple[list[str], SubprocessArgs]] = [
|
||||
(
|
||||
[
|
||||
"cargo",
|
||||
"generate",
|
||||
"--path",
|
||||
args.template_dir,
|
||||
"-n",
|
||||
CRATE_NAME,
|
||||
"-d",
|
||||
f"program_type={args.program_type}",
|
||||
]
|
||||
+ additional_args,
|
||||
{"cwd": tmp_dir},
|
||||
),
|
||||
]
|
||||
project_dir = os.path.join(tmp_dir, CRATE_NAME)
|
||||
match platform.system():
|
||||
case "Linux":
|
||||
cmds.extend(
|
||||
(cmd, {"cwd": project_dir})
|
||||
for cmd in (
|
||||
["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",
|
||||
"--exclude",
|
||||
f"{CRATE_NAME}-ebpf",
|
||||
"--all-targets",
|
||||
"--workspace",
|
||||
"--",
|
||||
"--deny",
|
||||
"warnings",
|
||||
],
|
||||
[
|
||||
"cargo",
|
||||
"--package",
|
||||
f"{CRATE_NAME}-ebpf",
|
||||
"--all-targets",
|
||||
"--",
|
||||
"--deny",
|
||||
"warnings",
|
||||
],
|
||||
)
|
||||
)
|
||||
case "Darwin":
|
||||
arch = platform.machine()
|
||||
if arch == "arm64":
|
||||
arch = "aarch64"
|
||||
target = f"{arch}-unknown-linux-musl"
|
||||
cmds.append(
|
||||
(
|
||||
[
|
||||
"cargo",
|
||||
"build",
|
||||
"--package",
|
||||
CRATE_NAME,
|
||||
"--release",
|
||||
"--target",
|
||||
target,
|
||||
"--config",
|
||||
f'target.{target}.linker = "rust-lld"',
|
||||
],
|
||||
{
|
||||
"cwd": project_dir,
|
||||
"env": os.environ
|
||||
| {
|
||||
"AYA_BUILD_EBPF": "true",
|
||||
"CC": f"{arch}-linux-musl-gcc",
|
||||
},
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
for cmd, kwargs in cmds:
|
||||
print(f"Running command: {' '.join(cmd)} with kwargs: {kwargs}")
|
||||
subprocess.check_call(cmd, **kwargs)
|
||||
|
||||
if platform.system() == "Linux":
|
||||
|
||||
async def run():
|
||||
async with asyncio.create_subprocess_exec(
|
||||
"cargo",
|
||||
"xtask",
|
||||
"run",
|
||||
cwd=project_dir,
|
||||
stdin=subprocess.DEVNULL,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
text=True,
|
||||
) as process:
|
||||
async with asyncio.timeout(30):
|
||||
for line in process.stdout:
|
||||
sys.stdout.write(line)
|
||||
if "Waiting for Ctrl-C" in line:
|
||||
process.send_signal(signal.SIGINT)
|
||||
retcode = await process.wait()
|
||||
if retcode != 0:
|
||||
raise subprocess.CalledProcessError(retcode, process.args)
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,88 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eux
|
||||
|
||||
TEMPLATE_DIR=$1
|
||||
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
|
||||
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=()
|
||||
esac
|
||||
|
||||
TMP_DIR=$(mktemp -d)
|
||||
clean_up() {
|
||||
# shellcheck disable=SC2317
|
||||
rm -rf "${TMP_DIR}"
|
||||
}
|
||||
trap clean_up EXIT
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
expect {
|
||||
-re "Exiting.*" { }
|
||||
eof { }
|
||||
}
|
||||
EOF
|
Loading…
Reference in New Issue