Rewild Your Web
18
fork

Configure Feed

Select the types of activity you want to include in your feed.

build: use docker to cross-compile to aarch64

Signed-off-by: webbeef <me@webbeef.org>

webbeef 123b8714 072a9f3c

+153 -125
+1 -1
.cargo/config.toml
··· 29 29 linker = "lld-link.exe" 30 30 31 31 [target.aarch64-unknown-linux-gnu] 32 - linker = "./support/arm64/fake-clang-ld.sh" 32 + # Linker set via CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER in build-arm64.sh 33 33 34 34 [env] 35 35 MACOSX_DEPLOYMENT_TARGET = "13.0"
+1 -1
.gitignore
··· 1 1 source/ 2 2 target/ 3 - scripts/servo-arm64-sysroot 3 + dist/
-3
Cargo.toml
··· 308 308 lto = true 309 309 codegen-units = 1 310 310 opt-level = 3 311 - 312 - [profile.production-stripped] 313 - inherits = "production" 314 311 strip = true 315 312 316 313 [profile.profiling]
+44 -44
build-arm64.sh
··· 1 1 #!/bin/bash 2 + # SPDX-License-Identifier: AGPL-3.0-or-later 3 + # 4 + # Cross-compile Beaver for aarch64-unknown-linux-gnu using Docker. 5 + # The source tree is bind-mounted — no separate clone needed. 6 + # 7 + # The target/ directory uses a Docker named volume because macOS has a 8 + # case-insensitive filesystem which breaks mozjs (it generates both 9 + # string.h and String.h system wrappers that collide). 2 10 3 11 set -e 4 12 5 13 PROFILE=${1:-"release"} 6 - 7 - SYSROOT=`pwd`/scripts/servo-arm64-sysroot 8 - 9 - export PKG_CONFIG_SYSROOT_DIR=${SYSROOT} 10 - export PKG_CONFIG_ALLOW_CROSS=1 11 - 12 - export CC=clang 13 - export CXX=clang++ 14 - export AR=llvm-ar 15 - 16 - CXX_INCLUDES="-I${SYSROOT}/usr/include/c++/8/" 17 - 18 - # We need -fuse-ld=lld here for jemalloc-sys 19 - export TARGET_CFLAGS="--sysroot=${SYSROOT} -fuse-ld=lld -I${SYSROOT}/usr/include/aarch64-linux-gnu" 20 - export TARGET_CXXFLAGS="--sysroot=${SYSROOT} $CXX_INCLUDES" 21 - 22 - export CFLAGS="$TARGET_CFLAGS -I${SYSROOT}/usr/include/aarch64-linux-gnu" 23 - 24 - # Needed for mozjs bindgen 25 - export BINDGEN_EXTRA_CLANG_ARGS="--sysroot=${SYSROOT} $CXX_INCLUDES" 26 - 27 - # Needed for cmake 28 - export LDFLAGS="-L${SYSROOT}/lib/aarch64-linux-gnu -fuse-ld=lld" 29 - 30 - # Build without tray icon or global key support 31 - cargo build --target aarch64-unknown-linux-gnu --profile ${PROFILE} -p beaver-shell \ 32 - --no-default-features \ 33 - --features="servo/clipboard,js_jit,max_log_level,webgpu" 34 - 35 - llvm-strip target/aarch64-unknown-linux-gnu/${PROFILE}/beavershell 36 - 37 - REMOTE_DIR=/home/mobian/beaver 38 - 39 - echo "Pushing update..." 14 + IMAGE_NAME="beaver-arm64-builder" 15 + TARGET_VOLUME="beaver-arm64-target" 40 16 41 - # Create the beaver directory if needed. 42 - ssh mobian@mobian 'mkdir -p /home/mobian/beaver' 17 + # Build Docker image if it doesn't exist yet. 18 + if ! docker image inspect "$IMAGE_NAME" &>/dev/null; then 19 + echo "Building cross-compilation image..." 20 + docker build -t "$IMAGE_NAME" -f support/docker/Dockerfile.arm64 . 21 + fi 43 22 44 - # rsync the binary 45 - rsync -vz --progress target/aarch64-unknown-linux-gnu/${PROFILE}/beavershell \ 46 - mobian@mobian:${REMOTE_DIR}/beavershell 23 + echo "Building beaver-shell for aarch64 (profile: ${PROFILE})..." 47 24 48 - # rsync the resources 49 - rsync -avz --progress resources mobian@mobian:${REMOTE_DIR}/ 25 + docker run --rm \ 26 + --memory=24g \ 27 + -v "$(pwd):/src" \ 28 + -v "${TARGET_VOLUME}:/src/target" \ 29 + -v "${HOME}/.cargo/registry:/root/.cargo/registry" \ 30 + -v "${HOME}/.cargo/git:/root/.cargo/git" \ 31 + -e PKG_CONFIG_ALLOW_CROSS=1 \ 32 + -e PKG_CONFIG_SYSROOT_DIR="" \ 33 + -e PKG_CONFIG_PATH="/usr/lib/aarch64-linux-gnu/pkgconfig" \ 34 + -e CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc \ 35 + -e CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++ \ 36 + -e AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-ar \ 37 + -e CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \ 38 + -e BINDGEN_EXTRA_CLANG_ARGS="--target=aarch64-linux-gnu" \ 39 + -e CARGO_BUILD_JOBS="${CARGO_BUILD_JOBS:-8}" \ 40 + "$IMAGE_NAME" \ 41 + cargo build --target aarch64-unknown-linux-gnu --profile "$PROFILE" \ 42 + -p beaver-shell \ 43 + --no-default-features \ 44 + --features="servo/clipboard,servo/gstreamer,js_jit,max_log_level,native-bluetooth,webgpu" 50 45 51 - # rsync the UI 52 - rsync -avz --progress ui mobian@mobian:${REMOTE_DIR}/ 46 + # Copy the binary out of the Docker volume to the host for deploy. 47 + echo "Copying binary from Docker volume..." 48 + docker run --rm \ 49 + -v "${TARGET_VOLUME}:/target" \ 50 + -v "$(pwd)/dist:/out" \ 51 + "$IMAGE_NAME" \ 52 + sh -c "mkdir -p /out && cp /target/aarch64-unknown-linux-gnu/${PROFILE}/beavershell /out/" 53 53 54 - echo "done!" 54 + echo "Build complete: dist/beavershell"
+31
deploy-arm64.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: AGPL-3.0-or-later 3 + # 4 + # Deploy a cross-compiled Beaver build to a remote ARM64 device. 5 + 6 + set -e 7 + 8 + BINARY="dist/beavershell" 9 + REMOTE_HOST="mobian@mobian" 10 + REMOTE_DIR="/home/mobian/beaver" 11 + 12 + if [ ! -f "$BINARY" ]; then 13 + echo "Binary not found: $BINARY" 14 + echo "Run ./build-arm64.sh first." 15 + exit 1 16 + fi 17 + 18 + # Strip the binary (try llvm-strip first, fall back to cross strip). 19 + llvm-strip "$BINARY" 2>/dev/null || \ 20 + aarch64-linux-gnu-strip "$BINARY" 2>/dev/null || \ 21 + echo "Warning: could not strip binary" 22 + 23 + echo "Deploying to ${REMOTE_HOST}:${REMOTE_DIR}..." 24 + 25 + ssh "$REMOTE_HOST" "mkdir -p ${REMOTE_DIR}" 26 + 27 + rsync -vz --progress "$BINARY" "${REMOTE_HOST}:${REMOTE_DIR}/beavershell" 28 + rsync -avz --progress resources "${REMOTE_HOST}:${REMOTE_DIR}/" 29 + rsync -avz --progress ui "${REMOTE_HOST}:${REMOTE_DIR}/" 30 + 31 + echo "Done!"
+34 -9
readme.md
··· 38 38 39 39 ![The floating search window](media/desktop_5.png) 40 40 41 - ## Mobile builds 41 + ## Mobile builds (cross-compilation from macOS/Linux) 42 42 43 - The only tested platform is the Pixel 3a running Mobian (see https://wiki.debian.org/InstallingDebianOn/Google/Pixel3a). 43 + The target platform is aarch64 Linux devices such as the Pixel 3a running Mobian (see https://wiki.debian.org/InstallingDebianOn/Google/Pixel3a). 44 44 45 45 ![A rewilding Pixel 3a](media/pixel_3a.jpeg) 46 46 47 - First create a sysroot by running `sysroot.sh` in the `scripts` directory. 47 + ### Prerequisites 48 + 49 + - Docker Desktop (with at least 24GB memory allocated in Settings > Resources) 50 + 51 + ### Building 52 + 53 + Cross-compilation uses a Docker container with an ARM64 toolchain and all native dependencies. The source tree is bind-mounted so no separate clone is needed. 54 + 55 + ```bash 56 + # First build creates the Docker image, then compiles (takes a while): 57 + ./build-arm64.sh release 58 + 59 + # Subsequent builds are incremental: 60 + ./build-arm64.sh release 61 + 62 + # Production build with LTO: 63 + ./build-arm64.sh production 64 + ``` 65 + 66 + The binary is output to `dist/beavershell`. 67 + 68 + You can adjust parallelism if needed: `CARGO_BUILD_JOBS=2 ./build-arm64.sh release` 69 + 70 + ### Deploying to device 48 71 49 - Then build with `./build-arm64.sh` or `./build-arm64.sh production` 72 + The deploy script rsyncs the binary, resources, and UI to a remote device over SSH: 50 73 51 - The build script expects to be able to ssh with key authentication to `mobian@mobian`. You can then run on device with this command: 52 - `mobian@mobian:~$ ./beaver/beaver` 74 + ```bash 75 + ./deploy-arm64.sh 76 + ``` 53 77 54 - Note that you will have to set these 2 environment variables: 78 + This expects key-based SSH access to `mobian@mobian`. Then run on device: 55 79 56 - - SURFMAN_FORCE_GLES=1 57 - - WAYLAND_DISPLAY=wayland-0 80 + ```bash 81 + SURFMAN_FORCE_GLES=1 WAYLAND_DISPLAY=wayland-0 ./beaver/beavershell 82 + ``` 58 83 59 84 Here's what this looks like 60 85
-67
scripts/sysroot.sh
··· 1 - #!/bin/bash 2 - 3 - # Simplified version of: 4 - # https://searchfox.org/firefox-main/rev/e62801966f0afe75facf57d066b6e472fbbc1adb/taskcluster/scripts/misc/build-sysroot.sh 5 - 6 - set -x 7 - set -e 8 - 9 - sysroot="servo-arm64-sysroot" 10 - 11 - packages=" 12 - linux-libc-dev 13 - libasound2-dev 14 - libstdc++-8-dev 15 - libfontconfig1-dev 16 - libfreetype6-dev 17 - libgconf2-dev 18 - libgcc-8-dev 19 - libgtk-3-dev 20 - libpango1.0-dev 21 - libpulse-dev 22 - libudev-dev 23 - libx11-xcb-dev 24 - libxt-dev 25 - $* 26 - " 27 - 28 - echo "deb http://snapshot.debian.org/archive/debian/20230611T210420Z buster main" | mmdebstrap \ 29 - --architectures=arm64 \ 30 - --variant=extract \ 31 - --mode=fakeroot \ 32 - --include=$(echo $packages | tr ' ' ,) \ 33 - buster $sysroot \ 34 - --dpkgopt=path-exclude="*" \ 35 - --dpkgopt=path-include="/lib/*" \ 36 - --dpkgopt=path-include="/lib32/*" \ 37 - --dpkgopt=path-include="/usr/include/*" \ 38 - --dpkgopt=path-include="/usr/lib/*" \ 39 - --dpkgopt=path-include="/usr/lib32/*" \ 40 - --dpkgopt=path-exclude="/usr/lib/debug/*" \ 41 - --dpkgopt=path-exclude="/usr/lib/python*" \ 42 - --dpkgopt=path-include="/usr/share/pkgconfig/*" \ 43 - 44 - # Remove more unwanted files 45 - rm -rf $sysroot/etc $sysroot/dev $sysroot/tmp $sysroot/var 46 - 47 - # Remove empty directories 48 - find $sysroot -depth -type d -empty -delete 49 - 50 - # Adjust symbolic links to link into the sysroot instead of absolute 51 - # paths that end up pointing at the host system. 52 - find $sysroot -type l | while read l; do 53 - t=$(readlink $l) 54 - case "$t" in 55 - /*) 56 - # We have a path in the form "$sysroot/a/b/c/d" and we want ../../.., 57 - # which is how we get from d to the root of the sysroot. For that, 58 - # we start from the directory containing d ("$sysroot/a/b/c"), remove 59 - # all non-slash characters, leaving is with "///", replace each slash 60 - # with "../", which gives us "../../../", and then we remove the last 61 - # slash. 62 - rel=$(dirname $l | sed 's,[^/],,g;s,/,../,g;s,/$,,') 63 - ln -sf $rel$t $l 64 - ;; 65 - esac 66 - done 67 -
+42
support/docker/Dockerfile.arm64
··· 1 + # Cross-compilation environment for aarch64-unknown-linux-gnu. 2 + # Usage: docker build -t beaver-arm64-builder -f support/docker/Dockerfile.arm64 . 3 + 4 + FROM debian:bookworm-slim 5 + 6 + # Install host tools + cross-compilation support 7 + RUN dpkg --add-architecture arm64 && \ 8 + apt-get update && apt-get install -y --no-install-recommends \ 9 + # Host build tools 10 + build-essential pkg-config cmake python3 curl git ca-certificates \ 11 + clang lld llvm \ 12 + # Cross-compilation toolchain 13 + gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \ 14 + crossbuild-essential-arm64 \ 15 + # ARM64 native libraries 16 + libfreetype-dev:arm64 \ 17 + libfontconfig-dev:arm64 \ 18 + libgtk-3-dev:arm64 \ 19 + libpango1.0-dev:arm64 \ 20 + libpulse-dev:arm64 \ 21 + libudev-dev:arm64 \ 22 + libx11-xcb-dev:arm64 \ 23 + libxt-dev:arm64 \ 24 + libasound2-dev:arm64 \ 25 + libxkbcommon-dev:arm64 \ 26 + libgl-dev:arm64 \ 27 + libssl-dev:arm64 \ 28 + # Bluetooth (btleplug uses D-Bus on Linux) 29 + libdbus-1-dev:arm64 \ 30 + # GStreamer ARM64 31 + libgstreamer1.0-dev:arm64 \ 32 + libgstreamer-plugins-base1.0-dev:arm64 \ 33 + libgstreamer-plugins-bad1.0-dev:arm64 \ 34 + && rm -rf /var/lib/apt/lists/* 35 + 36 + # Install Rust stable with aarch64 target 37 + RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ 38 + sh -s -- -y --default-toolchain stable 39 + ENV PATH="/root/.cargo/bin:${PATH}" 40 + RUN rustup target add aarch64-unknown-linux-gnu 41 + 42 + WORKDIR /src