mirror of
https://github.com/MidnightBlueLabs/tetra-bluestation.git
synced 2026-03-29 05:09:51 +00:00
Initial release for automated binary releases for amd64 and aach64 targets
Automatically builds amd64 and aach64 target through gitlab workflow. Also allows for local cross-compilation through `cross` tool Co-authored-by: Frédéric Druppel <Frederic.druppel@icloud.com>
This commit is contained in:
113
.github/workflows/build.yml
vendored
Normal file
113
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
name: Build release binaries
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- feature/cross_compile
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- target: x86_64-unknown-linux-gnu
|
||||||
|
bin_path: target/x86_64-unknown-linux-gnu/release/tetra-bluestation
|
||||||
|
build_cmd: cargo build --release --target x86_64-unknown-linux-gnu -p bluestation-bs --bin tetra-bluestation
|
||||||
|
artifact_name: tetra-bluestation-x86_64
|
||||||
|
|
||||||
|
- target: aarch64-unknown-linux-gnu
|
||||||
|
bin_path: target/aarch64-unknown-linux-gnu/release/tetra-bluestation
|
||||||
|
build_cmd: cross build --release --target aarch64-unknown-linux-gnu -p bluestation-bs --bin tetra-bluestation
|
||||||
|
artifact_name: tetra-bluestation-aarch64-generic
|
||||||
|
|
||||||
|
- target: aarch64-unknown-linux-gnu
|
||||||
|
bin_path: target/aarch64-unknown-linux-gnu/release/tetra-bluestation
|
||||||
|
build_cmd: cross build --release --target aarch64-unknown-linux-gnu -p bluestation-bs --bin tetra-bluestation
|
||||||
|
artifact_name: tetra-bluestation-rpi4
|
||||||
|
cpu_rustflags: "-C target-cpu=cortex-a72"
|
||||||
|
|
||||||
|
- target: aarch64-unknown-linux-gnu
|
||||||
|
bin_path: target/aarch64-unknown-linux-gnu/release/tetra-bluestation
|
||||||
|
build_cmd: cross build --release --target aarch64-unknown-linux-gnu -p bluestation-bs --bin tetra-bluestation
|
||||||
|
artifact_name: tetra-bluestation-rpi5
|
||||||
|
cpu_rustflags: "-C target-cpu=cortex-a76"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4.2.2
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
|
with:
|
||||||
|
target: ${{ matrix.target }}
|
||||||
|
|
||||||
|
- name: Install cross
|
||||||
|
if: matrix.target == 'aarch64-unknown-linux-gnu'
|
||||||
|
run: cargo install cross --locked
|
||||||
|
|
||||||
|
- name: Apply CPU-specific RUSTFLAGS
|
||||||
|
if: matrix.cpu_rustflags != ''
|
||||||
|
run: echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS=${{ matrix.cpu_rustflags }}" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- name: Install native build dependencies (amd64)
|
||||||
|
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --no-install-recommends \
|
||||||
|
git make g++ cmake pkg-config \
|
||||||
|
libsoapysdr-dev \
|
||||||
|
soapysdr-tools \
|
||||||
|
libasound2-dev \
|
||||||
|
clang llvm-dev libclang-dev
|
||||||
|
|
||||||
|
echo "PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig" >> "$GITHUB_ENV"
|
||||||
|
pkg-config --modversion SoapySDR
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: ${{ matrix.build_cmd }}
|
||||||
|
|
||||||
|
- name: Rename binary
|
||||||
|
run: cp ${{ matrix.bin_path }} ${{ matrix.artifact_name }}
|
||||||
|
|
||||||
|
- name: Upload binary
|
||||||
|
uses: actions/upload-artifact@v4.6.0
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.artifact_name }}
|
||||||
|
path: ${{ matrix.artifact_name }}
|
||||||
|
|
||||||
|
release:
|
||||||
|
name: Publish latest release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4.2.2
|
||||||
|
|
||||||
|
- name: Read version from Cargo.toml
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
VERSION=$(grep '^version' Cargo.toml | head -1 | cut -d'"' -f2)
|
||||||
|
SHORT_SHA=$(git rev-parse --short HEAD)
|
||||||
|
echo "tag=v$VERSION-$SHORT_SHA" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "name=v$VERSION-$SHORT_SHA" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Download all binaries
|
||||||
|
uses: actions/download-artifact@v4.2.1
|
||||||
|
with:
|
||||||
|
path: artifacts
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Publish release
|
||||||
|
uses: softprops/action-gh-release@v2.3.2
|
||||||
|
with:
|
||||||
|
tag_name: ${{ steps.version.outputs.tag }}
|
||||||
|
name: ${{ steps.version.outputs.name }}
|
||||||
|
files: artifacts/*
|
||||||
2
Cross.toml
Normal file
2
Cross.toml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[target.aarch64-unknown-linux-gnu]
|
||||||
|
dockerfile = "contrib/cross-compile/Dockerfile.aarch64"
|
||||||
18
contrib/cross-compile/Dockerfile.aarch64
Normal file
18
contrib/cross-compile/Dockerfile.aarch64
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
FROM ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main
|
||||||
|
|
||||||
|
RUN dpkg --add-architecture arm64 && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
cmake git g++ && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN git clone https://github.com/pothosware/SoapySDR.git --branch soapy-sdr-0.8.1 && \
|
||||||
|
cd SoapySDR && \
|
||||||
|
mkdir build && cd build && \
|
||||||
|
cmake .. \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||||
|
-DCMAKE_INSTALL_LIBDIR=lib/aarch64-linux-gnu \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=/opt/toolchain.cmake && \
|
||||||
|
make -j"$(nproc)" && \
|
||||||
|
make install && \
|
||||||
|
cd / && rm -rf SoapySDR
|
||||||
194
contrib/cross-compile/setup_cross_compile.sh
Executable file
194
contrib/cross-compile/setup_cross_compile.sh
Executable file
@@ -0,0 +1,194 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# setup_cross_compile.sh
|
||||||
|
#
|
||||||
|
# Installs:
|
||||||
|
# - Docker Engine / docker.io
|
||||||
|
# - docker group membership for the invoking user
|
||||||
|
# - Rust `cross`
|
||||||
|
# - Adds cargo bin directory to $PATH
|
||||||
|
#
|
||||||
|
# Assumptions:
|
||||||
|
# - Rust + cargo + rustup are already installed
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./setup_cross_compile.sh
|
||||||
|
#
|
||||||
|
# Notes:
|
||||||
|
# - Must not be run as root.
|
||||||
|
# - Group membership changes require a new login session.
|
||||||
|
# - Path change needs new shell.
|
||||||
|
|
||||||
|
require_cmd() {
|
||||||
|
if ! command -v "$1" >/dev/null 2>&1; then
|
||||||
|
echo "[-] error: required command not found: $1" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_not_root() {
|
||||||
|
if [[ "${EUID}" -eq 0 ]]; then
|
||||||
|
echo "[-] error: do not run this script as root" >&2
|
||||||
|
echo " Run it as your normal user. The script will use sudo when needed." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
confirm_plan() {
|
||||||
|
cat <<'EOF'
|
||||||
|
[i] This script will perform the following actions:
|
||||||
|
|
||||||
|
1. Install Docker via apt if it is not already installed.
|
||||||
|
2. Enable and start the Docker service.
|
||||||
|
3. Add your user to the docker group if needed.
|
||||||
|
4. Install the Rust `cross` tool if it is not already installed.
|
||||||
|
5. Ensure $HOME/.cargo/bin is added to your PATH in ~/.bashrc if needed.
|
||||||
|
|
||||||
|
This script may call sudo for system changes.
|
||||||
|
It must be run as a normal user, not as root.
|
||||||
|
|
||||||
|
Proceed? [y/N]
|
||||||
|
EOF
|
||||||
|
|
||||||
|
read -r reply
|
||||||
|
case "${reply}" in
|
||||||
|
y|Y|yes|YES)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "[i] Aborted."
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
need_root() {
|
||||||
|
if [[ "${EUID}" -ne 0 ]]; then
|
||||||
|
require_cmd sudo
|
||||||
|
sudo "$@"
|
||||||
|
else
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_user() {
|
||||||
|
if [[ -n "${SUDO_USER:-}" && "${SUDO_USER}" != "root" ]]; then
|
||||||
|
printf '%s\n' "${SUDO_USER}"
|
||||||
|
else
|
||||||
|
id -un
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
user_home() {
|
||||||
|
local target_user
|
||||||
|
target_user="$(detect_user)"
|
||||||
|
getent passwd "${target_user}" | cut -d: -f6
|
||||||
|
}
|
||||||
|
|
||||||
|
install_docker_debian() {
|
||||||
|
if command -v docker >/dev/null 2>&1; then
|
||||||
|
echo "[+] docker already installed"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[i] installing docker"
|
||||||
|
need_root apt-get update
|
||||||
|
need_root apt-get install -y docker.io
|
||||||
|
need_root systemctl enable --now docker
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_docker_group_membership() {
|
||||||
|
local target_user
|
||||||
|
target_user="$(detect_user)"
|
||||||
|
|
||||||
|
if id -nG "${target_user}" | tr ' ' '\n' | grep -qx docker; then
|
||||||
|
echo "[+] user '${target_user}' is already in docker group"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[i] adding user '${target_user}' to docker group"
|
||||||
|
need_root usermod -aG docker "${target_user}"
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
|
[+] docker group membership was updated for user '${target_user}'.
|
||||||
|
You must log out and log back in before you can proceed.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
install_cross() {
|
||||||
|
require_cmd cargo
|
||||||
|
require_cmd rustup
|
||||||
|
|
||||||
|
if command -v cross >/dev/null 2>&1; then
|
||||||
|
echo "[+] cross already installed: $(command -v cross)"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[i] installing cross"
|
||||||
|
cargo install cross --locked
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_cargo_bin_in_bashrc_if_needed() {
|
||||||
|
local target_user home_dir bashrc cargo_bin line
|
||||||
|
target_user="$(detect_user)"
|
||||||
|
home_dir="$(user_home)"
|
||||||
|
bashrc="${home_dir}/.bashrc"
|
||||||
|
cargo_bin="${home_dir}/.cargo/bin"
|
||||||
|
line='export PATH="$HOME/.cargo/bin:$PATH"'
|
||||||
|
|
||||||
|
if command -v cross >/dev/null 2>&1; then
|
||||||
|
echo "[+] cross is already available in PATH: $(command -v cross)"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[!] cross is installed but not currently available in PATH"
|
||||||
|
|
||||||
|
mkdir -p "${cargo_bin}"
|
||||||
|
|
||||||
|
if [[ ! -f "${bashrc}" ]]; then
|
||||||
|
touch "${bashrc}"
|
||||||
|
chown "${target_user}:${target_user}" "${bashrc}" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep -Fqx "${line}" "${bashrc}"; then
|
||||||
|
printf '\n%s\n' "${line}" >> "${bashrc}"
|
||||||
|
chown "${target_user}:${target_user}" "${bashrc}" 2>/dev/null || true
|
||||||
|
echo "[+] added Cargo bin directory to ${bashrc}"
|
||||||
|
else
|
||||||
|
echo "[+] Cargo bin PATH line already present in ${bashrc}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
|
[i] PATH was updated in ${bashrc}, but the current shell will not pick it up automatically.
|
||||||
|
Log out and log back in, then verify:
|
||||||
|
command -v cross
|
||||||
|
cross --version
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
confirm_plan
|
||||||
|
ensure_not_root
|
||||||
|
require_cmd apt-get
|
||||||
|
require_cmd getent
|
||||||
|
|
||||||
|
install_docker_debian
|
||||||
|
ensure_docker_group_membership
|
||||||
|
install_cross
|
||||||
|
ensure_cargo_bin_in_bashrc_if_needed
|
||||||
|
|
||||||
|
cat <<'EOF'
|
||||||
|
|
||||||
|
[+] Setup complete.
|
||||||
|
Verify these two commands work:
|
||||||
|
docker --version
|
||||||
|
cross --version
|
||||||
|
|
||||||
|
Then run cross compilation:
|
||||||
|
cross build --release --target aarch64-unknown-linux-gnu
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Reference in New Issue
Block a user