refactor: 升级依赖版本并优化构建系统

- 升级核心依赖 (axum 0.8, tower-http 0.6, alsa 0.11 等)
- 简化交叉编译配置,切换至 Debian 11 提高兼容性
- 新增 Debian 包打包支持 (debuerreotype 模板)
- 移除独立的 mjpeg 解码器,简化视频模块
- 静态链接 libx264/libx265/libopus 到二进制
This commit is contained in:
mofeng-git
2026-01-10 10:59:00 +08:00
parent 3fa91772f0
commit e670f1ffd1
46 changed files with 893 additions and 1156 deletions

View File

@@ -1,32 +1,36 @@
# One-KVM Runtime Image
# This Dockerfile only packages pre-compiled binaries (no compilation)
# Used after cross-compiling with `cross build`
# Using Debian 11 for maximum compatibility (GLIBC 2.31)
ARG TARGETPLATFORM=linux/amd64
FROM debian:12-slim
FROM debian:11-slim
ARG TARGETPLATFORM
# Install runtime dependencies in a single layer
# Static linked: FFmpeg core, libyuv, libvpx, libjpeg-turbo
# Dynamic linked: hardware acceleration drivers, GPL codecs (x264/x265)
# All codec libraries (libx264, libx265, libopus) are now statically linked
# Only hardware acceleration drivers and core system libraries remain dynamic
RUN apt-get update && \
apt-get install -y --no-install-recommends \
# Core runtime (all platforms)
libasound2 \
libv4l-0 \
libudev1 \
libdrm2 \
libopus0 \
# Core runtime (all platforms) - no codec libs needed
ca-certificates \
# GPL codecs (must be dynamic for license compliance)
libx264-164 \
libx265-199 && \
libudev1 \
libasound2 \
# v4l2 is handled by kernel, minimal userspace needed
libv4l-0 \
&& \
# Platform-specific hardware acceleration
if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
apt-get install -y --no-install-recommends \
libva2 libva-drm2 libva-x11-2 libx11-6 libxcb1 libmfx1; \
libva2 libva-drm2 libva-x11-2 libx11-6 libxcb1 libxau6 libxdmcp6 libmfx1; \
elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
apt-get install -y --no-install-recommends \
libdrm2 libva2; \
elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \
apt-get install -y --no-install-recommends \
libdrm2 libva2; \
fi && \
rm -rf /var/lib/apt/lists/* && \
mkdir -p /etc/one-kvm/ventoy

80
build/build-images.sh Executable file
View File

@@ -0,0 +1,80 @@
#!/bin/bash
# Build cross-compiled binaries using cross with custom Dockerfiles
# Usage: ./build/build-images.sh [arch]
# Example: ./build/build-images.sh x86_64
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
# Supported architectures (Rust target)
ARCH_MAP=(
"x86_64-unknown-linux-gnu"
"aarch64-unknown-linux-gnu"
"armv7-unknown-linux-gnueabihf"
)
# Build for specific architecture using cross
build_arch() {
local rust_target="$1"
echo "=== Building: $rust_target (via cross with custom Dockerfile) ==="
cross build --release --target "$rust_target"
}
# Main
case "${1:-all}" in
all)
for target in "${ARCH_MAP[@]}"; do
build_arch "$target"
done
;;
x86_64|arm64|armv7)
case "$1" in
x86_64) build_arch "x86_64-unknown-linux-gnu" ;;
arm64) build_arch "aarch64-unknown-linux-gnu" ;;
armv7) build_arch "armv7-unknown-linux-gnueabihf" ;;
esac
;;
help|--help|-h)
echo "Usage: $0 [arch|help]"
echo ""
echo "Commands:"
echo " all (default) Build all architectures"
echo " x86_64 Build only x86_64"
echo " arm64 Build only arm64"
echo " armv7 Build only ARMv7"
echo ""
echo "Examples:"
echo " $0 # Build all"
echo " $0 x86_64 # Build x86_64 only"
exit 0
;;
*)
echo "Error: Unknown argument: $1"
exit 1
;;
esac
echo ""
echo "Binaries built:"
for target in "${ARCH_MAP[@]}"; do
if [ -f "$PROJECT_DIR/target/$target/release/one-kvm" ]; then
echo " $target: OK"
fi
done
echo ""
echo "Static libraries:"
for target in "${ARCH_MAP[@]}"; do
case "$target" in
x86_64-unknown-linux-gnu) gnu_target="x86_64-linux-gnu" ;;
aarch64-unknown-linux-gnu) gnu_target="aarch64-linux-gnu" ;;
armv7-unknown-linux-gnueabihf) gnu_target="armv7-linux-gnueabihf" ;;
esac
if [ -d "$PROJECT_DIR/target/one-kvm-libs/$gnu_target/lib" ]; then
echo " $gnu_target: OK"
fi
done
echo ""
echo "Next step: ./build/package-docker.sh or ./build/package-deb.sh"

View File

@@ -1,7 +1,7 @@
# Cross-compilation image for ARM64 based on Debian 12
# Uses multiarch to install ARM64 libraries on x86_64 host
# Cross-compilation image for ARM64 based on Debian 11
# Build on Debian 11 (GLIBC 2.31) for maximum runtime compatibility
FROM debian:12
FROM debian:11
# Set Rustup mirrors (Aliyun)
ENV RUSTUP_UPDATE_ROOT=https://mirrors.aliyun.com/rustup/rustup \
@@ -28,7 +28,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
git \
libclang-dev \
llvm \
mold \
meson \
ninja-build \
wget \
@@ -36,6 +35,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
gcc-aarch64-linux-gnu \
g++-aarch64-linux-gnu \
libc6-dev-arm64-cross \
# Autotools for libopus (requires autoreconf)
autoconf \
automake \
libtool \
&& rm -rf /var/lib/apt/lists/*
# Install ARM64 development libraries (without VAAPI/X11 for ARM)
@@ -44,24 +47,22 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libv4l-dev:arm64 \
libudev-dev:arm64 \
zlib1g-dev:arm64 \
# Note: libjpeg-turbo, libyuv, libvpx are built from source below for static linking
libx264-dev:arm64 \
libx265-dev:arm64 \
libopus-dev:arm64 \
# Note: libjpeg-turbo, libyuv, libvpx, libx264, libx265, libopus are built from source below for static linking
libdrm-dev:arm64 \
&& rm -rf /var/lib/apt/lists/*
# Build static libjpeg-turbo from source (cross-compile for ARM64)
RUN git clone --depth 1 https://github.com/libjpeg-turbo/libjpeg-turbo /tmp/libjpeg-turbo \
&& cd /tmp/libjpeg-turbo \
&& cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
&& mkdir build && cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX=/usr/aarch64-linux-gnu \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
-DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
-DCMAKE_INSTALL_PREFIX=/opt/one-kvm-libs/aarch64-linux-gnu \
-DENABLE_SHARED=OFF -DENABLE_STATIC=ON \
&& cmake --build build -j$(nproc) \
&& cmake --install build \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/libjpeg-turbo
# Build static libyuv from source (cross-compile for ARM64)
@@ -69,16 +70,13 @@ RUN git clone --depth 1 https://github.com/lemenkov/libyuv /tmp/libyuv \
&& cd /tmp/libyuv \
&& mkdir build && cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX=/usr/aarch64-linux-gnu \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
-DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
-DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \
-DCMAKE_PREFIX_PATH=/opt/one-kvm-libs/aarch64-linux-gnu \
-DCMAKE_INSTALL_PREFIX=/opt/one-kvm-libs/aarch64-linux-gnu \
&& make -j$(nproc) \
&& mkdir -p /opt/one-kvm-libs/aarch64-linux-gnu/lib \
&& cp libyuv.a /opt/one-kvm-libs/aarch64-linux-gnu/lib/ \
&& cp -r ../include /opt/one-kvm-libs/aarch64-linux-gnu/ \
&& make install \
&& rm -rf /tmp/libyuv
# Build static libvpx from source (cross-compile for ARM64)
@@ -91,7 +89,8 @@ RUN git clone --depth 1 https://github.com/webmproject/libvpx /tmp/libvpx \
&& export LD=aarch64-linux-gnu-ld \
&& export AR=aarch64-linux-gnu-ar \
&& export CROSS=aarch64-linux-gnu- \
&& ./configure --prefix=/opt/one-kvm-libs/aarch64-linux-gnu \
&& ./configure \
--prefix=/usr/aarch64-linux-gnu \
--target=arm64-linux-gcc \
--enable-static --disable-shared --enable-pic \
--disable-examples --disable-tools --disable-docs \
@@ -102,9 +101,79 @@ RUN git clone --depth 1 https://github.com/webmproject/libvpx /tmp/libvpx \
&& file libvpx.a \
&& make install \
&& echo "=== libvpx: Verifying installed library ===" \
&& file /opt/one-kvm-libs/aarch64-linux-gnu/lib/libvpx.a \
&& file /usr/aarch64-linux-gnu/lib/libvpx.a \
&& rm -rf /tmp/libvpx
# Build static libx264 from source (cross-compile for ARM64)
RUN git clone --depth 1 https://code.videolan.org/videolan/x264.git /tmp/x264 \
&& cd /tmp/x264 \
&& export CC=aarch64-linux-gnu-gcc \
&& export AR=aarch64-linux-gnu-ar \
&& export RANLIB=aarch64-linux-gnu-ranlib \
&& ./configure \
--prefix=/usr/aarch64-linux-gnu \
--host=aarch64-linux-gnu \
--enable-static \
--enable-pic \
--disable-cli \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/x264
# Build static libx265 from source (cross-compile for ARM64)
RUN git clone --depth 1 https://bitbucket.org/multicoreware/x265_git /tmp/x265 \
&& cd /tmp/x265 \
&& cd source \
&& mkdir -p build \
&& cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/aarch64-linux-gnu \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
-DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
-DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \
-DENABLE_SHARED=OFF \
-DENABLE_CLI=OFF \
-DENABLE_NEON_DOTPROD=OFF \
-DENABLE_NEON_I8MM=OFF \
-DENABLE_SVE=OFF \
-DENABLE_SVE2=OFF \
-DENABLE_SVE2_BITPERM=OFF \
-DBUILD_SHARED_LIBS=OFF \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/x265
# Create pkg-config file for x265 (required by FFmpeg)
RUN mkdir -p /usr/aarch64-linux-gnu/lib/pkgconfig && \
cat > /usr/aarch64-linux-gnu/lib/pkgconfig/x265.pc <<EOF
prefix=/usr/aarch64-linux-gnu
exec_prefix=\${prefix}
libdir=\${exec_prefix}/lib
includedir=\${prefix}/include
Name: x265
Description: H.265/HEVC video encoder
Version: 199
Libs: -L\${libdir} -lx265 -lstdc++ -lm -ldl -lpthread
Cflags: -I\${includedir}
EOF
# Build static libopus from source (cross-compile for ARM64)
RUN git clone --depth 1 https://github.com/xiph/opus /tmp/opus \
&& cd /tmp/opus \
&& export CC=aarch64-linux-gnu-gcc \
&& export AR=aarch64-linux-gnu-ar \
&& export RANLIB=aarch64-linux-gnu-ranlib \
&& ./autogen.sh \
&& ./configure \
--host=aarch64-linux-gnu \
--enable-static --disable-shared \
--disable-doc \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/opus
# Download and build FFmpeg with RKMPP support
RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
&& wget -q https://files.mofeng.run/src/image/other/ffmpeg.tar.gz \
@@ -123,6 +192,7 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
-DBUILD_TEST=OFF \
&& make -j$(nproc) \
&& make install \
&& sed -i 's/^Libs:.*$/& -lstdc++ -lm -lpthread/' /usr/aarch64-linux-gnu/lib/pkgconfig/rockchip_mpp.pc \
&& cd ../.. \
# Build RKRGA - create cross file for meson
&& echo '[binaries]' > /tmp/aarch64-cross.txt \
@@ -146,10 +216,11 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
-Dlibrga_demo=false \
&& ninja -C build \
&& ninja -C build install \
&& sed -i 's/^Libs:.*$/& -lstdc++ -lm -lpthread/' /usr/aarch64-linux-gnu/lib/pkgconfig/librga.pc \
&& cd .. \
# Create pkg-config wrapper for cross-compilation
&& echo '#!/bin/sh' > /tmp/aarch64-pkg-config \
&& echo 'export PKG_CONFIG_LIBDIR=/opt/one-kvm-libs/aarch64-linux-gnu/lib/pkgconfig:/usr/aarch64-linux-gnu/lib/pkgconfig:/usr/lib/aarch64-linux-gnu/pkgconfig' >> /tmp/aarch64-pkg-config \
&& echo 'export PKG_CONFIG_LIBDIR=/usr/aarch64-linux-gnu/lib/pkgconfig:/usr/lib/aarch64-linux-gnu/pkgconfig' >> /tmp/aarch64-pkg-config \
&& echo 'export PKG_CONFIG_PATH=""' >> /tmp/aarch64-pkg-config \
&& echo 'export PKG_CONFIG_SYSROOT_DIR=""' >> /tmp/aarch64-pkg-config \
&& echo 'exec pkg-config "$@"' >> /tmp/aarch64-pkg-config \
@@ -157,7 +228,7 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
# Build FFmpeg with RKMPP (minimal build for encoding only)
&& cd ffmpeg-rockchip \
&& ./configure \
--prefix=/opt/one-kvm-libs/aarch64-linux-gnu \
--prefix=/usr/aarch64-linux-gnu \
--cross-prefix=aarch64-linux-gnu- \
--arch=aarch64 \
--target-os=linux \
@@ -235,25 +306,14 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
# Add Rust target
RUN rustup target add aarch64-unknown-linux-gnu
# Create symlink for mold to work with cross-compiler
RUN ln -s /usr/bin/mold /usr/bin/aarch64-linux-gnu-ld.mold
# Copy entrypoint script
COPY build/cross/entrypoint.sh /usr/local/bin/cross-entrypoint.sh
RUN chmod +x /usr/local/bin/cross-entrypoint.sh
# Configure environment for cross-compilation
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc \
CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++ \
AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-ar \
PKG_CONFIG_LIBDIR=/opt/one-kvm-libs/aarch64-linux-gnu/lib/pkgconfig:/usr/aarch64-linux-gnu/lib/pkgconfig:/usr/lib/aarch64-linux-gnu/pkgconfig \
PKG_CONFIG_LIBDIR=/usr/aarch64-linux-gnu/lib/pkgconfig:/usr/lib/aarch64-linux-gnu/pkgconfig \
PKG_CONFIG_PATH="" \
PKG_CONFIG_ALLOW_CROSS=1 \
LIBRARY_PATH="/opt/one-kvm-libs/aarch64-linux-gnu/lib" \
CPATH="/opt/one-kvm-libs/aarch64-linux-gnu/include" \
FFMPEG_STATIC=1 \
LIBYUV_STATIC=1 \
RUSTFLAGS="-C linker=aarch64-linux-gnu-gcc -C link-arg=-fuse-ld=mold"
ENTRYPOINT ["/usr/local/bin/cross-entrypoint.sh"]
RUSTFLAGS="-C linker=aarch64-linux-gnu-gcc"

View File

@@ -1,7 +1,7 @@
# Cross-compilation image for ARMv7 based on Debian 12
# Uses multiarch to install ARMv7 libraries on x86_64 host
# Cross-compilation image for ARMv7 based on Debian 11
# Build on Debian 11 (GLIBC 2.31) for maximum runtime compatibility
FROM debian:12
FROM debian:11
# Set Rustup mirrors (Aliyun)
ENV RUSTUP_UPDATE_ROOT=https://mirrors.aliyun.com/rustup/rustup \
@@ -28,7 +28,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
git \
libclang-dev \
llvm \
mold \
meson \
ninja-build \
wget \
@@ -36,6 +35,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
gcc-arm-linux-gnueabihf \
g++-arm-linux-gnueabihf \
libc6-dev-armhf-cross \
# Autotools for libopus (requires autoreconf)
autoconf \
automake \
libtool \
&& rm -rf /var/lib/apt/lists/*
# Install ARMv7 development libraries (without VAAPI/X11 for ARM)
@@ -44,24 +47,21 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libv4l-dev:armhf \
libudev-dev:armhf \
zlib1g-dev:armhf \
# Note: libjpeg-turbo, libyuv, libvpx are built from source below for static linking
libx264-dev:armhf \
libx265-dev:armhf \
libopus-dev:armhf \
libdrm-dev:armhf \
&& rm -rf /var/lib/apt/lists/*
# Build static libjpeg-turbo from source (cross-compile for ARMv7)
RUN git clone --depth 1 https://github.com/libjpeg-turbo/libjpeg-turbo /tmp/libjpeg-turbo \
&& cd /tmp/libjpeg-turbo \
&& cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
&& mkdir build && cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX=/usr/arm-linux-gnueabihf \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=arm \
-DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
-DCMAKE_INSTALL_PREFIX=/opt/one-kvm-libs/armv7-linux-gnueabihf \
-DENABLE_SHARED=OFF -DENABLE_STATIC=ON \
&& cmake --build build -j$(nproc) \
&& cmake --install build \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/libjpeg-turbo
# Build static libyuv from source (cross-compile for ARMv7)
@@ -69,20 +69,16 @@ RUN git clone --depth 1 https://github.com/lemenkov/libyuv /tmp/libyuv \
&& cd /tmp/libyuv \
&& mkdir build && cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX=/usr/arm-linux-gnueabihf \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=arm \
-DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
-DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \
-DCMAKE_PREFIX_PATH=/opt/one-kvm-libs/armv7-linux-gnueabihf \
-DCMAKE_INSTALL_PREFIX=/opt/one-kvm-libs/armv7-linux-gnueabihf \
&& make -j$(nproc) \
&& mkdir -p /opt/one-kvm-libs/armv7-linux-gnueabihf/lib \
&& cp libyuv.a /opt/one-kvm-libs/armv7-linux-gnueabihf/lib/ \
&& cp -r ../include /opt/one-kvm-libs/armv7-linux-gnueabihf/ \
&& make install \
&& rm -rf /tmp/libyuv
# Build static libvpx from source (cross-compile for ARMv7)
# CC/CXX/LD/AR must be environment variables, not configure arguments
RUN git clone --depth 1 https://github.com/webmproject/libvpx /tmp/libvpx \
&& cd /tmp/libvpx \
&& export CC=arm-linux-gnueabihf-gcc \
@@ -90,17 +86,83 @@ RUN git clone --depth 1 https://github.com/webmproject/libvpx /tmp/libvpx \
&& export LD=arm-linux-gnueabihf-ld \
&& export AR=arm-linux-gnueabihf-ar \
&& export CROSS=arm-linux-gnueabihf- \
&& ./configure --prefix=/opt/one-kvm-libs/armv7-linux-gnueabihf \
&& ./configure \
--prefix=/usr/arm-linux-gnueabihf \
--target=armv7-linux-gcc \
--enable-static --disable-shared --enable-pic \
--disable-examples --disable-tools --disable-docs \
--disable-unit-tests \
&& make -j$(nproc) \
&& echo "=== libvpx: Checking architecture ===" \
&& file libvpx.a \
&& make install \
&& rm -rf /tmp/libvpx
# Build static libx264 from source (cross-compile for ARMv7)
RUN git clone --depth 1 https://code.videolan.org/videolan/x264.git /tmp/x264 \
&& cd /tmp/x264 \
&& export CC=arm-linux-gnueabihf-gcc \
&& export AR=arm-linux-gnueabihf-ar \
&& export RANLIB=arm-linux-gnueabihf-ranlib \
&& ./configure \
--prefix=/usr/arm-linux-gnueabihf \
--host=arm-linux-gnueabihf \
--cross-prefix=arm-linux-gnueabihf- \
--enable-static --disable-shared \
--enable-pic \
--disable-cli \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/x264
# Build static libx265 from source (cross-compile for ARMv7)
RUN git clone --depth 1 https://bitbucket.org/multicoreware/x265_git /tmp/x265 \
&& cd /tmp/x265 \
&& cd source \
&& mkdir -p build \
&& cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/arm-linux-gnueabihf \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=arm \
-DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
-DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \
-DENABLE_SHARED=OFF \
-DENABLE_CLI=OFF \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/x265
# Create pkg-config file for x265 (required by FFmpeg)
RUN mkdir -p /usr/arm-linux-gnueabihf/lib/pkgconfig && \
cat > /usr/arm-linux-gnueabihf/lib/pkgconfig/x265.pc <<EOF
prefix=/usr/arm-linux-gnueabihf
exec_prefix=\${prefix}
libdir=\${exec_prefix}/lib
includedir=\${prefix}/include
Name: x265
Description: H.265/HEVC video encoder
Version: 199
Libs: -L\${libdir} -lx265 -lstdc++ -lm -ldl -lpthread
Cflags: -I\${includedir}
EOF
# Build static libopus from source (cross-compile for ARMv7)
RUN git clone --depth 1 https://github.com/xiph/opus /tmp/opus \
&& cd /tmp/opus \
&& export CC=arm-linux-gnueabihf-gcc \
&& export AR=arm-linux-gnueabihf-ar \
&& export RANLIB=arm-linux-gnueabihf-ranlib \
&& ./autogen.sh \
&& ./configure \
--host=arm-linux-gnueabihf \
--enable-static --disable-shared \
--disable-doc \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/opus
# Download and build FFmpeg with RKMPP support
RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
&& wget -q https://files.mofeng.run/src/image/other/ffmpeg.tar.gz \
@@ -119,6 +181,7 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
-DBUILD_TEST=OFF \
&& make -j$(nproc) \
&& make install \
&& sed -i 's/^Libs:.*$/& -lstdc++ -lm -lpthread/' /usr/arm-linux-gnueabihf/lib/pkgconfig/rockchip_mpp.pc \
&& cd ../.. \
# Build RKRGA - create cross file for meson
&& echo '[binaries]' > /tmp/armhf-cross.txt \
@@ -142,10 +205,11 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
-Dlibrga_demo=false \
&& ninja -C build \
&& ninja -C build install \
&& sed -i 's/^Libs:.*$/& -lstdc++ -lm -lpthread/' /usr/arm-linux-gnueabihf/lib/pkgconfig/librga.pc \
&& cd .. \
# Create pkg-config wrapper for cross-compilation
&& echo '#!/bin/sh' > /tmp/armhf-pkg-config \
&& echo 'export PKG_CONFIG_LIBDIR=/opt/one-kvm-libs/armv7-linux-gnueabihf/lib/pkgconfig:/usr/arm-linux-gnueabihf/lib/pkgconfig:/usr/lib/arm-linux-gnueabihf/pkgconfig' >> /tmp/armhf-pkg-config \
&& echo 'export PKG_CONFIG_LIBDIR=/usr/arm-linux-gnueabihf/lib/pkgconfig:/usr/arm-linux-gnueabihf/lib/pkgconfig:/usr/lib/arm-linux-gnueabihf/pkgconfig' >> /tmp/armhf-pkg-config \
&& echo 'export PKG_CONFIG_PATH=""' >> /tmp/armhf-pkg-config \
&& echo 'export PKG_CONFIG_SYSROOT_DIR=""' >> /tmp/armhf-pkg-config \
&& echo 'exec pkg-config "$@"' >> /tmp/armhf-pkg-config \
@@ -153,7 +217,7 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
# Build FFmpeg with RKMPP (minimal build for encoding only)
&& cd ffmpeg-rockchip \
&& ./configure \
--prefix=/opt/one-kvm-libs/armv7-linux-gnueabihf \
--prefix=/usr/arm-linux-gnueabihf \
--cross-prefix=arm-linux-gnueabihf- \
--arch=arm \
--target-os=linux \
@@ -231,25 +295,17 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
# Add Rust target
RUN rustup target add armv7-unknown-linux-gnueabihf
# Create symlink for mold to work with cross-compiler
RUN ln -s /usr/bin/mold /usr/bin/arm-linux-gnueabihf-ld.mold
# Copy entrypoint script
COPY build/cross/entrypoint.sh /usr/local/bin/cross-entrypoint.sh
RUN chmod +x /usr/local/bin/cross-entrypoint.sh
# Configure environment for cross-compilation
ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \
CC_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
CXX_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \
AR_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \
PKG_CONFIG_LIBDIR=/opt/one-kvm-libs/armv7-linux-gnueabihf/lib/pkgconfig:/usr/arm-linux-gnueabihf/lib/pkgconfig:/usr/lib/arm-linux-gnueabihf/pkgconfig \
PKG_CONFIG_LIBDIR=/usr/arm-linux-gnueabihf/lib/pkgconfig:/usr/lib/arm-linux-gnueabihf/pkgconfig \
PKG_CONFIG_PATH="" \
PKG_CONFIG_ALLOW_CROSS=1 \
LIBRARY_PATH="/opt/one-kvm-libs/armv7-linux-gnueabihf/lib" \
CPATH="/opt/one-kvm-libs/armv7-linux-gnueabihf/include" \
FFMPEG_STATIC=1 \
LIBYUV_STATIC=1 \
RUSTFLAGS="-C linker=arm-linux-gnueabihf-gcc -C link-arg=-fuse-ld=mold"
RUSTFLAGS="-C linker=arm-linux-gnueabihf-gcc"
ENTRYPOINT ["/usr/local/bin/cross-entrypoint.sh"]
# Default command
CMD ["bash"]

View File

@@ -1,7 +1,7 @@
# Cross-compilation image for x86_64 based on Debian 12
# Matches the runtime environment exactly
# Cross-compilation image for x86_64 based on Debian 11
# Build on Debian 11 (GLIBC 2.31) for maximum runtime compatibility
FROM debian:12
FROM debian:11
# Set Rustup mirrors (Aliyun)
ENV RUSTUP_UPDATE_ROOT=https://mirrors.aliyun.com/rustup/rustup \
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
ENV PATH="/root/.cargo/bin:${PATH}"
# Install build dependencies
# Note: libyuv, libvpx are built from source below for static linking
# Note: libyuv, libvpx, libx264, libx265, libopus are built from source below for static linking
RUN apt-get update && apt-get install -y --no-install-recommends \
# Build tools
build-essential \
@@ -28,20 +28,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
git \
libclang-dev \
llvm \
mold \
wget \
# Autotools for libopus (requires autoreconf)
autoconf \
automake \
libtool \
# Core system libraries
libasound2-dev \
libv4l-dev \
libudev-dev \
zlib1g-dev \
# Note: libjpeg-turbo is built from source below for static linking
# Video codec libraries (dynamic, for software fallback)
libx264-dev \
libx265-dev \
# Audio codec
libopus-dev \
# Hardware acceleration
# Note: libjpeg-turbo, libx264, libx265, libopus are built from source below for static linking
libva-dev \
libdrm-dev \
libmfx-dev \
@@ -55,11 +52,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
# Build static libjpeg-turbo from source (needed by libyuv)
RUN git clone --depth 1 https://github.com/libjpeg-turbo/libjpeg-turbo /tmp/libjpeg-turbo \
&& cd /tmp/libjpeg-turbo \
&& cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX=/opt/one-kvm-libs/x86_64-linux-gnu \
&& mkdir build && cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DENABLE_SHARED=OFF -DENABLE_STATIC=ON \
&& cmake --build build -j$(nproc) \
&& cmake --install build \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/libjpeg-turbo
# Build static libyuv from source (uses libjpeg-turbo headers)
@@ -67,32 +64,75 @@ RUN git clone --depth 1 https://github.com/lemenkov/libyuv /tmp/libyuv \
&& cd /tmp/libyuv \
&& mkdir build && cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_PREFIX_PATH=/opt/one-kvm-libs/x86_64-linux-gnu \
-DCMAKE_INSTALL_PREFIX=/opt/one-kvm-libs/x86_64-linux-gnu \
&& make -j$(nproc) \
&& mkdir -p /opt/one-kvm-libs/x86_64-linux-gnu/lib \
&& cp libyuv.a /opt/one-kvm-libs/x86_64-linux-gnu/lib/ \
&& cp -r ../include /opt/one-kvm-libs/x86_64-linux-gnu/ \
&& make install \
&& rm -rf /tmp/libyuv
# Build static libvpx from source
RUN git clone --depth 1 https://github.com/webmproject/libvpx /tmp/libvpx \
&& cd /tmp/libvpx \
&& ./configure --prefix=/opt/one-kvm-libs/x86_64-linux-gnu \
&& ./configure \
--enable-static --disable-shared --enable-pic \
--disable-examples --disable-tools --disable-docs \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/libvpx
# Build static libx264 from source
RUN git clone --depth 1 https://code.videolan.org/videolan/x264.git /tmp/x264 \
&& cd /tmp/x264 \
&& ./configure --enable-static --disable-cli \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/x264
# Build static libx265 from source
RUN git clone --depth 1 https://bitbucket.org/multicoreware/x265_git /tmp/x265 \
&& cd /tmp/x265 \
&& cd source \
&& mkdir -p build \
&& cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release \
-DENABLE_SHARED=OFF \
-DENABLE_CLI=OFF \
-DBUILD_SHARED_LIBS=OFF \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/x265
# Create pkg-config file for x265 (required by FFmpeg)
# Fix: Added -lstdc++ -lm -ldl -lpthread to Libs for static linking compatibility
RUN mkdir -p /usr/local/lib/pkgconfig && \
cat > /usr/local/lib/pkgconfig/x265.pc <<EOF
prefix=/usr/local
exec_prefix=\${prefix}
libdir=\${exec_prefix}/lib
includedir=\${prefix}/include
Name: x265
Description: H.265/HEVC video encoder
Version: 199
Libs: -L\${libdir} -lx265 -lstdc++ -lm -ldl -lpthread
Cflags: -I\${includedir}
EOF
# Build static libopus from source
RUN git clone --depth 1 https://github.com/xiph/opus /tmp/opus \
&& cd /tmp/opus \
&& ./autogen.sh \
&& ./configure \
--enable-static --disable-shared \
--disable-doc \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/opus
# Download and build FFmpeg with minimal configuration for encoding only
RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
&& wget -q https://files.mofeng.run/src/image/other/ffmpeg.tar.gz \
&& tar -xzf ffmpeg.tar.gz \
&& cd ffmpeg/ffmpeg-rockchip \
&& export PKG_CONFIG_PATH="/opt/one-kvm-libs/x86_64-linux-gnu/lib/pkgconfig:$PKG_CONFIG_PATH" \
&& ./configure \
--prefix=/opt/one-kvm-libs/x86_64-linux-gnu \
--enable-gpl \
--enable-version3 \
--disable-shared \
@@ -165,16 +205,7 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
# Add Rust target
RUN rustup target add x86_64-unknown-linux-gnu
# Copy entrypoint script
COPY build/cross/entrypoint.sh /usr/local/bin/cross-entrypoint.sh
RUN chmod +x /usr/local/bin/cross-entrypoint.sh
# Configure environment for static linking
ENV RUSTFLAGS="-C link-arg=-fuse-ld=mold" \
PKG_CONFIG_PATH="/opt/one-kvm-libs/x86_64-linux-gnu/lib/pkgconfig" \
LIBRARY_PATH="/opt/one-kvm-libs/x86_64-linux-gnu/lib" \
CPATH="/opt/one-kvm-libs/x86_64-linux-gnu/include" \
ENV PKG_CONFIG_ALLOW_CROSS=1\
FFMPEG_STATIC=1 \
LIBYUV_STATIC=1
ENTRYPOINT ["/usr/local/bin/cross-entrypoint.sh"]
LIBYUV_STATIC=1

View File

@@ -0,0 +1,5 @@
one-kvm ({version}) stable; urgency=low
* Initial release
-- SilentWind <admin@mofeng.run> {date}

22
build/debian/control.tpl Normal file
View File

@@ -0,0 +1,22 @@
Source: one-kvm
Section: admin
Priority: optional
Maintainer: SilentWind <admin@mofeng.run>
Package: one-kvm
Architecture: {arch}
Depends: ${{auto}}, ca-certificates{distsuffix}
Description: A open and lightweight IP-KVM solution written in Rust
Enables BIOS-level remote management of servers and workstations.
.
One-KVM provides video capture, HID emulation (keyboard/mouse),
mass storage device forwarding, and ATX power control for
remote server management over IP.
.
Features:
* Hardware-accelerated video encoding (VAAPI, QSV, RKMPP)
* WebRTC and MJPEG streaming with low latency
* USB HID emulation via OTG gadget
* Mass storage device for ISO/IMG mounting
* ATX power control via GPIO or USB relay
Homepage: https://github.com/mofeng-git/One-KVM

29
build/debian/copyright Normal file
View File

@@ -0,0 +1,29 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: one-kvm
Source: https://github.com/mofeng-git/one-KVM
Files: *
Copyright: 2025 One-KVM contributors
License: GPL-2.0
Files: libs/ventoy-img-rs/resources/*
Copyright: Ventoy contributors
License: GPL-2.0
License: GPL-2.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
On Debian systems, the full text of the GNU General Public License
version 2 can be found in the file `/usr/share/common-licenses/GPL-2'.

39
build/debian/postinst.tpl Normal file
View File

@@ -0,0 +1,39 @@
#!/bin/bash
# Post-installation script for one-kvm
set -e
case "$1" in
configure|abort-upgrade|abort-remove|abort-deconfigure)
# Create data directory
mkdir -p /var/lib/one-kvm/ventoy
mkdir -p /var/log/one-kvm
# Set permissions
chmod 755 /var/lib/one-kvm
chmod 755 /var/lib/one-kvm/ventoy
chmod 755 /var/log/one-kvm
# Enable and start service (if systemd is available)
if [ -d /run/systemd/system ]; then
systemctl daemon-reload
systemctl enable one-kvm
# Don't start here, let user configure first
fi
;;
triggered)
# Handle triggers (e.g., systemd restart)
if [ -d /run/systemd/system ]; then
systemctl restart one-kvm || true
fi
;;
abort-rollback|failed-upgrade)
exit 0
;;
*)
echo "postinst called with unknown argument: $1" >&2
exit 1
;;
esac
exit 0

28
build/debian/prerm.tpl Normal file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
# Pre-removal script for one-kvm
set -e
case "$1" in
remove|purge)
# Stop service if running
if [ -d /run/systemd/system ]; then
systemctl stop one-kvm || true
systemctl disable one-kvm || true
fi
;;
upgrade|deconfigure)
# Keep data on upgrade
:
;;
failed-upgrade)
# Handle upgrade failure
:
;;
*)
echo "prerm called with unknown argument: $1" >&2
exit 1
;;
esac
exit 0

15
build/one-kvm.service Normal file
View File

@@ -0,0 +1,15 @@
[Unit]
Description=One-KVM IP-KVM Service
Documentation=https://github.com/mofeng-git/One-KVM
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=root
ExecStart=/usr/bin/one-kvm
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

178
build/package-deb.sh Executable file
View File

@@ -0,0 +1,178 @@
#!/bin/bash
# Build deb packages from pre-compiled binaries
# Binaries are compiled once on Debian 11 (GLIBC 2.31) via build-images.sh
# This script packages them directly on the host using dpkg-deb
# Usage: ./build/build-deb.sh [arch]
# Example: ./build/build-deb.sh aarch64
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
# Version from Cargo.toml
VERSION=$(grep -m1 '^version =' "$PROJECT_DIR/Cargo.toml" | cut -d'"' -f2)
if [ -z "$VERSION" ]; then
echo "Error: Could not extract version from Cargo.toml"
exit 1
fi
OUTPUT_DIR="$PROJECT_DIR/target/debian"
mkdir -p "$OUTPUT_DIR"
# Supported architectures
TARGETS=(
"x86_64-unknown-linux-gnu:amd64"
"aarch64-unknown-linux-gnu:arm64"
"armv7-unknown-linux-gnueabihf:armhf"
)
# Package single architecture
package_arch() {
local RUST_TARGET="$1"
local DEB_ARCH="$2"
echo "========================================"
echo "Packaging: $RUST_TARGET -> $DEB_ARCH"
echo "========================================"
local BINARY_PATH="$PROJECT_DIR/target/$RUST_TARGET/release/one-kvm"
if [[ ! -f "$BINARY_PATH" ]]; then
echo "Error: Binary not found at $BINARY_PATH"
echo "Please run ./build/build-images.sh first."
return 1
fi
local PKG_DIR="/tmp/one-kvm-pkg-$$"
local DEB_PATH="$OUTPUT_DIR/one-kvm_${VERSION}_${DEB_ARCH}.deb"
# Create package structure
mkdir -p "$PKG_DIR/DEBIAN"
mkdir -p "$PKG_DIR/usr/bin"
mkdir -p "$PKG_DIR/etc/one-kvm/ventoy"
mkdir -p "$PKG_DIR/lib/systemd/system"
# Copy binary
cp "$BINARY_PATH" "$PKG_DIR/usr/bin/one-kvm"
chmod 755 "$PKG_DIR/usr/bin/one-kvm"
# Copy and process ventoy resources (decompress .xz files)
if [ -d "$PROJECT_DIR/libs/ventoy-img-rs/resources" ]; then
for file in "$PROJECT_DIR/libs/ventoy-img-rs/resources/"*; do
if [ -f "$file" ]; then
local filename=$(basename "$file")
if [[ "$filename" == *.xz ]]; then
# Decompress xz files to target dir (not in-place)
xz -d -c "$file" > "$PKG_DIR/etc/one-kvm/ventoy/${filename%.xz}"
else
cp "$file" "$PKG_DIR/etc/one-kvm/ventoy/"
fi
fi
done
fi
# Copy systemd service file
if [ -f "$SCRIPT_DIR/one-kvm.service" ]; then
cp "$SCRIPT_DIR/one-kvm.service" "$PKG_DIR/lib/systemd/system/"
fi
# Create postinst script (enable service on install)
cat > "$PKG_DIR/DEBIAN/postinst" <<'EOF'
#!/bin/bash
set -e
case "$1" in
configure)
# Enable and start service
if [ -f /lib/systemd/system/one-kvm.service ]; then
systemctl enable one-kvm
systemctl start one-kvm || true
fi
;;
abort-upgrade|abort-deconfigure|abort-remove)
;;
*)
;;
esac
exit 0
EOF
chmod 755 "$PKG_DIR/DEBIAN/postinst"
# Create prerm script (stop service on remove)
cat > "$PKG_DIR/DEBIAN/prerm" <<'EOF'
#!/bin/bash
set -e
case "$1" in
remove|deconfigure)
if [ -f /lib/systemd/system/one-kvm.service ]; then
systemctl stop one-kvm || true
systemctl disable one-kvm || true
fi
;;
upgrade)
if [ -f /lib/systemd/system/one-kvm.service ]; then
systemctl stop one-kvm || true
fi
;;
failed-upgrade)
;;
*)
;;
esac
exit 0
EOF
chmod 755 "$PKG_DIR/DEBIAN/prerm"
# Create control file
cat > "$PKG_DIR/DEBIAN/control" <<EOF
Package: one-kvm
Version: $VERSION
Section: admin
Priority: optional
Architecture: $DEB_ARCH
Depends: libc6 (>= 2.31), libgcc-s1, libstdc++6, libasound2 (>= 1.1), libva2 (>= 2.0), libdrm2 (>= 2.4), libx11-6 (>= 1.6), libxcb1 (>= 1.14)
Maintainer: SilentWind <admin@mofeng.run>
Description: A open and lightweight IP-KVM solution
Enables BIOS-level remote management of servers and workstations.
Built on Debian 11, compatible with Debian 11+, Ubuntu 20.04+.
EOF
# Build deb directly on host
dpkg-deb --build "$PKG_DIR" "$DEB_PATH"
rm -rf "$PKG_DIR"
echo "Created: $DEB_PATH"
}
# Main
if [ -n "$1" ]; then
# Package specific arch
FOUND=0
for target in "${TARGETS[@]}"; do
IFS=':' read -r RUST_TARGET DEB_ARCH <<< "$target"
if [[ "$1" == "$DEB_ARCH" ]] || [[ "$1" == "$RUST_TARGET" ]]; then
package_arch "$RUST_TARGET" "$DEB_ARCH"
FOUND=1
break
fi
done
if [ $FOUND -eq 0 ]; then
echo "Error: Unknown architecture: $1"
echo "Available: amd64, arm64, armhf"
exit 1
fi
else
# Package all architectures
for target in "${TARGETS[@]}"; do
IFS=':' read -r RUST_TARGET DEB_ARCH <<< "$target"
package_arch "$RUST_TARGET" "$DEB_ARCH"
done
fi
echo ""
echo "========================================"
echo "All packages built successfully!"
echo "========================================"
ls -la "$OUTPUT_DIR"/*.deb

View File

@@ -81,7 +81,7 @@ while [[ $# -gt 0 ]]; do
BUILD_BINARY=true
shift
;;
--help)
-h|--help)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Package pre-compiled One-KVM binaries into Docker images."