feat: cross compile using docker

This commit is contained in:
Stephan Hradek 2025-11-28 09:11:48 +01:00
parent c29c811d3c
commit 630f956e4a
No known key found for this signature in database
GPG key ID: DDF026DB9AE9A387
6 changed files with 174 additions and 0 deletions

3
.gitignore vendored
View file

@ -12,3 +12,6 @@ result-*
.vscode/
*.snap
platform/built/
MacOSX*.sdk*

49
platform/README.md Normal file
View file

@ -0,0 +1,49 @@
# Cross Compile yazi for Different Platforms with Docker
I do not like to have multiple different development dependencies installed on
my computer, so I usually use [Docker](https://www.docker.com) to develop and
build.
Here are some dockerfiles to help in cross-compiling yazi for different
platforms which I use.
- QNAP TS 431 with OS 4.3.6
- macOS
## Build for QNAP TS431
As I own a QNAP TS431, I wanted to run yazi there as well.
Unfortunately it's a quite old system so I doubt many of you will have a use for
this, but maybe it helps someone to adapt it for another, older Linux.
To build simply run
`platform/ts431/build.sh`
When finished, you sholud have a directory `platform/built/ts431` containing
both, `ya` and `yazi`.
## Build for Apple
Here we have some options:
- `-a` `apple`|`intel`
- `-s` *own-sdk-version*
- `-m` *minimal-target-version*
When you have another macOS SDK than version 11.3, you can pass the version
number using `-s VERSIONNUMBER`.
Otherwise 11.3 will be downloaded and used.
To generate an SDK tarball, follow the instructions for
[osxcross](https://github.com/tpoechtrager/osxcross?tab=readme-ov-file#packaging-the-sdk).
Place your `MacOSX${VERSIONNMBER}.sdk.tar.xz` in`platform/mac/`.
Running `platform/mac/build.sh` without any options, will generate executables
for Apple Silicon hardware using SDK 11.3 and targeting at least 11.0.
To compile the same for Intel hardware run `platform/mac/build.sh -a intel`.
The resulting `ya` and `yazi` can be found in `platform/built/mac/apple` for
Apple Silicon and `platform/built/mac/intel` for Intel hardware.

58
platform/mac/Dockerfile Normal file
View file

@ -0,0 +1,58 @@
ARG OWNSDK="11.3"
ARG MACMIN="11.0"
# For Apple Silicon
ARG ARCH="aarch64"
# For Intel
# ARG ARCH="x86_64"
FROM rust:latest AS rustbuilder
ARG OWNSDK
ARG MACMIN
ARG ARCH
RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential ca-certificates clang cmake curl git llvm lld make pkg-config python3 xz-utils \
&& git clone --depth 1 https://github.com/tpoechtrager/osxcross.git /osxcross \
&& rm -rf /var/lib/apt/lists/* \
;
COPY platform/mac/*.sdk.tar.xz /mac/
RUN if [ "$OWNSDK" = "11.3" ] ; then \
curl -L -o /osxcross/tarballs/MacOSX11.3.sdk.tar.xz https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/MacOSX11.3.sdk.tar.xz ;\
else \
cp /mac/MacOSX${OWNSDK}.sdk.tar.xz /osxcross/tarballs/ ;\
fi \
&& UNATTENDED=1 OSX_VERSION_MIN=${MACMIN} /osxcross/build.sh \
&& echo rm -rf /osxcross/tarballs/* \
;
RUN rustup target add ${ARCH}-apple-darwin \
;
FROM rustbuilder AS macyazi
ARG MACMIN
ARG ARCH
ARG OWNSDK
WORKDIR /yazi
COPY . .
RUN export PATH=/osxcross/target/bin:$PATH \
&& export SDKROOT=/osxcross/target/SDK/MacOSX${OWNSDK}.sdk \
&& export MACOSX_DEPLOYMENT_TARGET=${MACMIN} \
&& if [ "$ARCH" = "aarch64" ] ; then CSTUFF="oa64" ; else CSTUFF="o64" ; fi \
&& ARCH_KEY="${ARCH}_apple_darwin" \
&& ARCH_UPPER="$( echo "$ARCH_KEY" | tr a-z A-Z )" \
&& eval "export CC_${ARCH_KEY}=${CSTUFF}-clang" \
&& eval "export CXX_${ARCH_KEY}=${CSTUFF}-clang++" \
&& eval "export CARGO_TARGET_${ARCH_UPPER}_LINKER=${CSTUFF}-clang" \
&& eval "export AR_${ARCH_KEY}=llvm-ar" \
&& eval "export RANLIB_${ARCH_KEY}=llvm-ranlib" \
&& cargo build --locked --release --target ${ARCH}-apple-darwin \
;
FROM scratch
ARG ARCH
COPY --from=macyazi /yazi/target/${ARCH}-apple-darwin/release/ya /yazi/target/${ARCH}-apple-darwin/release/yazi /

35
platform/mac/build.sh Executable file
View file

@ -0,0 +1,35 @@
#!/bin/bash
arch="apple"
min="11.0"
sdk="11.3"
plaintext=0
while getopts a:m:s:p opt
do
case "$opt" in
a) arch="$OPTARG" ;;
m) min="$OPTARG" ;;
s) sdk="$OPTARG" ;;
p) plaintext=1 ;; # For debugging
*) echo >&2 "unknown flag $opt"
exit 1
;;
esac
done
buildargs=(--build-arg MACMIN="$min" --build-arg OWNSDK="$sdk")
case "$arch" in
apple) buildargs+=(--build-arg ARCH="aarch64") ;;
intel) buildargs+=(--build-arg ARCH="x86_64") ;;
*) echo >&2 "unknown architecture $arch"
exit 2
;;
esac
if [[ $plaintext = 1 ]] ; then
buildargs+=(--progress=plain)
fi
dir="$( dirname "$0" )"
docker build -o "platform/built/$(basename "$dir")/$arch/" -f "$dir/Dockerfile" "${buildargs[@]}" .

25
platform/ts431/Dockerfile Normal file
View file

@ -0,0 +1,25 @@
FROM rust:slim AS builder
# Pakete, die IMMER verfügbar sind
RUN apt-get update && apt-get install -y \
build-essential \
gcc-arm-linux-gnueabihf \
pkg-config
# Rust ARMv7 target
RUN rustup target add armv7-unknown-linux-gnueabihf
WORKDIR /yazi
COPY . .
# Cross-linker setzen
ENV CC=arm-linux-gnueabihf-gcc
ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc
# wichtig für ring
ENV RUSTFLAGS="-C target-feature=+crt-static"
RUN cargo build --release --target armv7-unknown-linux-gnueabihf
FROM scratch
COPY --from=builder /yazi/target/armv7-unknown-linux-gnueabihf/release/yazi /yazi/target/armv7-unknown-linux-gnueabihf/release/ya /

4
platform/ts431/build.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
dir="$( dirname "$0" )"
docker build -o "platform/built/$(basename "$dir")/" -f "$dir/Dockerfile" .