mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 20:55:44 +00:00
Add ARM64 Linux build infrastructure for Shardok (#4990)
* Add ARM64 Linux build infrastructure for Shardok Infrastructure to support cross-compiling Shardok for ARM64 Linux, enabling deployment to Hetzner ARM instances (CAX41) for on-demand compute. Changes: - Add linux_arm64 platform definition - Add LLVM toolchain for ARM64 cross-compilation - Add ARM64 sysroot placeholder (needs workflow run to populate) - Add ARM64 busybox for container health checks - Add Ubuntu 24.04 ARM64 base image - Add Shardok ARM64 container image targets - Update sysroot build workflow to support ARM64 Next steps: 1. Run "Build Linux Sysroot" workflow with architecture=arm64 2. Update MODULE.bazel with generated sysroot SHA 3. Build and push ARM64 container 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Update ARM64 sysroot SHA from workflow build 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix ARM64 container build issues - Use linux/arm64/v8 platform string (rules_oci requires variant suffix) - Remove busybox_layer_arm64 due to busybox.net SSL certificate issues - Health checks can be added later using an alternative busybox source 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add GitHub Actions workflow for ARM64 Shardok build Builds and pushes ARM64 container image to GitHub Container Registry for deployment on Hetzner ARM instances (CAX41). Triggered on: - Push to main (when Shardok-related files change) - Manual workflow_dispatch 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,12 +8,22 @@ on:
|
||||
required: true
|
||||
default: 'v2'
|
||||
type: string
|
||||
architecture:
|
||||
description: 'Target architecture'
|
||||
required: true
|
||||
default: 'amd64'
|
||||
type: choice
|
||||
options:
|
||||
- amd64
|
||||
- arm64
|
||||
- both
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-sysroot:
|
||||
build-sysroot-amd64:
|
||||
if: ${{ inputs.architecture == 'amd64' || inputs.architecture == 'both' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -25,7 +35,7 @@ jobs:
|
||||
- name: Upload sysroot artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ubuntu-noble-sysroot
|
||||
name: ubuntu-noble-sysroot-amd64
|
||||
path: tools/sysroot/output/
|
||||
|
||||
- name: Install AWS CLI
|
||||
@@ -41,7 +51,7 @@ jobs:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.SECRET_KEY }}
|
||||
run: |
|
||||
# Upload sysroot tarball to DO Spaces (using eagle0-windows bucket, same as other workflows)
|
||||
# Upload sysroot tarball to DO Spaces
|
||||
aws s3 cp tools/sysroot/output/ubuntu_noble_amd64_sysroot.tar.xz \
|
||||
s3://eagle0-windows/sysroot/${{ inputs.version }}/ubuntu_noble_amd64_sysroot.tar.xz \
|
||||
--endpoint-url https://sfo3.digitaloceanspaces.com \
|
||||
@@ -54,7 +64,7 @@ jobs:
|
||||
--acl public-read
|
||||
|
||||
echo ""
|
||||
echo "=== Sysroot uploaded ==="
|
||||
echo "=== AMD64 Sysroot uploaded ==="
|
||||
echo "URL: https://eagle0-windows.sfo3.digitaloceanspaces.com/sysroot/${{ inputs.version }}/ubuntu_noble_amd64_sysroot.tar.xz"
|
||||
echo "SHA256: $(cat tools/sysroot/output/ubuntu_noble_amd64_sysroot.sha256)"
|
||||
echo ""
|
||||
@@ -64,3 +74,64 @@ jobs:
|
||||
echo " sha256 = \"$(cat tools/sysroot/output/ubuntu_noble_amd64_sysroot.sha256)\","
|
||||
echo " urls = [\"https://eagle0-windows.sfo3.digitaloceanspaces.com/sysroot/${{ inputs.version }}/ubuntu_noble_amd64_sysroot.tar.xz\"],"
|
||||
echo ")"
|
||||
|
||||
build-sysroot-arm64:
|
||||
if: ${{ inputs.architecture == 'arm64' || inputs.architecture == 'both' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU for ARM64 emulation
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build ARM64 sysroot
|
||||
run: ./tools/sysroot/build_sysroot_arm64.sh
|
||||
|
||||
- name: Upload sysroot artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ubuntu-noble-sysroot-arm64
|
||||
path: tools/sysroot/output/
|
||||
|
||||
- name: Install AWS CLI
|
||||
run: |
|
||||
if ! command -v aws &> /dev/null; then
|
||||
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
||||
unzip -q awscliv2.zip
|
||||
sudo ./aws/install
|
||||
fi
|
||||
|
||||
- name: Upload to DigitalOcean Spaces
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.SECRET_KEY }}
|
||||
run: |
|
||||
# Upload sysroot tarball to DO Spaces
|
||||
aws s3 cp tools/sysroot/output/ubuntu_noble_arm64_sysroot.tar.xz \
|
||||
s3://eagle0-windows/sysroot/${{ inputs.version }}/ubuntu_noble_arm64_sysroot.tar.xz \
|
||||
--endpoint-url https://sfo3.digitaloceanspaces.com \
|
||||
--acl public-read
|
||||
|
||||
# Upload sha256 file
|
||||
aws s3 cp tools/sysroot/output/ubuntu_noble_arm64_sysroot.sha256 \
|
||||
s3://eagle0-windows/sysroot/${{ inputs.version }}/ubuntu_noble_arm64_sysroot.sha256 \
|
||||
--endpoint-url https://sfo3.digitaloceanspaces.com \
|
||||
--acl public-read
|
||||
|
||||
echo ""
|
||||
echo "=== ARM64 Sysroot uploaded ==="
|
||||
echo "URL: https://eagle0-windows.sfo3.digitaloceanspaces.com/sysroot/${{ inputs.version }}/ubuntu_noble_arm64_sysroot.tar.xz"
|
||||
echo "SHA256: $(cat tools/sysroot/output/ubuntu_noble_arm64_sysroot.sha256)"
|
||||
echo ""
|
||||
echo "Update MODULE.bazel with:"
|
||||
echo "sysroot("
|
||||
echo " name = \"linux_sysroot_arm64\","
|
||||
echo " sha256 = \"$(cat tools/sysroot/output/ubuntu_noble_arm64_sysroot.sha256)\","
|
||||
echo " urls = [\"https://eagle0-windows.sfo3.digitaloceanspaces.com/sysroot/${{ inputs.version }}/ubuntu_noble_arm64_sysroot.tar.xz\"],"
|
||||
echo ")"
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
name: Shardok ARM64 Build and Push
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- 'src/main/cpp/**'
|
||||
- 'src/main/protobuf/net/eagle0/shardok/**'
|
||||
- 'src/main/protobuf/net/eagle0/common/**'
|
||||
- 'src/main/resources/net/eagle0/shardok/**'
|
||||
- 'ci/BUILD.bazel'
|
||||
- 'MODULE.bazel'
|
||||
- '.github/workflows/shardok_arm64_build.yml'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
push_images:
|
||||
description: 'Push images to container registry'
|
||||
required: true
|
||||
default: 'true'
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build-shardok-arm64:
|
||||
runs-on: self-hosted
|
||||
outputs:
|
||||
image_tag: ${{ steps.push-shardok.outputs.image_tag }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
lfs: false
|
||||
|
||||
- name: Build Shardok ARM64 binary (cross-compile for Linux ARM64)
|
||||
run: |
|
||||
set -ex
|
||||
|
||||
echo "=== Building shardok-server binary for linux-aarch64 ==="
|
||||
bazel build \
|
||||
--platforms=//:linux_arm64 \
|
||||
--extra_toolchains=@llvm_toolchain_linux_arm64//:all \
|
||||
//src/main/cpp/net/eagle0/shardok:shardok-server
|
||||
|
||||
LINUX_BIN="bazel-bin/src/main/cpp/net/eagle0/shardok/shardok-server"
|
||||
echo "=== Checking binary at: $LINUX_BIN ==="
|
||||
|
||||
if [ ! -f "$LINUX_BIN" ]; then
|
||||
echo "ERROR: Binary not found at $LINUX_BIN"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify it's ELF (Linux) not Mach-O (macOS)
|
||||
echo "=== Verifying binary format ==="
|
||||
MAGIC=$(head -c 4 "$LINUX_BIN" | xxd -p)
|
||||
echo "Binary magic bytes: $MAGIC"
|
||||
|
||||
if [ "$MAGIC" = "7f454c46" ]; then
|
||||
echo "SUCCESS: Binary is ELF format (Linux)"
|
||||
# Check if it's ARM64 (e_machine = 0xB7 = 183 for aarch64)
|
||||
E_MACHINE=$(od -An -j18 -N2 -tx2 "$LINUX_BIN" | tr -d ' ')
|
||||
echo "ELF e_machine: $E_MACHINE"
|
||||
if [ "$E_MACHINE" = "b700" ]; then
|
||||
echo "SUCCESS: Binary is ARM64 (aarch64)"
|
||||
else
|
||||
echo "WARNING: Binary e_machine is $E_MACHINE (expected b700 for aarch64)"
|
||||
fi
|
||||
elif [ "$MAGIC" = "cfaeedfe" ] || [ "$MAGIC" = "cffaedfe" ]; then
|
||||
echo "ERROR: Binary is Mach-O format (macOS) - cross-compilation failed!"
|
||||
exit 1
|
||||
else
|
||||
echo "WARNING: Unknown binary format: $MAGIC"
|
||||
file "$LINUX_BIN" || true
|
||||
fi
|
||||
|
||||
- name: Build Shardok ARM64 Docker image
|
||||
id: build-shardok
|
||||
run: |
|
||||
set -ex
|
||||
|
||||
bazel build \
|
||||
--platforms=//:linux_arm64 \
|
||||
--extra_toolchains=@llvm_toolchain_linux_arm64//:all \
|
||||
//ci:shardok_server_image_arm64
|
||||
|
||||
IMAGE_PATH=$(readlink -f bazel-bin/ci/shardok_server_image_arm64)
|
||||
echo "Image path: $IMAGE_PATH"
|
||||
echo "image_path=$IMAGE_PATH" >> $GITHUB_OUTPUT
|
||||
|
||||
# Verify the binary inside the tar layer is ARM64 ELF
|
||||
echo "=== Verifying binary in image tar ==="
|
||||
BINARY_TAR="bazel-bin/ci/shardok_binary_layer_arm64.tar"
|
||||
if [ -f "$BINARY_TAR" ]; then
|
||||
echo "Checking binary in $BINARY_TAR"
|
||||
MAGIC=$(tar -xOf "$BINARY_TAR" app/shardok-server 2>/dev/null | head -c 4 | xxd -p)
|
||||
echo "Binary magic in tar: $MAGIC"
|
||||
if [ "$MAGIC" = "7f454c46" ]; then
|
||||
echo "SUCCESS: Binary in tar is ELF format (Linux)"
|
||||
else
|
||||
echo "ERROR: Binary in tar is NOT ELF format!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "WARNING: Could not find $BINARY_TAR"
|
||||
fi
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_images == 'true')
|
||||
env:
|
||||
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
echo "$GHCR_TOKEN" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
|
||||
- name: Push Shardok ARM64 image to GHCR
|
||||
id: push-shardok
|
||||
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_images == 'true')
|
||||
run: |
|
||||
set -ex
|
||||
|
||||
CROSS_IMAGE="${{ steps.build-shardok.outputs.image_path }}"
|
||||
echo "Using cross-compiled image: $CROSS_IMAGE"
|
||||
|
||||
if [ -z "$CROSS_IMAGE" ] || [ ! -d "$CROSS_IMAGE" ]; then
|
||||
echo "ERROR: Cross-compiled image not found at: $CROSS_IMAGE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build a push target to get crane in runfiles
|
||||
bazel build //ci:eagle_server_push
|
||||
|
||||
# Find the Darwin crane binary
|
||||
RUNFILES="bazel-bin/ci/push_eagle_server_push.sh.runfiles"
|
||||
CRANE=$(find "$RUNFILES" -path "*darwin*" -name crane 2>/dev/null | head -1)
|
||||
if [ -z "$CRANE" ]; then
|
||||
CRANE=$(find "$RUNFILES" -name crane 2>/dev/null | head -1)
|
||||
fi
|
||||
if [ -z "$CRANE" ] || [ ! -e "$CRANE" ]; then
|
||||
echo "ERROR: crane not found"
|
||||
exit 1
|
||||
fi
|
||||
echo "Using crane: $CRANE"
|
||||
|
||||
# Push with SHA tag
|
||||
GIT_SHA=$(git rev-parse --short=8 HEAD)
|
||||
IMAGE_TAG="ghcr.io/nolen777/shardok-server:${GIT_SHA}"
|
||||
echo "Pushing shardok ARM64 image: $IMAGE_TAG"
|
||||
$CRANE push "$CROSS_IMAGE" "$IMAGE_TAG"
|
||||
|
||||
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
|
||||
|
||||
# Also update :latest-arm64 for convenience
|
||||
echo "Copying to :latest-arm64 tag"
|
||||
$CRANE copy "$IMAGE_TAG" "ghcr.io/nolen777/shardok-server:latest-arm64"
|
||||
|
||||
echo "=== Push complete ==="
|
||||
echo "Image: $IMAGE_TAG"
|
||||
echo "Also tagged as: ghcr.io/nolen777/shardok-server:latest-arm64"
|
||||
@@ -12,6 +12,15 @@ platform(
|
||||
],
|
||||
)
|
||||
|
||||
# Platform for cross-compiling to Linux ARM64
|
||||
platform(
|
||||
name = "linux_arm64",
|
||||
constraint_values = [
|
||||
"@platforms//os:linux",
|
||||
"@platforms//cpu:aarch64",
|
||||
],
|
||||
)
|
||||
|
||||
gazelle(name = "gazelle")
|
||||
|
||||
# gazelle:proto file
|
||||
|
||||
+39
-5
@@ -57,25 +57,47 @@ llvm.toolchain(
|
||||
llvm_version = "20.1.2",
|
||||
)
|
||||
|
||||
# Linux sysroot for cross-compilation (Chromium's Debian sysroot)
|
||||
# Linux x86_64 sysroot for cross-compilation
|
||||
llvm.sysroot(
|
||||
name = "llvm_toolchain_linux",
|
||||
label = "@linux_sysroot//sysroot",
|
||||
targets = ["linux-x86_64"],
|
||||
)
|
||||
|
||||
use_repo(llvm, "llvm_toolchain", "llvm_toolchain_linux")
|
||||
# Cross-compilation toolchain (macOS -> Linux ARM64)
|
||||
llvm.toolchain(
|
||||
name = "llvm_toolchain_linux_arm64",
|
||||
llvm_version = "20.1.2",
|
||||
)
|
||||
|
||||
# Download the Linux sysroot (Ubuntu 24.04 Noble for C++23 support)
|
||||
# Linux ARM64 sysroot for cross-compilation
|
||||
llvm.sysroot(
|
||||
name = "llvm_toolchain_linux_arm64",
|
||||
label = "@linux_sysroot_arm64//sysroot",
|
||||
targets = ["linux-aarch64"],
|
||||
)
|
||||
|
||||
use_repo(llvm, "llvm_toolchain", "llvm_toolchain_linux", "llvm_toolchain_linux_arm64")
|
||||
|
||||
# Download the Linux sysroots (Ubuntu 24.04 Noble for C++23 support)
|
||||
# Built by: .github/workflows/build_sysroot.yml
|
||||
# To rebuild: Run the "Build Linux Sysroot" workflow with a new version, then update sha256 and URL
|
||||
sysroot = use_repo_rule("@toolchains_llvm//toolchain:sysroot.bzl", "sysroot")
|
||||
|
||||
# x86_64 sysroot
|
||||
sysroot(
|
||||
name = "linux_sysroot",
|
||||
sha256 = "a06475004fe8003ae7ccb4fe1d5511feb9b27cce4a8826eb1dfd686ed83f3dba",
|
||||
urls = ["https://eagle0-windows.sfo3.digitaloceanspaces.com/sysroot/v3/ubuntu_noble_amd64_sysroot.tar.xz"],
|
||||
)
|
||||
|
||||
# ARM64 sysroot
|
||||
sysroot(
|
||||
name = "linux_sysroot_arm64",
|
||||
sha256 = "87469137737e09bc73855007dab835477eb10a7b3ce3f725f93f64e25747f3f9",
|
||||
urls = ["https://eagle0-windows.sfo3.digitaloceanspaces.com/sysroot/v4/ubuntu_noble_arm64_sysroot.tar.xz"],
|
||||
)
|
||||
|
||||
#
|
||||
# Language Support - Go
|
||||
#
|
||||
@@ -144,7 +166,10 @@ oci.pull(
|
||||
oci.pull(
|
||||
name = "ubuntu_24_04",
|
||||
image = "docker.io/library/ubuntu",
|
||||
platforms = ["linux/amd64"],
|
||||
platforms = [
|
||||
"linux/amd64",
|
||||
"linux/arm64/v8",
|
||||
],
|
||||
tag = "24.04",
|
||||
)
|
||||
|
||||
@@ -155,7 +180,7 @@ oci.pull(
|
||||
platforms = ["linux/amd64"],
|
||||
tag = "3.21",
|
||||
)
|
||||
use_repo(oci, "alpine_linux", "alpine_linux_linux_amd64", "eclipse_temurin_17", "eclipse_temurin_17_linux_amd64", "ubuntu_24_04", "ubuntu_24_04_linux_amd64")
|
||||
use_repo(oci, "alpine_linux", "alpine_linux_linux_amd64", "eclipse_temurin_17", "eclipse_temurin_17_linux_amd64", "ubuntu_24_04", "ubuntu_24_04_linux_amd64", "ubuntu_24_04_linux_arm64_v8")
|
||||
|
||||
#
|
||||
# Java/Scala Dependencies
|
||||
@@ -275,6 +300,14 @@ http_file(
|
||||
executable = True,
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "busybox_aarch64",
|
||||
sha256 = "141adb1b625a6f44c4b114f76b4387b4ea4f7ab802b88eb40e0d2f6adcccb1c3",
|
||||
urls = ["https://busybox.net/downloads/binaries/1.35.0-aarch64-linux-musl/busybox"],
|
||||
downloaded_file_path = "busybox",
|
||||
executable = True,
|
||||
)
|
||||
|
||||
#
|
||||
# Toolchain Registration
|
||||
#
|
||||
@@ -288,5 +321,6 @@ register_toolchains(
|
||||
register_toolchains(
|
||||
"@llvm_toolchain//:all",
|
||||
"@llvm_toolchain_linux//:all",
|
||||
"@llvm_toolchain_linux_arm64//:all",
|
||||
dev_dependency = True,
|
||||
)
|
||||
|
||||
Generated
+18
-2
@@ -1293,7 +1293,7 @@
|
||||
"@@rules_oci~//oci:extensions.bzl%oci": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "FaY+7xb13bB3hmxqwAWaGp3Tf3Q4Nfdlr+F38CP5mcg=",
|
||||
"usagesDigest": "uqsqMpE+yaVuTByR2rIA2v1Vkm1JwwuN6nbXOo1W9G0=",
|
||||
"usagesDigest": "39yHQmifPoGf+JSYpnQSnJGugxbrFVge/+ENmUiqZ6M=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
@@ -1343,6 +1343,20 @@
|
||||
"bazel_tags": []
|
||||
}
|
||||
},
|
||||
"ubuntu_24_04_linux_arm64_v8": {
|
||||
"bzlFile": "@@rules_oci~//oci/private:pull.bzl",
|
||||
"ruleClassName": "oci_pull",
|
||||
"attributes": {
|
||||
"www_authenticate_challenges": {},
|
||||
"scheme": "https",
|
||||
"registry": "index.docker.io",
|
||||
"repository": "library/ubuntu",
|
||||
"identifier": "24.04",
|
||||
"platform": "linux/arm64/v8",
|
||||
"target_name": "ubuntu_24_04_linux_arm64_v8",
|
||||
"bazel_tags": []
|
||||
}
|
||||
},
|
||||
"ubuntu_24_04": {
|
||||
"bzlFile": "@@rules_oci~//oci/private:pull.bzl",
|
||||
"ruleClassName": "oci_alias",
|
||||
@@ -1354,7 +1368,8 @@
|
||||
"repository": "library/ubuntu",
|
||||
"identifier": "24.04",
|
||||
"platforms": {
|
||||
"@@platforms//cpu:x86_64": "@ubuntu_24_04_linux_amd64"
|
||||
"@@platforms//cpu:x86_64": "@ubuntu_24_04_linux_amd64",
|
||||
"@@platforms//cpu:arm64": "@ubuntu_24_04_linux_arm64_v8"
|
||||
},
|
||||
"bzlmod_repository": "ubuntu_24_04",
|
||||
"reproducible": true
|
||||
@@ -1528,6 +1543,7 @@
|
||||
"eclipse_temurin_17_linux_amd64",
|
||||
"ubuntu_24_04",
|
||||
"ubuntu_24_04_linux_amd64",
|
||||
"ubuntu_24_04_linux_arm64_v8",
|
||||
"alpine_linux",
|
||||
"alpine_linux_linux_amd64"
|
||||
],
|
||||
|
||||
@@ -17,6 +17,18 @@ pkg_tar(
|
||||
},
|
||||
)
|
||||
|
||||
pkg_tar(
|
||||
name = "busybox_layer_arm64",
|
||||
srcs = ["@busybox_aarch64//file"],
|
||||
package_dir = "/usr/local/bin",
|
||||
remap_paths = {
|
||||
"file/busybox": "busybox",
|
||||
},
|
||||
symlinks = {
|
||||
"/usr/local/bin/nc": "busybox",
|
||||
},
|
||||
)
|
||||
|
||||
#
|
||||
# Eagle Server Docker Image
|
||||
#
|
||||
@@ -155,6 +167,53 @@ oci_push(
|
||||
repository = "registry.digitalocean.com/eagle0/shardok-server",
|
||||
)
|
||||
|
||||
#
|
||||
# Shardok Server ARM64 Docker Image (for Hetzner on-demand compute)
|
||||
#
|
||||
# Build: bazel build //ci:shardok_server_image_arm64 --platforms=//:linux_arm64 --extra_toolchains=@llvm_toolchain_linux_arm64//:all
|
||||
# Load: bazel run //ci:shardok_server_load_arm64
|
||||
# Push: bazel run //ci:shardok_server_push_arm64
|
||||
#
|
||||
|
||||
# Package the Shardok binary (ARM64 version - must be built with --platforms=//:linux_arm64)
|
||||
pkg_tar(
|
||||
name = "shardok_binary_layer_arm64",
|
||||
srcs = ["//src/main/cpp/net/eagle0/shardok:shardok-server"],
|
||||
package_dir = "/app",
|
||||
)
|
||||
|
||||
oci_image(
|
||||
name = "shardok_server_image_arm64",
|
||||
base = "@ubuntu_24_04_linux_arm64_v8",
|
||||
entrypoint = ["/app/shardok-server"],
|
||||
exposed_ports = [
|
||||
"40042/tcp",
|
||||
"40052/tcp",
|
||||
],
|
||||
tars = [
|
||||
# Note: busybox_layer_arm64 omitted - busybox.net has SSL issues
|
||||
# Health checks can use the shardok-server binary itself or be added later
|
||||
":shardok_binary_layer_arm64",
|
||||
":shardok_resources_layer",
|
||||
":shardok_maps_layer",
|
||||
],
|
||||
workdir = "/app",
|
||||
)
|
||||
|
||||
# Load into Docker locally (ARM64): bazel run //ci:shardok_server_load_arm64
|
||||
oci_load(
|
||||
name = "shardok_server_load_arm64",
|
||||
image = ":shardok_server_image_arm64",
|
||||
repo_tags = ["eagle0/shardok-server:latest-arm64"],
|
||||
)
|
||||
|
||||
# Push to GitHub Container Registry (for Hetzner deployment)
|
||||
oci_push(
|
||||
name = "shardok_server_push_arm64",
|
||||
image = ":shardok_server_image_arm64",
|
||||
repository = "ghcr.io/nolen777/shardok-server",
|
||||
)
|
||||
|
||||
#
|
||||
# Admin Server Docker Image (Go)
|
||||
#
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# Dockerfile to create Ubuntu 24.04 (Noble) sysroot for cross-compilation to ARM64
|
||||
#
|
||||
# This creates a minimal sysroot containing headers and libraries needed
|
||||
# to cross-compile C++ code targeting Linux ARM64 (aarch64).
|
||||
#
|
||||
# Key requirement: Clang needs to find GCC's installation to locate libstdc++
|
||||
# headers. It looks for /usr/lib/gcc/<triple>/<version>/ in the sysroot.
|
||||
|
||||
FROM ubuntu:24.04
|
||||
|
||||
# Install the packages we need in the sysroot
|
||||
# These provide headers and libraries for linking
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
# C++ standard library with C++23 support (GCC 13)
|
||||
libstdc++-13-dev \
|
||||
# GCC 13 (needed for Clang to find C++ headers via GCC detection)
|
||||
gcc-13 \
|
||||
g++-13 \
|
||||
# C library
|
||||
libc6-dev \
|
||||
# Linux kernel headers
|
||||
linux-libc-dev \
|
||||
# Common dependencies
|
||||
zlib1g-dev \
|
||||
libssl-dev \
|
||||
# Clean up
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create sysroot directory
|
||||
RUN mkdir -p /sysroot
|
||||
|
||||
# Copy the essential directories for cross-compilation
|
||||
# Note: We preserve the exact directory structure that clang expects
|
||||
RUN cp -a /usr/include /sysroot/ && \
|
||||
cp -a /usr/lib/aarch64-linux-gnu /sysroot/usr_lib && \
|
||||
mkdir -p /sysroot/lib && \
|
||||
cp -a /lib/aarch64-linux-gnu /sysroot/lib/ && \
|
||||
# Copy GCC installation directory - Clang uses this to find libstdc++ headers
|
||||
# Copy everything except .so files (Bazel can't handle them as inputs)
|
||||
mkdir -p /sysroot/usr/lib/gcc && \
|
||||
cp -a /usr/lib/gcc/aarch64-linux-gnu /sysroot/usr/lib/gcc/ && \
|
||||
find /sysroot/usr/lib/gcc -name "*.so" -delete && \
|
||||
find /sysroot/usr/lib/gcc -name "*.so.*" -delete && \
|
||||
# Create symlinks for clang's target triple (aarch64-unknown-linux-gnu -> aarch64-linux-gnu)
|
||||
# Clang uses --target=aarch64-unknown-linux-gnu but Ubuntu uses aarch64-linux-gnu
|
||||
ln -s aarch64-linux-gnu /sysroot/usr/lib/gcc/aarch64-unknown-linux-gnu && \
|
||||
ln -s aarch64-linux-gnu /sysroot/lib/aarch64-unknown-linux-gnu && \
|
||||
ln -s aarch64-linux-gnu /sysroot/include/aarch64-unknown-linux-gnu
|
||||
Executable
+95
@@ -0,0 +1,95 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Build an Ubuntu 24.04 (Noble) ARM64 sysroot for cross-compilation
|
||||
#
|
||||
# This script:
|
||||
# 1. Builds a Docker image with the required packages (using QEMU for ARM64 emulation)
|
||||
# 2. Extracts the sysroot files
|
||||
# 3. Creates a tarball with proper structure for toolchains_llvm
|
||||
# 4. Computes the SHA256 hash
|
||||
#
|
||||
# Output: ubuntu_noble_arm64_sysroot.tar.xz and its SHA256
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
||||
SYSROOT_NAME="ubuntu_noble_arm64_sysroot"
|
||||
|
||||
echo "=== Building Ubuntu 24.04 ARM64 sysroot ==="
|
||||
|
||||
# Create output directory
|
||||
mkdir -p "${OUTPUT_DIR}"
|
||||
|
||||
# Enable Docker buildx for ARM64 emulation
|
||||
docker buildx create --use --name arm64builder 2>/dev/null || docker buildx use arm64builder
|
||||
|
||||
# Build the Docker image for ARM64
|
||||
echo "Building Docker image for ARM64 (this may take a while with QEMU emulation)..."
|
||||
docker buildx build --platform linux/arm64 -t sysroot-builder-arm64 -f "${SCRIPT_DIR}/Dockerfile.arm64" --load "${SCRIPT_DIR}"
|
||||
|
||||
# Create a container and extract the sysroot
|
||||
echo "Extracting sysroot..."
|
||||
CONTAINER_ID=$(docker create --platform linux/arm64 sysroot-builder-arm64)
|
||||
|
||||
# Create the sysroot structure expected by toolchains_llvm
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
SYSROOT_DIR="${TEMP_DIR}/sysroot"
|
||||
mkdir -p "${SYSROOT_DIR}/usr/lib" "${SYSROOT_DIR}/lib"
|
||||
|
||||
# Extract files from container
|
||||
docker cp "${CONTAINER_ID}:/sysroot/include" "${SYSROOT_DIR}/usr/"
|
||||
docker cp "${CONTAINER_ID}:/sysroot/usr_lib" "${SYSROOT_DIR}/usr/lib/aarch64-linux-gnu"
|
||||
docker cp "${CONTAINER_ID}:/sysroot/lib/aarch64-linux-gnu" "${SYSROOT_DIR}/lib/"
|
||||
|
||||
# Copy GCC installation directory - Clang uses this to find libstdc++ headers
|
||||
# The path /usr/lib/gcc/aarch64-linux-gnu/13 is where clang looks for GCC
|
||||
docker cp "${CONTAINER_ID}:/sysroot/usr/lib/gcc" "${SYSROOT_DIR}/usr/lib/"
|
||||
|
||||
# Create symlinks for clang's target triple (aarch64-unknown-linux-gnu -> aarch64-linux-gnu)
|
||||
# Note: docker cp preserves symlinks within directories, but we need to explicitly handle
|
||||
# symlinks at the top level of copied directories
|
||||
ln -sf aarch64-linux-gnu "${SYSROOT_DIR}/lib/aarch64-unknown-linux-gnu"
|
||||
|
||||
# Also need lib64 symlink for some builds
|
||||
ln -sf lib "${SYSROOT_DIR}/lib64"
|
||||
|
||||
# Create .so symlinks for shared libraries that only have versioned names
|
||||
# The linker looks for libfoo.so but Ubuntu only has libfoo.so.1
|
||||
ln -sf libgcc_s.so.1 "${SYSROOT_DIR}/lib/aarch64-linux-gnu/libgcc_s.so"
|
||||
|
||||
# Add dynamic linker symlink in lib/ since libc.so linker script
|
||||
# references /lib/ld-linux-aarch64.so.1 as an absolute path
|
||||
ln -sf aarch64-linux-gnu/ld-linux-aarch64.so.1 "${SYSROOT_DIR}/lib/ld-linux-aarch64.so.1"
|
||||
|
||||
# Create the tarball
|
||||
# Note: We create the tarball from inside the sysroot directory so the contents
|
||||
# are at the root level (usr/, lib/, etc.) rather than wrapped in sysroot/
|
||||
echo "Creating tarball..."
|
||||
cd "${SYSROOT_DIR}"
|
||||
tar -cJf "${OUTPUT_DIR}/${SYSROOT_NAME}.tar.xz" .
|
||||
|
||||
echo "Verifying tarball structure..."
|
||||
tar -tf "${OUTPUT_DIR}/${SYSROOT_NAME}.tar.xz" | head -20 || true
|
||||
|
||||
# Compute SHA256
|
||||
echo "Computing SHA256..."
|
||||
SHA256=$(shasum -a 256 "${OUTPUT_DIR}/${SYSROOT_NAME}.tar.xz" | cut -d' ' -f1)
|
||||
echo "${SHA256}" > "${OUTPUT_DIR}/${SYSROOT_NAME}.sha256"
|
||||
|
||||
# Cleanup
|
||||
docker rm "${CONTAINER_ID}" > /dev/null
|
||||
rm -rf "${TEMP_DIR}"
|
||||
|
||||
echo ""
|
||||
echo "=== ARM64 Sysroot build complete ==="
|
||||
echo "Tarball: ${OUTPUT_DIR}/${SYSROOT_NAME}.tar.xz"
|
||||
echo "SHA256: ${SHA256}"
|
||||
echo ""
|
||||
echo "To use this sysroot, upload it somewhere accessible and update MODULE.bazel:"
|
||||
echo ""
|
||||
echo "sysroot("
|
||||
echo " name = \"linux_sysroot_arm64\","
|
||||
echo " sha256 = \"${SHA256}\","
|
||||
echo " urls = [\"<your-upload-url>/${SYSROOT_NAME}.tar.xz\"],"
|
||||
echo ")"
|
||||
Reference in New Issue
Block a user