ci: 完善构建流程和中国网络环境加速

This commit is contained in:
mofeng-git
2026-06-10 09:48:42 +08:00
parent 921c00c472
commit 4b65eebd5d
29 changed files with 7166 additions and 367 deletions

View File

@@ -1,14 +0,0 @@
# Agents Notes
## Windows MSVC Build
Run from the repository root in PowerShell:
```powershell
$env:VCPKG_ROOT='C:\Users\mofen\code\vcpkg'
$env:TURBOJPEG_SOURCE='explicit'
$env:TURBOJPEG_LIB_DIR='C:\Users\mofen\code\vcpkg\installed\x64-windows-static\lib'
$env:TURBOJPEG_INCLUDE_DIR='C:\Users\mofen\code\vcpkg\installed\x64-windows-static\include'
cargo build --target x86_64-pc-windows-msvc
```

View File

@@ -44,8 +44,6 @@ val oneKvmVersion = Regex("""(?m)^version\s*=\s*"([^"]+)"""")
?.groupValues
?.get(1)
?: throw GradleException("Failed to resolve version from root Cargo.toml")
val androidFfmpegSourceDir = rootProject.layout.projectDirectory
.dir("../.tmp/android-ffmpeg-check/src/ffmpeg-rockchip")
val localProperties = Properties().apply {
val file = rootProject.file("local.properties")
if (file.exists()) {
@@ -207,7 +205,6 @@ tasks.register<Exec>("buildAndroidFfmpegMediaCodec") {
group = "build"
val ffmpegRoot = file(androidFfmpegRoot.get())
val sourceDir = androidFfmpegSourceDir.asFile
val scriptFile = androidFfmpegBuildScript.asFile
val stampFile = ffmpegRoot.resolve(".one-kvm-android-ffmpeg.stamp")
@@ -215,8 +212,6 @@ tasks.register<Exec>("buildAndroidFfmpegMediaCodec") {
commandLine(
"bash",
scriptFile.absolutePath,
"--source",
sourceDir.absolutePath,
"--output",
ffmpegRoot.absolutePath,
"--ndk",
@@ -227,7 +222,6 @@ tasks.register<Exec>("buildAndroidFfmpegMediaCodec") {
selectedAndroidAbis.joinToString(","),
)
inputs.dir(sourceDir)
inputs.file(scriptFile)
outputs.dir(ffmpegRoot)
@@ -235,12 +229,6 @@ tasks.register<Exec>("buildAndroidFfmpegMediaCodec") {
val hasAndroidFfmpeg = androidFfmpegRequiredFiles(ffmpegRoot).all { it.exists() }
val hasCurrentBuildStamp =
stampFile.exists() && stampFile.readText() == androidFfmpegBuildStamp(scriptFile)
if (!hasAndroidFfmpeg && !sourceDir.resolve("configure").exists()) {
throw GradleException(
"Missing Android FFmpeg MediaCodec build at ${ffmpegRoot.absolutePath}, " +
"and source was not found at ${sourceDir.absolutePath}",
)
}
!hasAndroidFfmpeg || !hasCurrentBuildStamp
}

View File

@@ -1,5 +1,16 @@
pluginManagement {
fun isEnabled(value: String?): Boolean = when (value?.lowercase()) {
"1", "true", "yes", "on" -> true
else -> false
}
val mirrorAcceleration = isEnabled(System.getenv("CHINAMIRRO"))
repositories {
if (mirrorAcceleration) {
maven("https://maven.aliyun.com/repository/google")
maven("https://maven.aliyun.com/repository/public")
maven("https://maven.aliyun.com/repository/gradle-plugin")
}
google()
mavenCentral()
gradlePluginPortal()
@@ -7,8 +18,18 @@ pluginManagement {
}
dependencyResolutionManagement {
fun isEnabled(value: String?): Boolean = when (value?.lowercase()) {
"1", "true", "yes", "on" -> true
else -> false
}
val mirrorAcceleration = isEnabled(System.getenv("CHINAMIRRO"))
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
if (mirrorAcceleration) {
maven("https://maven.aliyun.com/repository/google")
maven("https://maven.aliyun.com/repository/public")
}
google()
mavenCentral()
}

View File

@@ -17,28 +17,21 @@ fail() {
build_android() {
local arch="$1"
local docker_build_args=()
local docker_mount_args=()
local gradle_distribution_url="${ONE_KVM_GRADLE_DISTRIBUTION_URL:-}"
local gradle_distribution_url_cn="${ONE_KVM_GRADLE_DISTRIBUTION_URL_CN:-https://mirrors.cloud.tencent.com/gradle/gradle-9.1.0-bin.zip}"
local gradle_network_timeout="${ONE_KVM_GRADLE_NETWORK_TIMEOUT:-120000}"
local gradle_cache="${ONE_KVM_ANDROID_GRADLE_CACHE_DIR:-one-kvm-android-gradle-cache}"
local cargo_registry_cache="${ONE_KVM_ANDROID_CARGO_REGISTRY_CACHE_DIR:-one-kvm-android-cargo-registry}"
local cargo_git_cache="${ONE_KVM_ANDROID_CARGO_GIT_CACHE_DIR:-one-kvm-android-cargo-git}"
add_cache_mount() {
local source="$1"
local target="$2"
if [[ "$source" == /* || "$source" == ./* || "$source" == ../* ]]; then
mkdir -p "$source"
source="$(cd "$source" && pwd)"
fi
docker_mount_args+=("-v" "$source:$target")
}
if [[ "${CHINAMIRRO:-}" == "1" ]]; then
docker_build_args+=("--build-arg" "CHINAMIRRO=1")
docker_build_args+=("--build-arg" "DEBIAN_IMAGE=${DEBIAN_IMAGE:-docker.1ms.run/library/debian:11}")
docker_build_args+=("--build-arg" "RUSTUP_DIST_SERVER_CN=${RUSTUP_DIST_SERVER_CN:-https://rsproxy.cn}")
docker_build_args+=("--build-arg" "RUSTUP_UPDATE_ROOT_CN=${RUSTUP_UPDATE_ROOT_CN:-https://rsproxy.cn/rustup}")
docker_build_args+=("--build-arg" "CARGO_INDEX_CN=${CARGO_INDEX_CN:-https://rsproxy.cn/crates.io-index}")
docker_build_args+=("--build-arg" "CARGO_REGISTRY_CN=${CARGO_REGISTRY_CN:-sparse+https://rsproxy.cn/index/}")
docker_build_args+=("--build-arg" "MAVEN_REPOSITORY_CN=${MAVEN_REPOSITORY_CN:-https://maven.aliyun.com/repository/public}")
docker_build_args+=("--build-arg" "GOOGLE_MAVEN_REPOSITORY_CN=${GOOGLE_MAVEN_REPOSITORY_CN:-https://maven.aliyun.com/repository/google}")
docker_build_args+=("--build-arg" "GRADLE_PLUGIN_REPOSITORY_CN=${GRADLE_PLUGIN_REPOSITORY_CN:-https://maven.aliyun.com/repository/gradle-plugin}")
docker_build_args+=("--build-arg" "GRADLE_DISTRIBUTION_URL_CN=$gradle_distribution_url_cn")
if [[ -z "$gradle_distribution_url" ]]; then
gradle_distribution_url="$gradle_distribution_url_cn"
fi
@@ -55,16 +48,12 @@ build_android() {
"$PROJECT_ROOT/build/cross"
fi
add_cache_mount "$gradle_cache" "/root/.gradle"
add_cache_mount "$cargo_registry_cache" "/root/.cargo/registry"
add_cache_mount "$cargo_git_cache" "/root/.cargo/git"
echo "=== Building Android APK: $arch ==="
docker run --rm \
-v "$PROJECT_ROOT:/workspace" \
"${docker_mount_args[@]}" \
-w /workspace \
-e "CHINAMIRRO=${CHINAMIRRO:-0}" \
-e "GH_PROXY=${GH_PROXY:-https://gh-proxy.com}" \
-e "ONE_KVM_GRADLE_DISTRIBUTION_URL=$gradle_distribution_url" \
-e "ONE_KVM_GRADLE_DISTRIBUTION_URL_CN=$gradle_distribution_url_cn" \
-e "ONE_KVM_GRADLE_NETWORK_TIMEOUT=$gradle_network_timeout" \
@@ -102,9 +91,6 @@ Examples:
CHINAMIRRO=1 ONE_KVM_GRADLE_DISTRIBUTION_URL=https://mirrors.aliyun.com/macports/distfiles/gradle/gradle-9.1.0-bin.zip build/build-android.sh all
Environment:
ONE_KVM_ANDROID_GRADLE_CACHE_DIR Host Gradle cache path or Docker volume name
ONE_KVM_ANDROID_CARGO_REGISTRY_CACHE_DIR Host Cargo registry cache path or Docker volume name
ONE_KVM_ANDROID_CARGO_GIT_CACHE_DIR Host Cargo git cache path or Docker volume name
ONE_KVM_ANDROID_SKIP_DOCKER_BUILD=1 Reuse an already loaded Docker image
APK output:

View File

@@ -21,16 +21,21 @@ build_arch() {
case "${CHINAMIRRO:-}" in
1|true|TRUE|yes|YES|on|ON)
local cross_build_opts="${CROSS_BUILD_OPTS:+$CROSS_BUILD_OPTS }--build-arg CHINAMIRRO=1"
echo "=== China mirror acceleration: enabled (Tsinghua) ==="
local cross_build_opts="${CROSS_BUILD_OPTS:+$CROSS_BUILD_OPTS }--progress=plain --build-arg CHINAMIRRO=1 --build-arg GH_PROXY=${GH_PROXY:-https://gh-proxy.com/} --build-arg DEBIAN_IMAGE=${DEBIAN_IMAGE:-docker.1ms.run/library/debian:11}"
cross_build_opts="$cross_build_opts --build-arg HTTP_PROXY= --build-arg HTTPS_PROXY= --build-arg ALL_PROXY= --build-arg NO_PROXY="
cross_build_opts="$cross_build_opts --build-arg http_proxy= --build-arg https_proxy= --build-arg all_proxy= --build-arg no_proxy="
echo "=== China mirror acceleration: enabled ==="
echo "=== Building: $rust_target (via cross with custom Dockerfile) ==="
env \
CROSS_BUILD_OPTS="$cross_build_opts" \
CARGO_SOURCE_CRATES_IO_REPLACE_WITH=tuna \
CARGO_SOURCE_TUNA_REGISTRY=sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/ \
CARGO_SOURCE_CRATES_IO_REPLACE_WITH=rsproxy-sparse \
CARGO_SOURCE_RSPROXY_REGISTRY=https://rsproxy.cn/crates.io-index \
CARGO_SOURCE_RSPROXY_SPARSE_REGISTRY=sparse+https://rsproxy.cn/index/ \
CARGO_REGISTRIES_RSPROXY_INDEX=https://rsproxy.cn/crates.io-index \
CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse \
RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup \
RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup \
CARGO_NET_GIT_FETCH_WITH_CLI=true \
RUSTUP_DIST_SERVER=https://rsproxy.cn \
RUSTUP_UPDATE_ROOT=https://rsproxy.cn/rustup \
cross build --release --target "$rust_target"
return
;;
@@ -66,7 +71,7 @@ case "${1:-all}" in
echo "Examples:"
echo " $0 # Build all"
echo " $0 x86_64 # Build x86_64 only"
echo " CHINAMIRRO=1 $0 arm64 # Build with Tsinghua mirrors"
echo " CHINAMIRRO=1 $0 arm64 # Build with China mirrors"
exit 0
;;
*)
@@ -83,16 +88,4 @@ for target in "${ARCH_MAP[@]}"; do
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,8 @@
# Android build image for One-KVM
# Based on Debian 11 for stable toolchain/runtime compatibility
FROM debian:11
ARG DEBIAN_IMAGE=debian:11
FROM ${DEBIAN_IMAGE}
ARG CHINAMIRRO=0
ARG ANDROID_SDK_ROOT=/root/android-sdk
@@ -10,11 +11,13 @@ ARG ANDROID_NDK_VERSION=27.3.13750724
ARG ANDROID_PLATFORM=36
ARG ANDROID_BUILD_TOOLS=36.0.0
ARG CARGO_NDK_VERSION=4.1.2
ARG RUSTUP_DIST_SERVER_CN=https://mirrors.tuna.tsinghua.edu.cn/rustup
ARG RUSTUP_UPDATE_ROOT_CN=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup
ARG CARGO_REGISTRY_CN=sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/
ARG RUSTUP_DIST_SERVER_CN=https://rsproxy.cn
ARG RUSTUP_UPDATE_ROOT_CN=https://rsproxy.cn/rustup
ARG CARGO_INDEX_CN=https://rsproxy.cn/crates.io-index
ARG CARGO_REGISTRY_CN=sparse+https://rsproxy.cn/index/
ARG MAVEN_REPOSITORY_CN=https://maven.aliyun.com/repository/public
ARG GOOGLE_MAVEN_REPOSITORY_CN=https://maven.aliyun.com/repository/google
ARG GRADLE_PLUGIN_REPOSITORY_CN=https://maven.aliyun.com/repository/gradle-plugin
ARG GRADLE_DISTRIBUTION_URL_CN=https://mirrors.cloud.tencent.com/gradle/gradle-9.1.0-bin.zip
ARG ANDROID_CMDLINE_TOOLS_URL=
@@ -29,9 +32,8 @@ ENV PATH=/root/.cargo/bin:${PATH}
ENV ONE_KVM_GRADLE_DISTRIBUTION_URL_CN=${GRADLE_DISTRIBUTION_URL_CN}
RUN if [ "$CHINAMIRRO" = "1" ]; then \
sed -i \
-e 's|http://deb.debian.org/debian|http://mirrors.tuna.tsinghua.edu.cn/debian|g' \
-e 's|http://security.debian.org/debian-security|http://mirrors.tuna.tsinghua.edu.cn/debian-security|g' \
sed -i -E \
-e 's|http://deb.debian.org/debian([[:space:]])|http://mirrors.tuna.tsinghua.edu.cn/debian\1|g' \
/etc/apt/sources.list; \
fi
@@ -39,6 +41,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
wget \
bzip2 \
unzip \
zip \
git \
@@ -63,11 +66,15 @@ RUN if [ "$CHINAMIRRO" = "1" ]; then \
mkdir -p /root/.cargo; \
printf '%s\n' \
'[source.crates-io]' \
"replace-with = 'tuna'" \
'[source.tuna]' \
"replace-with = 'rsproxy-sparse'" \
'[source.rsproxy]' \
"registry = '${CARGO_INDEX_CN}'" \
'[source.rsproxy-sparse]' \
"registry = '${CARGO_REGISTRY_CN}'" \
'[registries.tuna]' \
"index = '${CARGO_REGISTRY_CN}'" \
'[registries.rsproxy]' \
"index = '${CARGO_INDEX_CN}'" \
'[net]' \
'git-fetch-with-cli = true' \
> /root/.cargo/config.toml; \
fi \
&& curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable \
@@ -102,6 +109,7 @@ RUN if [ "$CHINAMIRRO" = "1" ]; then \
"beforeSettings { settings ->" \
" settings.pluginManagement.repositories.maven { url = uri('${GOOGLE_MAVEN_REPOSITORY_CN}') }" \
" settings.pluginManagement.repositories.maven { url = uri('${MAVEN_REPOSITORY_CN}') }" \
" settings.pluginManagement.repositories.maven { url = uri('${GRADLE_PLUGIN_REPOSITORY_CN}') }" \
" settings.dependencyResolutionManagement.repositories.maven { url = uri('${GOOGLE_MAVEN_REPOSITORY_CN}') }" \
" settings.dependencyResolutionManagement.repositories.maven { url = uri('${MAVEN_REPOSITORY_CN}') }" \
"}" \
@@ -238,7 +246,9 @@ RUN printf '%s\n' \
' '"'"' "$WRAPPER_PROPERTIES" > "$WRAPPER_PROPERTIES_TMP"' \
' cp "$WRAPPER_PROPERTIES_TMP" "$WRAPPER_PROPERTIES"' \
' rm -f "$WRAPPER_PROPERTIES_TMP"' \
' find /root/.gradle/wrapper/dists -name "*.lck" -o -name "*.part" 2>/dev/null | xargs -r rm -f' \
' if [[ -d /root/.gradle/wrapper/dists ]]; then' \
' find /root/.gradle/wrapper/dists \( -name "*.lck" -o -name "*.part" \) -print0 | xargs -0 -r rm -f' \
' fi' \
'fi' \
'' \
'ensure_keystore' \

View File

@@ -1,19 +1,26 @@
# Cross-compilation image for ARM64 based on Debian 11
# Build on Debian 11 (GLIBC 2.31) for maximum runtime compatibility
FROM debian:11
ARG DEBIAN_IMAGE=debian:11
FROM ${DEBIAN_IMAGE}
# Linux headers used by v4l2r bindgen
ARG LINUX_HEADERS_VERSION=6.6
ARG LINUX_HEADERS_SHA256=
ARG CHINAMIRRO=0
ARG GH_PROXY=https://gh-proxy.com/
ARG RUSTUP_DIST_SERVER_CN=https://rsproxy.cn
ARG RUSTUP_UPDATE_ROOT_CN=https://rsproxy.cn/rustup
ARG CARGO_INDEX_CN=https://rsproxy.cn/crates.io-index
ARG CARGO_REGISTRY_CN=sparse+https://rsproxy.cn/index/
ARG LIBJPEG_TURBO_VERSION=3.1.4.1
ARG LIBYUV_REV=957f295ea946cbbd13fcfc46e7066f2efa801233
ARG LIBVPX_VERSION=1.16.0
ARG X265_VERSION=3.4
ARG OPUS_VERSION=1.5.2
ARG FFMPEG_ROCKCHIP_REV=40c412daccf08164493da0de990eb99a8948116b
# Optionally use Tsinghua mirrors for builds in China.
# Optionally use China mirrors for builds in China.
RUN if [ "$CHINAMIRRO" = "1" ]; then \
sed -i \
-e 's|http://deb.debian.org/debian|http://mirrors.tuna.tsinghua.edu.cn/debian|g' \
-e 's|http://security.debian.org/debian-security|http://mirrors.tuna.tsinghua.edu.cn/debian-security|g' \
sed -i -E \
-e 's|http://deb.debian.org/debian([[:space:]])|http://mirrors.tuna.tsinghua.edu.cn/debian\1|g' \
/etc/apt/sources.list; \
fi
@@ -22,19 +29,23 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ca-certificates \
&& if [ "$CHINAMIRRO" = "1" ]; then \
export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup; \
export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup; \
export RUSTUP_DIST_SERVER=${RUSTUP_DIST_SERVER_CN}; \
export RUSTUP_UPDATE_ROOT=${RUSTUP_UPDATE_ROOT_CN}; \
fi \
&& curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable \
&& if [ "$CHINAMIRRO" = "1" ]; then \
mkdir -p /root/.cargo; \
printf '%s\n' \
'[source.crates-io]' \
"replace-with = 'tuna'" \
'[source.tuna]' \
'registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"' \
'[registries.tuna]' \
'index = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"' \
"replace-with = 'rsproxy-sparse'" \
'[source.rsproxy]' \
"registry = '${CARGO_INDEX_CN}'" \
'[source.rsproxy-sparse]' \
"registry = '${CARGO_REGISTRY_CN}'" \
'[registries.rsproxy]' \
"index = '${CARGO_INDEX_CN}'" \
'[net]' \
'git-fetch-with-cli = true' \
> /root/.cargo/config.toml; \
fi \
&& rm -rf /var/lib/apt/lists/*
@@ -70,6 +81,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
# Install ARM64 development libraries (without VAAPI/X11 for ARM)
RUN apt-get update && apt-get install -y --no-install-recommends \
libssl1.1 \
libssl1.1:arm64 \
libasound2-dev:arm64 \
libv4l-dev:arm64 \
libudev-dev:arm64 \
@@ -79,20 +92,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libdrm-dev:arm64 \
&& rm -rf /var/lib/apt/lists/*
# Install newer V4L2 headers for v4l2r bindgen
RUN mkdir -p /opt/v4l2-headers \
&& wget -q https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${LINUX_HEADERS_VERSION}.tar.xz -O /tmp/linux-headers.tar.xz \
&& if [ -n "$LINUX_HEADERS_SHA256" ]; then echo "$LINUX_HEADERS_SHA256 /tmp/linux-headers.tar.xz" | sha256sum -c -; fi \
&& tar -xf /tmp/linux-headers.tar.xz -C /tmp \
&& cd /tmp/linux-${LINUX_HEADERS_VERSION} \
&& make ARCH=arm64 headers_install INSTALL_HDR_PATH=/opt/v4l2-headers \
&& rm -rf /tmp/linux-${LINUX_HEADERS_VERSION} /tmp/linux-headers.tar.xz
ENV V4L2R_VIDEODEV2_H_PATH=/opt/v4l2-headers/include
# 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 \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git init /tmp/libjpeg-turbo \
&& cd /tmp/libjpeg-turbo \
&& git remote add origin "${github_prefix}https://github.com/libjpeg-turbo/libjpeg-turbo.git" \
&& git fetch --depth 1 origin "refs/tags/${LIBJPEG_TURBO_VERSION}" \
&& git checkout --detach FETCH_HEAD \
&& mkdir build && cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX=/usr/aarch64-linux-gnu \
@@ -108,7 +115,9 @@ RUN git clone --depth 1 https://github.com/libjpeg-turbo/libjpeg-turbo /tmp/libj
# Build static libyuv from source (cross-compile for ARM64)
RUN git init /tmp/libyuv \
&& cd /tmp/libyuv \
&& git remote add origin https://github.com/lemenkov/libyuv \
&& github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git remote add origin "${github_prefix}https://github.com/lemenkov/libyuv" \
&& git fetch --depth 1 origin ${LIBYUV_REV} \
&& git checkout --detach FETCH_HEAD \
&& mkdir build && cd build \
@@ -129,8 +138,13 @@ RUN git init /tmp/libyuv \
# Build static libvpx from source (cross-compile for ARM64)
# CC/CXX/LD/AR must be environment variables, not configure arguments
RUN git clone --depth 1 https://github.com/webmproject/libvpx /tmp/libvpx \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git init /tmp/libvpx \
&& cd /tmp/libvpx \
&& git remote add origin "${github_prefix}https://github.com/webmproject/libvpx.git" \
&& git fetch --depth 1 origin "refs/tags/v${LIBVPX_VERSION}" \
&& git checkout --detach FETCH_HEAD \
&& echo "=== libvpx: Configuring for ARM64 ===" \
&& export CC=aarch64-linux-gnu-gcc \
&& export CXX=aarch64-linux-gnu-g++ \
@@ -153,7 +167,9 @@ RUN git clone --depth 1 https://github.com/webmproject/libvpx /tmp/libvpx \
&& 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 \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git clone --depth 1 "${github_prefix}https://github.com/mirror/x264.git" /tmp/x264 \
&& cd /tmp/x264 \
&& export CC=aarch64-linux-gnu-gcc \
&& export AR=aarch64-linux-gnu-ar \
@@ -169,12 +185,18 @@ RUN git clone --depth 1 https://code.videolan.org/videolan/x264.git /tmp/x264 \
&& 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 \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git init /tmp/x265 \
&& cd /tmp/x265 \
&& git remote add origin "${github_prefix}https://github.com/videolan/x265.git" \
&& git fetch --depth 1 origin "refs/tags/${X265_VERSION}" \
&& git checkout --detach FETCH_HEAD \
&& cd source \
&& mkdir -p build \
&& cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_ASM_NASM_FLAGS="-w-macro-params-legacy" \
-DCMAKE_INSTALL_PREFIX=/usr/aarch64-linux-gnu \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
@@ -208,12 +230,15 @@ 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 \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& wget -O /tmp/opus.tar.gz "${github_prefix}https://github.com/xiph/opus/releases/download/v${OPUS_VERSION}/opus-${OPUS_VERSION}.tar.gz" \
&& tar -xzf /tmp/opus.tar.gz -C /tmp \
&& mv "/tmp/opus-${OPUS_VERSION}" /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 \
--prefix=/usr/aarch64-linux-gnu \
--host=aarch64-linux-gnu \
@@ -221,13 +246,20 @@ RUN git clone --depth 1 https://github.com/xiph/opus /tmp/opus \
--disable-doc \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/opus
&& rm -rf /tmp/opus /tmp/opus.tar.gz
# 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 \
&& tar -xzf ffmpeg.tar.gz \
&& cd ffmpeg \
&& github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git clone --depth 1 "https://gitee.com/nyanmisaka/mpp.git" rkmpp \
&& git clone --depth 1 "https://gitee.com/nyanmisaka/rga.git" rkrga \
&& git init ffmpeg-rockchip \
&& cd ffmpeg-rockchip \
&& git remote add origin "${github_prefix}https://github.com/nyanmisaka/ffmpeg-rockchip.git" \
&& git fetch --depth 1 origin ${FFMPEG_ROCKCHIP_REV} \
&& git checkout --detach FETCH_HEAD \
&& cd .. \
# Build RKMPP
&& mkdir -p rkmpp/build && cd rkmpp/build \
&& cmake .. \
@@ -358,8 +390,8 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
# Add Rust target
RUN if [ "$CHINAMIRRO" = "1" ]; then \
export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup; \
export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup; \
export RUSTUP_DIST_SERVER=${RUSTUP_DIST_SERVER_CN}; \
export RUSTUP_UPDATE_ROOT=${RUSTUP_UPDATE_ROOT_CN}; \
fi \
&& rustup target add aarch64-unknown-linux-gnu

View File

@@ -1,19 +1,26 @@
# Cross-compilation image for ARMv7 based on Debian 11
# Build on Debian 11 (GLIBC 2.31) for maximum runtime compatibility
FROM debian:11
ARG DEBIAN_IMAGE=debian:11
FROM ${DEBIAN_IMAGE}
# Linux headers used by v4l2r bindgen
ARG LINUX_HEADERS_VERSION=6.6
ARG LINUX_HEADERS_SHA256=
ARG CHINAMIRRO=0
ARG GH_PROXY=https://gh-proxy.com/
ARG RUSTUP_DIST_SERVER_CN=https://rsproxy.cn
ARG RUSTUP_UPDATE_ROOT_CN=https://rsproxy.cn/rustup
ARG CARGO_INDEX_CN=https://rsproxy.cn/crates.io-index
ARG CARGO_REGISTRY_CN=sparse+https://rsproxy.cn/index/
ARG LIBJPEG_TURBO_VERSION=3.1.4.1
ARG LIBYUV_REV=957f295ea946cbbd13fcfc46e7066f2efa801233
ARG LIBVPX_VERSION=1.16.0
ARG X265_VERSION=3.4
ARG OPUS_VERSION=1.5.2
ARG FFMPEG_ROCKCHIP_REV=40c412daccf08164493da0de990eb99a8948116b
# Optionally use Tsinghua mirrors for builds in China.
# Optionally use China mirrors for builds in China.
RUN if [ "$CHINAMIRRO" = "1" ]; then \
sed -i \
-e 's|http://deb.debian.org/debian|http://mirrors.tuna.tsinghua.edu.cn/debian|g' \
-e 's|http://security.debian.org/debian-security|http://mirrors.tuna.tsinghua.edu.cn/debian-security|g' \
sed -i -E \
-e 's|http://deb.debian.org/debian([[:space:]])|http://mirrors.tuna.tsinghua.edu.cn/debian\1|g' \
/etc/apt/sources.list; \
fi
@@ -22,19 +29,23 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ca-certificates \
&& if [ "$CHINAMIRRO" = "1" ]; then \
export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup; \
export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup; \
export RUSTUP_DIST_SERVER=${RUSTUP_DIST_SERVER_CN}; \
export RUSTUP_UPDATE_ROOT=${RUSTUP_UPDATE_ROOT_CN}; \
fi \
&& curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable \
&& if [ "$CHINAMIRRO" = "1" ]; then \
mkdir -p /root/.cargo; \
printf '%s\n' \
'[source.crates-io]' \
"replace-with = 'tuna'" \
'[source.tuna]' \
'registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"' \
'[registries.tuna]' \
'index = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"' \
"replace-with = 'rsproxy-sparse'" \
'[source.rsproxy]' \
"registry = '${CARGO_INDEX_CN}'" \
'[source.rsproxy-sparse]' \
"registry = '${CARGO_REGISTRY_CN}'" \
'[registries.rsproxy]' \
"index = '${CARGO_INDEX_CN}'" \
'[net]' \
'git-fetch-with-cli = true' \
> /root/.cargo/config.toml; \
fi \
&& rm -rf /var/lib/apt/lists/*
@@ -70,6 +81,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
# Install ARMv7 development libraries (without VAAPI/X11 for ARM)
RUN apt-get update && apt-get install -y --no-install-recommends \
libssl1.1 \
libssl1.1:armhf \
libasound2-dev:armhf \
libv4l-dev:armhf \
libudev-dev:armhf \
@@ -78,20 +91,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libdrm-dev:armhf \
&& rm -rf /var/lib/apt/lists/*
# Install newer V4L2 headers for v4l2r bindgen
RUN mkdir -p /opt/v4l2-headers \
&& wget -q https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${LINUX_HEADERS_VERSION}.tar.xz -O /tmp/linux-headers.tar.xz \
&& if [ -n "$LINUX_HEADERS_SHA256" ]; then echo "$LINUX_HEADERS_SHA256 /tmp/linux-headers.tar.xz" | sha256sum -c -; fi \
&& tar -xf /tmp/linux-headers.tar.xz -C /tmp \
&& cd /tmp/linux-${LINUX_HEADERS_VERSION} \
&& make ARCH=arm headers_install INSTALL_HDR_PATH=/opt/v4l2-headers \
&& rm -rf /tmp/linux-${LINUX_HEADERS_VERSION} /tmp/linux-headers.tar.xz
ENV V4L2R_VIDEODEV2_H_PATH=/opt/v4l2-headers/include
# 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 \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git init /tmp/libjpeg-turbo \
&& cd /tmp/libjpeg-turbo \
&& git remote add origin "${github_prefix}https://github.com/libjpeg-turbo/libjpeg-turbo.git" \
&& git fetch --depth 1 origin "refs/tags/${LIBJPEG_TURBO_VERSION}" \
&& git checkout --detach FETCH_HEAD \
&& mkdir build && cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX=/usr/arm-linux-gnueabihf \
@@ -107,7 +114,9 @@ RUN git clone --depth 1 https://github.com/libjpeg-turbo/libjpeg-turbo /tmp/libj
# Build static libyuv from source (cross-compile for ARMv7)
RUN git init /tmp/libyuv \
&& cd /tmp/libyuv \
&& git remote add origin https://github.com/lemenkov/libyuv \
&& github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git remote add origin "${github_prefix}https://github.com/lemenkov/libyuv" \
&& git fetch --depth 1 origin ${LIBYUV_REV} \
&& git checkout --detach FETCH_HEAD \
&& mkdir build && cd build \
@@ -127,8 +136,13 @@ RUN git init /tmp/libyuv \
&& rm -rf /tmp/libyuv
# Build static libvpx from source (cross-compile for ARMv7)
RUN git clone --depth 1 https://github.com/webmproject/libvpx /tmp/libvpx \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git init /tmp/libvpx \
&& cd /tmp/libvpx \
&& git remote add origin "${github_prefix}https://github.com/webmproject/libvpx.git" \
&& git fetch --depth 1 origin "refs/tags/v${LIBVPX_VERSION}" \
&& git checkout --detach FETCH_HEAD \
&& export CC=arm-linux-gnueabihf-gcc \
&& export CXX=arm-linux-gnueabihf-g++ \
&& export LD=arm-linux-gnueabihf-ld \
@@ -145,7 +159,9 @@ RUN git clone --depth 1 https://github.com/webmproject/libvpx /tmp/libvpx \
&& 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 \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git clone --depth 1 "${github_prefix}https://github.com/mirror/x264.git" /tmp/x264 \
&& cd /tmp/x264 \
&& export CC=arm-linux-gnueabihf-gcc \
&& export AR=arm-linux-gnueabihf-ar \
@@ -162,12 +178,18 @@ RUN git clone --depth 1 https://code.videolan.org/videolan/x264.git /tmp/x264 \
&& 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 \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git init /tmp/x265 \
&& cd /tmp/x265 \
&& git remote add origin "${github_prefix}https://github.com/videolan/x265.git" \
&& git fetch --depth 1 origin "refs/tags/${X265_VERSION}" \
&& git checkout --detach FETCH_HEAD \
&& cd source \
&& mkdir -p build \
&& cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_ASM_NASM_FLAGS="-w-macro-params-legacy" \
-DCMAKE_INSTALL_PREFIX=/usr/arm-linux-gnueabihf \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=arm \
@@ -197,12 +219,15 @@ 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 \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& wget -O /tmp/opus.tar.gz "${github_prefix}https://github.com/xiph/opus/releases/download/v${OPUS_VERSION}/opus-${OPUS_VERSION}.tar.gz" \
&& tar -xzf /tmp/opus.tar.gz -C /tmp \
&& mv "/tmp/opus-${OPUS_VERSION}" /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 \
--prefix=/usr/arm-linux-gnueabihf \
--host=arm-linux-gnueabihf \
@@ -210,13 +235,20 @@ RUN git clone --depth 1 https://github.com/xiph/opus /tmp/opus \
--disable-doc \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/opus
&& rm -rf /tmp/opus /tmp/opus.tar.gz
# 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 \
&& tar -xzf ffmpeg.tar.gz \
&& cd ffmpeg \
&& github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git clone --depth 1 "https://gitee.com/nyanmisaka/mpp.git" rkmpp \
&& git clone --depth 1 "https://gitee.com/nyanmisaka/rga.git" rkrga \
&& git init ffmpeg-rockchip \
&& cd ffmpeg-rockchip \
&& git remote add origin "${github_prefix}https://github.com/nyanmisaka/ffmpeg-rockchip.git" \
&& git fetch --depth 1 origin ${FFMPEG_ROCKCHIP_REV} \
&& git checkout --detach FETCH_HEAD \
&& cd .. \
# Build RKMPP
&& mkdir -p rkmpp/build && cd rkmpp/build \
&& cmake .. \
@@ -347,8 +379,8 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
# Add Rust target
RUN if [ "$CHINAMIRRO" = "1" ]; then \
export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup; \
export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup; \
export RUSTUP_DIST_SERVER=${RUSTUP_DIST_SERVER_CN}; \
export RUSTUP_UPDATE_ROOT=${RUSTUP_UPDATE_ROOT_CN}; \
fi \
&& rustup target add armv7-unknown-linux-gnueabihf

View File

@@ -1,19 +1,26 @@
# Cross-compilation image for x86_64 based on Debian 11
# Build on Debian 11 (GLIBC 2.31) for maximum runtime compatibility
FROM debian:11
ARG DEBIAN_IMAGE=debian:11
FROM ${DEBIAN_IMAGE}
# Linux headers used by v4l2r bindgen
ARG LINUX_HEADERS_VERSION=6.6
ARG LINUX_HEADERS_SHA256=
ARG CHINAMIRRO=0
ARG GH_PROXY=https://gh-proxy.com/
ARG RUSTUP_DIST_SERVER_CN=https://rsproxy.cn
ARG RUSTUP_UPDATE_ROOT_CN=https://rsproxy.cn/rustup
ARG CARGO_INDEX_CN=https://rsproxy.cn/crates.io-index
ARG CARGO_REGISTRY_CN=sparse+https://rsproxy.cn/index/
ARG LIBJPEG_TURBO_VERSION=3.1.4.1
ARG LIBYUV_REV=957f295ea946cbbd13fcfc46e7066f2efa801233
ARG LIBVPX_VERSION=1.16.0
ARG X265_VERSION=3.4
ARG OPUS_VERSION=1.5.2
ARG FFMPEG_ROCKCHIP_REV=40c412daccf08164493da0de990eb99a8948116b
# Optionally use Tsinghua mirrors for builds in China.
# Optionally use China mirrors for builds in China.
RUN if [ "$CHINAMIRRO" = "1" ]; then \
sed -i \
-e 's|http://deb.debian.org/debian|http://mirrors.tuna.tsinghua.edu.cn/debian|g' \
-e 's|http://security.debian.org/debian-security|http://mirrors.tuna.tsinghua.edu.cn/debian-security|g' \
sed -i -E \
-e 's|http://deb.debian.org/debian([[:space:]])|http://mirrors.tuna.tsinghua.edu.cn/debian\1|g' \
/etc/apt/sources.list; \
fi
@@ -22,19 +29,23 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ca-certificates \
&& if [ "$CHINAMIRRO" = "1" ]; then \
export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup; \
export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup; \
export RUSTUP_DIST_SERVER=${RUSTUP_DIST_SERVER_CN}; \
export RUSTUP_UPDATE_ROOT=${RUSTUP_UPDATE_ROOT_CN}; \
fi \
&& curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable \
&& if [ "$CHINAMIRRO" = "1" ]; then \
mkdir -p /root/.cargo; \
printf '%s\n' \
'[source.crates-io]' \
"replace-with = 'tuna'" \
'[source.tuna]' \
'registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"' \
'[registries.tuna]' \
'index = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"' \
"replace-with = 'rsproxy-sparse'" \
'[source.rsproxy]' \
"registry = '${CARGO_INDEX_CN}'" \
'[source.rsproxy-sparse]' \
"registry = '${CARGO_REGISTRY_CN}'" \
'[registries.rsproxy]' \
"index = '${CARGO_INDEX_CN}'" \
'[net]' \
'git-fetch-with-cli = true' \
> /root/.cargo/config.toml; \
fi \
&& rm -rf /var/lib/apt/lists/*
@@ -77,20 +88,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libxdmcp-dev \
&& rm -rf /var/lib/apt/lists/*
# Install newer V4L2 headers for v4l2r bindgen
RUN mkdir -p /opt/v4l2-headers \
&& wget -q https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${LINUX_HEADERS_VERSION}.tar.xz -O /tmp/linux-headers.tar.xz \
&& if [ -n "$LINUX_HEADERS_SHA256" ]; then echo "$LINUX_HEADERS_SHA256 /tmp/linux-headers.tar.xz" | sha256sum -c -; fi \
&& tar -xf /tmp/linux-headers.tar.xz -C /tmp \
&& cd /tmp/linux-${LINUX_HEADERS_VERSION} \
&& make ARCH=x86 headers_install INSTALL_HDR_PATH=/opt/v4l2-headers \
&& rm -rf /tmp/linux-${LINUX_HEADERS_VERSION} /tmp/linux-headers.tar.xz
ENV V4L2R_VIDEODEV2_H_PATH=/opt/v4l2-headers/include
# Build static libjpeg-turbo from source (needed by libyuv)
RUN git clone --depth 1 https://github.com/libjpeg-turbo/libjpeg-turbo /tmp/libjpeg-turbo \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git init /tmp/libjpeg-turbo \
&& cd /tmp/libjpeg-turbo \
&& git remote add origin "${github_prefix}https://github.com/libjpeg-turbo/libjpeg-turbo.git" \
&& git fetch --depth 1 origin "refs/tags/${LIBJPEG_TURBO_VERSION}" \
&& git checkout --detach FETCH_HEAD \
&& mkdir build && cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX=/usr/local \
@@ -103,7 +108,9 @@ RUN git clone --depth 1 https://github.com/libjpeg-turbo/libjpeg-turbo /tmp/libj
# Build static libyuv from source (uses libjpeg-turbo headers)
RUN git init /tmp/libyuv \
&& cd /tmp/libyuv \
&& git remote add origin https://github.com/lemenkov/libyuv \
&& github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git remote add origin "${github_prefix}https://github.com/lemenkov/libyuv" \
&& git fetch --depth 1 origin ${LIBYUV_REV} \
&& git checkout --detach FETCH_HEAD \
&& mkdir build && cd build \
@@ -118,17 +125,25 @@ RUN git init /tmp/libyuv \
&& rm -rf /tmp/libyuv
# Build static libvpx from source
RUN git clone --depth 1 https://github.com/webmproject/libvpx /tmp/libvpx \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git init /tmp/libvpx \
&& cd /tmp/libvpx \
&& git remote add origin "${github_prefix}https://github.com/webmproject/libvpx.git" \
&& git fetch --depth 1 origin "refs/tags/v${LIBVPX_VERSION}" \
&& git checkout --detach FETCH_HEAD \
&& ./configure \
--enable-static --disable-shared --enable-pic \
--disable-examples --disable-tools --disable-docs \
--disable-unit-tests \
&& 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 \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git clone --depth 1 "${github_prefix}https://github.com/mirror/x264.git" /tmp/x264 \
&& cd /tmp/x264 \
&& ./configure --enable-static --disable-cli \
&& make -j$(nproc) \
@@ -136,12 +151,18 @@ RUN git clone --depth 1 https://code.videolan.org/videolan/x264.git /tmp/x264 \
&& rm -rf /tmp/x264
# Build static libx265 from source
RUN git clone --depth 1 https://bitbucket.org/multicoreware/x265_git /tmp/x265 \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git init /tmp/x265 \
&& cd /tmp/x265 \
&& git remote add origin "${github_prefix}https://github.com/videolan/x265.git" \
&& git fetch --depth 1 origin "refs/tags/${X265_VERSION}" \
&& git checkout --detach FETCH_HEAD \
&& cd source \
&& mkdir -p build \
&& cd build \
&& cmake .. -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_ASM_NASM_FLAGS="-w-macro-params-legacy" \
-DENABLE_SHARED=OFF \
-DENABLE_CLI=OFF \
-DBUILD_SHARED_LIBS=OFF \
@@ -166,21 +187,28 @@ Cflags: -I\${includedir}
EOF
# Build static libopus from source
RUN git clone --depth 1 https://github.com/xiph/opus /tmp/opus \
RUN github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& wget -O /tmp/opus.tar.gz "${github_prefix}https://github.com/xiph/opus/releases/download/v${OPUS_VERSION}/opus-${OPUS_VERSION}.tar.gz" \
&& tar -xzf /tmp/opus.tar.gz -C /tmp \
&& mv "/tmp/opus-${OPUS_VERSION}" /tmp/opus \
&& cd /tmp/opus \
&& ./autogen.sh \
&& ./configure \
--enable-static --disable-shared \
--disable-doc \
&& make -j$(nproc) \
&& make install \
&& rm -rf /tmp/opus
&& rm -rf /tmp/opus /tmp/opus.tar.gz
# 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 \
&& github_prefix="" \
&& if [ "$CHINAMIRRO" = "1" ]; then github_prefix="${GH_PROXY%/}/"; fi \
&& git init ffmpeg-rockchip \
&& cd ffmpeg-rockchip \
&& git remote add origin "${github_prefix}https://github.com/nyanmisaka/ffmpeg-rockchip.git" \
&& git fetch --depth 1 origin ${FFMPEG_ROCKCHIP_REV} \
&& git checkout --detach FETCH_HEAD \
&& ./configure \
--enable-gpl \
--enable-version3 \
@@ -253,8 +281,8 @@ RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \
# Add Rust target
RUN if [ "$CHINAMIRRO" = "1" ]; then \
export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup; \
export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup; \
export RUSTUP_DIST_SERVER=${RUSTUP_DIST_SERVER_CN}; \
export RUSTUP_UPDATE_ROOT=${RUSTUP_UPDATE_ROOT_CN}; \
fi \
&& rustup target add x86_64-unknown-linux-gnu

View File

@@ -15,9 +15,8 @@ parts are intentionally removed here so this dependency stays scoped to capture.
## Build options
`cargo build` generates V4L2 bindings from `/usr/include/linux/videodev2.h` by
default. Set `V4L2R_VIDEODEV2_H_PATH` to a directory containing `videodev2.h` to
generate bindings from a different header.
`cargo build` generates V4L2 bindings from the vendored Linux UAPI headers in
`include/`.
For Android targets, the build script uses the Android NDK sysroot. Set one of
`ANDROID_NDK_HOME`, `ANDROID_NDK_ROOT`, `NDK_HOME`, `ANDROID_HOME`, or

View File

@@ -1,14 +1,10 @@
use std::env::{self, VarError};
use std::env;
use std::path::PathBuf;
include!("bindgen.rs");
/// Environment variable that can be set to point to the directory containing the `videodev2.h`
/// file to use to generate the bindings.
const V4L2R_VIDEODEV_ENV: &str = "V4L2R_VIDEODEV2_H_PATH";
/// Default header file to parse if the `V4L2R_VIDEODEV2_H_PATH` environment variable is not set.
const DEFAULT_VIDEODEV2_H_PATH: &str = "/usr/include/linux";
/// Vendored Linux UAPI include root used for non-Android targets.
const VENDORED_INCLUDE_DIR: &str = "include";
/// Wrapper file to use as input of bindgen.
const WRAPPER_H: &str = "v4l2r_wrapper.h";
@@ -20,29 +16,14 @@ fn main() {
let target = env::var("TARGET").unwrap_or_default();
let is_android = target.contains("android");
let default_videodev2_h_path = if is_android {
android_sysroot().join("usr/include").display().to_string()
let include_root = if is_android {
android_sysroot().join("usr/include")
} else {
DEFAULT_VIDEODEV2_H_PATH.to_string()
PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("`CARGO_MANIFEST_DIR` is not set"))
.join(VENDORED_INCLUDE_DIR)
};
let videodev2_h = include_root.join("linux/videodev2.h");
let videodev2_h_path = env::var(V4L2R_VIDEODEV_ENV)
.or_else(|e| {
if let VarError::NotPresent = e {
Ok(default_videodev2_h_path.clone())
} else {
Err(e)
}
})
.expect("invalid `V4L2R_VIDEODEV2_H_PATH` environment variable");
let videodev2_h = PathBuf::from(videodev2_h_path.clone()).join(if is_android {
"linux/videodev2.h"
} else {
"videodev2.h"
});
println!("cargo::rerun-if-env-changed={}", V4L2R_VIDEODEV_ENV);
println!("cargo::rerun-if-env-changed=ANDROID_NDK_HOME");
println!("cargo::rerun-if-env-changed=ANDROID_NDK_ROOT");
println!("cargo::rerun-if-env-changed=NDK_HOME");
@@ -54,7 +35,7 @@ fn main() {
println!("cargo::rerun-if-changed={}", WRAPPER_H);
let mut clang_args = vec![
format!("-I{videodev2_h_path}"),
format!("-I{}", include_root.display()),
#[cfg(all(feature = "arch64", not(feature = "arch32")))]
"--target=x86_64-linux-gnu".into(),
#[cfg(all(feature = "arch32", not(feature = "arch64")))]

View File

@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __ASM_GENERIC_BITS_PER_LONG
#define __ASM_GENERIC_BITS_PER_LONG
#ifndef __BITS_PER_LONG
/*
* In order to keep safe and avoid regression, only unify uapi
* bitsperlong.h for some archs which are using newer toolchains
* that have the definitions of __CHAR_BIT__ and __SIZEOF_LONG__.
* See the following link for more info:
* https://lore.kernel.org/linux-arch/b9624545-2c80-49a1-ac3c-39264a591f7b@app.fastmail.com/
*/
#if defined(__CHAR_BIT__) && defined(__SIZEOF_LONG__)
#define __BITS_PER_LONG (__CHAR_BIT__ * __SIZEOF_LONG__)
#else
/*
* There seems to be no way of detecting this automatically from user
* space, so 64 bit architectures should override this in their
* bitsperlong.h. In particular, an architecture that supports
* both 32 and 64 bit user space must not rely on CONFIG_64BIT
* to decide it, but rather check a compiler provided macro.
*/
#define __BITS_PER_LONG 32
#endif
#endif
#ifndef __BITS_PER_LONG_LONG
#define __BITS_PER_LONG_LONG 64
#endif
#endif /* __ASM_GENERIC_BITS_PER_LONG */

View File

@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* asm-generic/int-ll64.h
*
* Integer declarations for architectures which use "long long"
* for 64-bit types.
*/
#ifndef _ASM_GENERIC_INT_LL64_H
#define _ASM_GENERIC_INT_LL64_H
#include <asm/bitsperlong.h>
#ifndef __ASSEMBLY__
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
* header files exported to user space
*/
typedef __signed__ char __s8;
typedef unsigned char __u8;
typedef __signed__ short __s16;
typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
#ifdef __GNUC__
__extension__ typedef __signed__ long long __s64;
__extension__ typedef unsigned long long __u64;
#else
typedef __signed__ long long __s64;
typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
#endif /* _ASM_GENERIC_INT_LL64_H */

View File

@@ -0,0 +1,105 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _ASM_GENERIC_IOCTL_H
#define _ASM_GENERIC_IOCTL_H
/* ioctl command encoding: 32 bits total, command in lower 16 bits,
* size of the parameter structure in the lower 14 bits of the
* upper 16 bits.
* Encoding the size of the parameter structure in the ioctl request
* is useful for catching programs compiled with old versions
* and to avoid overwriting user space outside the user buffer area.
* The highest 2 bits are reserved for indicating the ``access mode''.
* NOTE: This limits the max parameter size to 16kB -1 !
*/
/*
* The following is for compatibility across the various Linux
* platforms. The generic ioctl numbering scheme doesn't really enforce
* a type field. De facto, however, the top 8 bits of the lower 16
* bits are indeed used as a type field, so we might just as well make
* this explicit here. Please be sure to use the decoding macros
* below from now on.
*/
#define _IOC_NRBITS 8
#define _IOC_TYPEBITS 8
/*
* Let any architecture override either of the following before
* including this file.
*/
#ifndef _IOC_SIZEBITS
# define _IOC_SIZEBITS 14
#endif
#ifndef _IOC_DIRBITS
# define _IOC_DIRBITS 2
#endif
#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
#define _IOC_NRSHIFT 0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
/*
* Direction bits, which any architecture can choose to override
* before including this file.
*
* NOTE: _IOC_WRITE means userland is writing and kernel is
* reading. _IOC_READ means userland is reading and kernel is writing.
*/
#ifndef _IOC_NONE
# define _IOC_NONE 0U
#endif
#ifndef _IOC_WRITE
# define _IOC_WRITE 1U
#endif
#ifndef _IOC_READ
# define _IOC_READ 2U
#endif
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
#define _IOC_TYPECHECK(t) (sizeof(t))
/*
* Used to create numbers.
*
* NOTE: _IOW means userland is writing and kernel is reading. _IOR
* means userland is reading and kernel is writing.
*/
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
/* used to decode ioctl numbers.. */
#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
/* ...and for the drivers/sound files... */
#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
#endif /* _ASM_GENERIC_IOCTL_H */

View File

@@ -0,0 +1,99 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __ASM_GENERIC_POSIX_TYPES_H
#define __ASM_GENERIC_POSIX_TYPES_H
#include <asm/bitsperlong.h>
/*
* This file is generally used by user-level software, so you need to
* be a little careful about namespace pollution etc.
*
* First the types that are often defined in different ways across
* architectures, so that you can override them.
*/
#ifndef __kernel_long_t
typedef long __kernel_long_t;
typedef unsigned long __kernel_ulong_t;
#endif
#ifndef __kernel_ino_t
typedef __kernel_ulong_t __kernel_ino_t;
#endif
#ifndef __kernel_mode_t
typedef unsigned int __kernel_mode_t;
#endif
#ifndef __kernel_pid_t
typedef int __kernel_pid_t;
#endif
#ifndef __kernel_ipc_pid_t
typedef int __kernel_ipc_pid_t;
#endif
#ifndef __kernel_uid_t
typedef unsigned int __kernel_uid_t;
typedef unsigned int __kernel_gid_t;
#endif
#ifndef __kernel_suseconds_t
typedef __kernel_long_t __kernel_suseconds_t;
#endif
#ifndef __kernel_daddr_t
typedef int __kernel_daddr_t;
#endif
#ifndef __kernel_uid32_t
typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t;
#endif
#ifndef __kernel_old_uid_t
typedef __kernel_uid_t __kernel_old_uid_t;
typedef __kernel_gid_t __kernel_old_gid_t;
#endif
#ifndef __kernel_old_dev_t
typedef unsigned int __kernel_old_dev_t;
#endif
/*
* Most 32 bit architectures use "unsigned int" size_t,
* and all 64 bit architectures use "unsigned long" size_t.
*/
#ifndef __kernel_size_t
#if __BITS_PER_LONG != 64
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
typedef int __kernel_ptrdiff_t;
#else
typedef __kernel_ulong_t __kernel_size_t;
typedef __kernel_long_t __kernel_ssize_t;
typedef __kernel_long_t __kernel_ptrdiff_t;
#endif
#endif
#ifndef __kernel_fsid_t
typedef struct {
int val[2];
} __kernel_fsid_t;
#endif
/*
* anything below here should be completely generic
*/
typedef __kernel_long_t __kernel_off_t;
typedef long long __kernel_loff_t;
typedef __kernel_long_t __kernel_old_time_t;
typedef __kernel_long_t __kernel_time_t;
typedef long long __kernel_time64_t;
typedef __kernel_long_t __kernel_clock_t;
typedef int __kernel_timer_t;
typedef int __kernel_clockid_t;
typedef char * __kernel_caddr_t;
typedef unsigned short __kernel_uid16_t;
typedef unsigned short __kernel_gid16_t;
#endif /* __ASM_GENERIC_POSIX_TYPES_H */

View File

@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _ASM_GENERIC_TYPES_H
#define _ASM_GENERIC_TYPES_H
/*
* int-ll64 is used everywhere now.
*/
#include <asm-generic/int-ll64.h>
#endif /* _ASM_GENERIC_TYPES_H */

View File

@@ -0,0 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/* const.h: Macros for dealing with constants. */
#ifndef _LINUX_CONST_H
#define _LINUX_CONST_H
/* Some constant macros are used in both assembler and
* C code. Therefore we cannot annotate them always with
* 'UL' and other type specifiers unilaterally. We
* use the following macros to deal with this.
*
* Similarly, _AT() will cast an expression with a type in C, but
* leave it unchanged in asm.
*/
#ifdef __ASSEMBLY__
#define _AC(X,Y) X
#define _AT(T,X) X
#else
#define __AC(X,Y) (X##Y)
#define _AC(X,Y) __AC(X,Y)
#define _AT(T,X) ((T)(X))
#endif
#define _UL(x) (_AC(x, UL))
#define _ULL(x) (_AC(x, ULL))
#define _BITUL(x) (_UL(1) << (x))
#define _BITULL(x) (_ULL(1) << (x))
#if !defined(__ASSEMBLY__)
/*
* Missing __asm__ support
*
* __BIT128() would not work in the __asm__ code, as it shifts an
* 'unsigned __init128' data type as direct representation of
* 128 bit constants is not supported in the gcc compiler, as
* they get silently truncated.
*
* TODO: Please revisit this implementation when gcc compiler
* starts representing 128 bit constants directly like long
* and unsigned long etc. Subsequently drop the comment for
* GENMASK_U128() which would then start supporting __asm__ code.
*/
#define _BIT128(x) ((unsigned __int128)(1) << (x))
#endif
#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1)
#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#endif /* _LINUX_CONST_H */

View File

@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_IOCTL_H
#define _LINUX_IOCTL_H
#include <asm/ioctl.h>
#endif /* _LINUX_IOCTL_H */

View File

@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_POSIX_TYPES_H
#define _LINUX_POSIX_TYPES_H
#include <linux/stddef.h>
/*
* This allows for 1024 file descriptors: if NR_OPEN is ever grown
* beyond that you'll have to change this too. But 1024 fd's seem to be
* enough even for such "real" unices like OSF/1, so hopefully this is
* one limit that doesn't have to be changed [again].
*
* Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in
* <sys/time.h> (and thus <linux/time.h>) - but this is a more logical
* place for them. Solved by having dummy defines in <sys/time.h>.
*/
/*
* This macro may have been defined in <gnu/types.h>. But we always
* use the one here.
*/
#undef __FD_SETSIZE
#define __FD_SETSIZE 1024
typedef struct {
unsigned long fds_bits[__FD_SETSIZE / (8 * sizeof(long))];
} __kernel_fd_set;
/* Type of a signal handler. */
typedef void (*__kernel_sighandler_t)(int);
/* Type of a SYSV IPC key. */
typedef int __kernel_key_t;
typedef int __kernel_mqd_t;
#include <asm/posix_types.h>
#endif /* _LINUX_POSIX_TYPES_H */

View File

@@ -0,0 +1,73 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_STDDEF_H
#define _LINUX_STDDEF_H
#ifndef __always_inline
#define __always_inline __inline__
#endif
/* Not all C++ standards support type declarations inside an anonymous union */
#ifndef __cplusplus
#define __struct_group_tag(TAG) TAG
#else
#define __struct_group_tag(TAG)
#endif
/**
* __struct_group() - Create a mirrored named and anonyomous struct
*
* @TAG: The tag name for the named sub-struct (usually empty)
* @NAME: The identifier name of the mirrored sub-struct
* @ATTRS: Any struct attributes (usually empty)
* @MEMBERS: The member declarations for the mirrored structs
*
* Used to create an anonymous union of two structs with identical layout
* and size: one anonymous and one named. The former's members can be used
* normally without sub-struct naming, and the latter can be used to
* reason about the start, end, and size of the group of struct members.
* The named struct can also be explicitly tagged for layer reuse (C only),
* as well as both having struct attributes appended.
*/
#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
union { \
struct { MEMBERS } ATTRS; \
struct __struct_group_tag(TAG) { MEMBERS } ATTRS NAME; \
} ATTRS
#ifdef __cplusplus
/* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */
#define __DECLARE_FLEX_ARRAY(T, member) \
T member[0]
#else
/**
* __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
*
* @TYPE: The type of each flexible array element
* @NAME: The name of the flexible array member
*
* In order to have a flexible array member in a union or alone in a
* struct, it needs to be wrapped in an anonymous struct with at least 1
* named member, but that member can be empty.
*/
#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
struct { \
struct { } __empty_ ## NAME; \
TYPE NAME[]; \
}
#endif
#ifndef __counted_by
#define __counted_by(m)
#endif
#ifndef __counted_by_le
#define __counted_by_le(m)
#endif
#ifndef __counted_by_be
#define __counted_by_be(m)
#endif
#endif /* _LINUX_STDDEF_H */

View File

@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_TYPES_H
#define _LINUX_TYPES_H
#include <asm/types.h>
#ifndef __ASSEMBLY__
#include <linux/posix_types.h>
#ifdef __SIZEOF_INT128__
typedef __signed__ __int128 __s128 __attribute__((aligned(16)));
typedef unsigned __int128 __u128 __attribute__((aligned(16)));
#endif
/*
* Below are truly Linux-specific types that should never collide with
* any application/library that wants linux/types.h.
*/
/* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
#ifdef __CHECKER__
#define __bitwise __attribute__((bitwise))
#else
#define __bitwise
#endif
/* The kernel doesn't use this legacy form, but user space does */
#define __bitwise__ __bitwise
typedef __u16 __bitwise __le16;
typedef __u16 __bitwise __be16;
typedef __u32 __bitwise __le32;
typedef __u32 __bitwise __be32;
typedef __u64 __bitwise __le64;
typedef __u64 __bitwise __be64;
typedef __u16 __bitwise __sum16;
typedef __u32 __bitwise __wsum;
/*
* aligned_u64 should be used in defining kernel<->userspace ABIs to avoid
* common 32/64-bit compat problems.
* 64-bit values align to 4-byte boundaries on x86_32 (and possibly other
* architectures) and to 8-byte boundaries on 64-bit architectures. The new
* aligned_64 type enforces 8-byte alignment so that structs containing
* aligned_64 values have the same alignment on 32-bit and 64-bit architectures.
* No conversions are necessary between 32-bit user-space and a 64-bit kernel.
*/
#define __aligned_u64 __u64 __attribute__((aligned(8)))
#define __aligned_s64 __s64 __attribute__((aligned(8)))
#define __aligned_be64 __be64 __attribute__((aligned(8)))
#define __aligned_le64 __le64 __attribute__((aligned(8)))
typedef unsigned __bitwise __poll_t;
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_TYPES_H */

View File

@@ -0,0 +1,69 @@
/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
/*
* include/linux/v4l2-common.h
*
* Common V4L2 and V4L2 subdev definitions.
*
* Users are advised to #include this file either through videodev2.h
* (V4L2) or through v4l2-subdev.h (V4L2 subdev) rather than to refer
* to this file directly.
*
* Copyright (C) 2012 Nokia Corporation
* Contact: Sakari Ailus <sakari.ailus@iki.fi>
*/
#ifndef __V4L2_COMMON__
#define __V4L2_COMMON__
#include <linux/types.h>
/*
*
* Selection interface definitions
*
*/
/* Current cropping area */
#define V4L2_SEL_TGT_CROP 0x0000
/* Default cropping area */
#define V4L2_SEL_TGT_CROP_DEFAULT 0x0001
/* Cropping bounds */
#define V4L2_SEL_TGT_CROP_BOUNDS 0x0002
/* Native frame size */
#define V4L2_SEL_TGT_NATIVE_SIZE 0x0003
/* Current composing area */
#define V4L2_SEL_TGT_COMPOSE 0x0100
/* Default composing area */
#define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101
/* Composing bounds */
#define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102
/* Current composing area plus all padding pixels */
#define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103
/* Selection flags */
#define V4L2_SEL_FLAG_GE (1 << 0)
#define V4L2_SEL_FLAG_LE (1 << 1)
#define V4L2_SEL_FLAG_KEEP_CONFIG (1 << 2)
struct v4l2_edid {
__u32 pad;
__u32 start_block;
__u32 blocks;
__u32 reserved[5];
__u8 *edid;
};
/* Backward compatibility target definitions --- to be removed. */
#define V4L2_SEL_TGT_CROP_ACTIVE V4L2_SEL_TGT_CROP
#define V4L2_SEL_TGT_COMPOSE_ACTIVE V4L2_SEL_TGT_COMPOSE
#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL V4L2_SEL_TGT_CROP
#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL V4L2_SEL_TGT_COMPOSE
#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS V4L2_SEL_TGT_CROP_BOUNDS
#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS V4L2_SEL_TGT_COMPOSE_BOUNDS
/* Backward compatibility flag definitions --- to be removed. */
#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE V4L2_SEL_FLAG_GE
#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE V4L2_SEL_FLAG_LE
#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG V4L2_SEL_FLAG_KEEP_CONFIG
#endif /* __V4L2_COMMON__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,13 +5,12 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
SOURCE_DIR=""
OUTPUT_DIR="${PROJECT_ROOT}/dist/android-alsa"
ANDROID_API="${ANDROID_API:-21}"
NDK_ROOT="${ANDROID_NDK_HOME:-${ANDROID_NDK_ROOT:-}}"
BUILD_ABIS="arm64-v8a armeabi-v7a"
JOBS="${JOBS:-$(nproc 2>/dev/null || echo 4)}"
ALSA_REPO="${ALSA_REPO:-https://github.com/alsa-project/alsa-lib.git}"
ALSA_VERSION="${ALSA_VERSION:-1.2.15}"
usage() {
cat <<'EOF'
@@ -19,8 +18,6 @@ Usage:
scripts/build-android-alsa.sh [options]
Options:
--source <dir> Existing alsa-lib source checkout. If omitted, the
script clones it into .tmp/android-alsa-src.
--output <dir> Output root. Default: dist/android-alsa
--ndk <dir> Android NDK root. Defaults to ANDROID_NDK_HOME or ANDROID_NDK_ROOT.
--api <level> Android API level. Default: 21.
@@ -44,10 +41,6 @@ fail() {
while [[ $# -gt 0 ]]; do
case "$1" in
--source)
SOURCE_DIR="${2:-}"
shift 2
;;
--output)
OUTPUT_DIR="${2:-}"
shift 2
@@ -77,16 +70,15 @@ done
[[ -n "$NDK_ROOT" ]] || fail "--ndk or ANDROID_NDK_HOME/ANDROID_NDK_ROOT is required"
[[ -d "$NDK_ROOT/toolchains/llvm/prebuilt" ]] || fail "Invalid NDK root: $NDK_ROOT"
if [[ -z "$SOURCE_DIR" ]]; then
SOURCE_DIR="${PROJECT_ROOT}/.tmp/android-alsa-src"
if [[ ! -d "$SOURCE_DIR/.git" ]]; then
rm -rf "$SOURCE_DIR"
git clone --depth 1 "$ALSA_REPO" "$SOURCE_DIR"
fi
fi
[[ -d "$SOURCE_DIR" ]] || fail "alsa-lib source not found: $SOURCE_DIR"
[[ -f "$SOURCE_DIR/configure.ac" || -f "$SOURCE_DIR/configure" ]] || fail "alsa-lib source layout not recognized under: $SOURCE_DIR"
SOURCE_DIR="${PROJECT_ROOT}/.tmp/android-alsa-src"
rm -rf "$SOURCE_DIR"
mkdir -p "${PROJECT_ROOT}/.tmp"
archive="${PROJECT_ROOT}/.tmp/alsa-lib-${ALSA_VERSION}.tar.bz2"
url="https://www.alsa-project.org/files/pub/lib/alsa-lib-${ALSA_VERSION}.tar.bz2"
echo "Downloading ALSA ${ALSA_VERSION}: $url"
curl -fL "$url" -o "$archive"
tar -xjf "$archive" -C "${PROJECT_ROOT}/.tmp"
mv "${PROJECT_ROOT}/.tmp/alsa-lib-${ALSA_VERSION}" "$SOURCE_DIR"
SOURCE_DIR="$(cd "$SOURCE_DIR" && pwd)"
mkdir -p "$OUTPUT_DIR"
@@ -94,11 +86,6 @@ OUTPUT_DIR="$(cd "$OUTPUT_DIR" && pwd)"
HOST_TAG="$(uname -s | tr '[:upper:]' '[:lower:]')-x86_64"
TOOLCHAIN="${NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_TAG}"
ANDROID_TOOLCHAIN_FILE="${NDK_ROOT}/build/cmake/android.toolchain.cmake"
[[ -d "$TOOLCHAIN/bin" ]] || fail "NDK LLVM toolchain not found: $TOOLCHAIN"
[[ -f "$ANDROID_TOOLCHAIN_FILE" ]] || fail "NDK CMake toolchain not found: $ANDROID_TOOLCHAIN_FILE"
command -v cmake >/dev/null 2>&1 || fail "cmake is required"
command -v autoreconf >/dev/null 2>&1 || fail "autoreconf is required"
normalize_abis() {
printf '%s\n' "$BUILD_ABIS" | tr ',' ' '
@@ -147,14 +134,6 @@ build_one() {
clean_generated_source_headers
if [[ -f "$SOURCE_DIR/config.status" || -f "$SOURCE_DIR/Makefile" ]]; then
(
cd "$SOURCE_DIR"
make distclean >/dev/null 2>&1 || true
)
clean_generated_source_headers
fi
if [[ ! -x "$SOURCE_DIR/configure" ]]; then
(
cd "$SOURCE_DIR"
@@ -178,6 +157,8 @@ build_one() {
--disable-doc \
--disable-oss \
--disable-seq \
--disable-ucm \
--disable-topology \
--disable-rawmidi \
--disable-hwdep \
--disable-usb \

View File

@@ -5,21 +5,17 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
SOURCE_DIR=""
OUTPUT_DIR="${PROJECT_ROOT}/dist/android-ffmpeg-mediacodec"
ANDROID_API="${ANDROID_API:-21}"
NDK_ROOT="${ANDROID_NDK_HOME:-${ANDROID_NDK_ROOT:-}}"
BUILD_ABIS="arm64-v8a armeabi-v7a"
JOBS="${JOBS:-$(nproc 2>/dev/null || echo 4)}"
FFMPEG_ROCKCHIP_REV="${FFMPEG_ROCKCHIP_REV:-40c412daccf08164493da0de990eb99a8948116b}"
usage() {
cat <<'EOF'
Usage:
scripts/build-android-ffmpeg-mediacodec.sh --source <ffmpeg-source-dir> [options]
Required:
--source <dir> FFmpeg source directory. For the downloaded package,
use the extracted ffmpeg-rockchip directory.
scripts/build-android-ffmpeg-mediacodec.sh [options]
Options:
--output <dir> Output root. Default: dist/android-ffmpeg-mediacodec
@@ -35,9 +31,7 @@ The output layout is compatible with ONE_KVM_ANDROID_FFMPEG_ROOT:
<output>/armeabi-v7a/lib
Example:
scripts/build-android-ffmpeg-mediacodec.sh \
--source .tmp/android-ffmpeg-check/src/ffmpeg-rockchip \
--output /opt/one-kvm/android-ffmpeg
scripts/build-android-ffmpeg-mediacodec.sh --output /opt/one-kvm/android-ffmpeg
export ONE_KVM_ANDROID_FFMPEG_ROOT=/opt/one-kvm/android-ffmpeg
cd android && ./gradlew :app:assembleDebug
@@ -51,10 +45,6 @@ fail() {
while [[ $# -gt 0 ]]; do
case "$1" in
--source)
SOURCE_DIR="${2:-}"
shift 2
;;
--output)
OUTPUT_DIR="${2:-}"
shift 2
@@ -81,11 +71,24 @@ while [[ $# -gt 0 ]]; do
esac
done
[[ -n "$SOURCE_DIR" ]] || fail "--source is required"
[[ -d "$SOURCE_DIR" ]] || fail "FFmpeg source not found: $SOURCE_DIR"
[[ -x "$SOURCE_DIR/configure" ]] || fail "FFmpeg configure script not found under: $SOURCE_DIR"
SOURCE_DIR="${PROJECT_ROOT}/.tmp/android-ffmpeg-check/src/ffmpeg-rockchip"
rm -rf "$SOURCE_DIR"
mkdir -p "$(dirname "$SOURCE_DIR")"
repo_url="https://github.com/nyanmisaka/ffmpeg-rockchip.git"
if [[ "${CHINAMIRRO:-0}" == "1" ]]; then
repo_url="${GH_PROXY:-https://gh-proxy.com}"
repo_url="${repo_url%/}/https://github.com/nyanmisaka/ffmpeg-rockchip.git"
fi
echo "Cloning FFmpeg source: $repo_url"
git init "$SOURCE_DIR"
(
cd "$SOURCE_DIR"
git remote add origin "$repo_url"
git fetch --depth 1 origin "$FFMPEG_ROCKCHIP_REV"
git checkout --detach FETCH_HEAD
)
[[ -n "$NDK_ROOT" ]] || fail "--ndk or ANDROID_NDK_HOME/ANDROID_NDK_ROOT is required"
[[ -d "$NDK_ROOT/toolchains/llvm/prebuilt" ]] || fail "Invalid NDK root: $NDK_ROOT"
SOURCE_DIR="$(cd "$SOURCE_DIR" && pwd)"
mkdir -p "$OUTPUT_DIR"
@@ -93,7 +96,6 @@ OUTPUT_DIR="$(cd "$OUTPUT_DIR" && pwd)"
HOST_TAG="$(uname -s | tr '[:upper:]' '[:lower:]')-x86_64"
TOOLCHAIN="${NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_TAG}"
[[ -d "$TOOLCHAIN/bin" ]] || fail "NDK LLVM toolchain not found: $TOOLCHAIN"
normalize_abis() {
printf '%s\n' "$BUILD_ABIS" | tr ',' ' '
@@ -106,11 +108,6 @@ patch_android_ffmpeg_mjpeg_mediacodec() {
local allcodecs="${avcodec_dir}/allcodecs.c"
local makefile="${avcodec_dir}/Makefile"
[[ -f "$mediacodecdec" ]] || fail "FFmpeg mediacodecdec.c not found: $mediacodecdec"
[[ -f "$allcodecs" ]] || fail "FFmpeg allcodecs.c not found: $allcodecs"
[[ -f "$makefile" ]] || fail "FFmpeg libavcodec Makefile not found: $makefile"
[[ -f "$configure_file" ]] || fail "FFmpeg configure not found: $configure_file"
python3 - "$mediacodecdec" "$allcodecs" "$configure_file" "$makefile" <<'PY'
from pathlib import Path
import sys
@@ -218,8 +215,6 @@ build_one() {
extra_cflags="-fPIC"
extra_ldflags=""
[[ -x "$cc" ]] || fail "Missing compiler: $cc"
if [[ "$abi" == "armeabi-v7a" ]]; then
extra_cflags="${extra_cflags} -march=armv7-a -mfloat-abi=softfp -mfpu=neon"
extra_ldflags="${extra_ldflags} -Wl,--fix-cortex-a8"

View File

@@ -5,14 +5,13 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
SOURCE_DIR=""
OUTPUT_DIR="${PROJECT_ROOT}/dist/android-libyuv"
JPEG_ROOT="${ONE_KVM_ANDROID_TURBOJPEG_ROOT:-${PROJECT_ROOT}/dist/android-turbojpeg}"
ANDROID_API="${ANDROID_API:-21}"
NDK_ROOT="${ANDROID_NDK_HOME:-${ANDROID_NDK_ROOT:-}}"
BUILD_ABIS="arm64-v8a armeabi-v7a"
JOBS="${JOBS:-$(nproc 2>/dev/null || echo 4)}"
LIBYUV_REPO="${LIBYUV_REPO:-https://github.com/lemenkov/libyuv.git}"
LIBYUV_REV="${LIBYUV_REV:-957f295ea946cbbd13fcfc46e7066f2efa801233}"
usage() {
cat <<'EOF'
@@ -20,8 +19,6 @@ Usage:
scripts/build-android-libyuv.sh [options]
Options:
--source <dir> Existing libyuv source checkout. If omitted, the script
clones libyuv into .tmp/android-libyuv-src.
--output <dir> Output root. Default: dist/android-libyuv
--ndk <dir> Android NDK root. Defaults to ANDROID_NDK_HOME or ANDROID_NDK_ROOT.
--api <level> Android API level. Default: 21.
@@ -51,10 +48,6 @@ fail() {
while [[ $# -gt 0 ]]; do
case "$1" in
--source)
SOURCE_DIR="${2:-}"
shift 2
;;
--output)
OUTPUT_DIR="${2:-}"
shift 2
@@ -88,27 +81,29 @@ done
[[ -n "$NDK_ROOT" ]] || fail "--ndk or ANDROID_NDK_HOME/ANDROID_NDK_ROOT is required"
[[ -d "$NDK_ROOT/toolchains/llvm/prebuilt" ]] || fail "Invalid NDK root: $NDK_ROOT"
if [[ -z "$SOURCE_DIR" ]]; then
SOURCE_DIR="${PROJECT_ROOT}/.tmp/android-libyuv-src"
if [[ ! -d "$SOURCE_DIR/.git" ]]; then
rm -rf "$SOURCE_DIR"
git clone --depth 1 "$LIBYUV_REPO" "$SOURCE_DIR"
fi
SOURCE_DIR="${PROJECT_ROOT}/.tmp/android-libyuv-src"
rm -rf "$SOURCE_DIR"
repo_url="https://github.com/lemenkov/libyuv.git"
if [[ "${CHINAMIRRO:-0}" == "1" ]]; then
repo_url="${GH_PROXY:-https://gh-proxy.com}"
repo_url="${repo_url%/}/https://github.com/lemenkov/libyuv.git"
fi
[[ -d "$SOURCE_DIR" ]] || fail "libyuv source not found: $SOURCE_DIR"
[[ -f "$SOURCE_DIR/CMakeLists.txt" ]] || fail "libyuv CMakeLists.txt not found under: $SOURCE_DIR"
echo "Cloning libyuv source: $repo_url"
git init "$SOURCE_DIR"
(
cd "$SOURCE_DIR"
git remote add origin "$repo_url"
git fetch --depth 1 origin "$LIBYUV_REV"
git checkout --detach FETCH_HEAD
)
SOURCE_DIR="$(cd "$SOURCE_DIR" && pwd)"
mkdir -p "$OUTPUT_DIR"
OUTPUT_DIR="$(cd "$OUTPUT_DIR" && pwd)"
HOST_TAG="$(uname -s | tr '[:upper:]' '[:lower:]')-x86_64"
TOOLCHAIN="${NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_TAG}"
ANDROID_TOOLCHAIN_FILE="${NDK_ROOT}/build/cmake/android.toolchain.cmake"
[[ -d "$TOOLCHAIN/bin" ]] || fail "NDK LLVM toolchain not found: $TOOLCHAIN"
[[ -f "$ANDROID_TOOLCHAIN_FILE" ]] || fail "NDK CMake toolchain not found: $ANDROID_TOOLCHAIN_FILE"
command -v cmake >/dev/null 2>&1 || fail "cmake is required"
normalize_abis() {
printf '%s\n' "$BUILD_ABIS" | tr ',' ' '

View File

@@ -5,16 +5,12 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
SOURCE_DIR=""
OUTPUT_DIR="${PROJECT_ROOT}/dist/android-opus"
ANDROID_API="${ANDROID_API:-21}"
NDK_ROOT="${ANDROID_NDK_HOME:-${ANDROID_NDK_ROOT:-}}"
BUILD_ABIS="arm64-v8a armeabi-v7a"
JOBS="${JOBS:-$(nproc 2>/dev/null || echo 4)}"
OPUS_VERSION="${OPUS_VERSION:-1.5.2}"
OPUS_TARBALL_URL="${OPUS_TARBALL_URL:-https://downloads.xiph.org/releases/opus/opus-${OPUS_VERSION}.tar.gz}"
OPUS_TARBALL_SHA256="${OPUS_TARBALL_SHA256:-65c1d2f78b9f2fb20082c38cbe47c951ad5839345876e46941612ee87f9a7ce1}"
LOCAL_OPUS_TARBALL="${LOCAL_OPUS_TARBALL:-${PROJECT_ROOT}/opus-${OPUS_VERSION}.tar.gz}"
usage() {
cat <<'EOF'
@@ -22,9 +18,6 @@ Usage:
scripts/build-android-opus.sh [options]
Options:
--source <dir> Existing opus source checkout. If omitted, the script
downloads and extracts the official source tarball
into .tmp/android-opus-src.
--output <dir> Output root. Default: dist/android-opus
--ndk <dir> Android NDK root. Defaults to ANDROID_NDK_HOME or ANDROID_NDK_ROOT.
--api <level> Android API level. Default: 21.
@@ -46,10 +39,6 @@ fail() {
while [[ $# -gt 0 ]]; do
case "$1" in
--source)
SOURCE_DIR="${2:-}"
shift 2
;;
--output)
OUTPUT_DIR="${2:-}"
shift 2
@@ -79,25 +68,13 @@ done
[[ -n "$NDK_ROOT" ]] || fail "--ndk or ANDROID_NDK_HOME/ANDROID_NDK_ROOT is required"
[[ -d "$NDK_ROOT/toolchains/llvm/prebuilt" ]] || fail "Invalid NDK root: $NDK_ROOT"
if [[ -z "$SOURCE_DIR" ]]; then
SOURCE_DIR="${PROJECT_ROOT}/.tmp/android-opus-src"
if [[ ! -f "$SOURCE_DIR/configure" ]]; then
rm -rf "$SOURCE_DIR"
mkdir -p "$SOURCE_DIR"
tarball="${PROJECT_ROOT}/.tmp/opus-${OPUS_VERSION}.tar.gz"
if [[ -f "$LOCAL_OPUS_TARBALL" ]]; then
cp "$LOCAL_OPUS_TARBALL" "$tarball"
else
command -v curl >/dev/null 2>&1 || fail "curl is required to download opus source"
curl -fsSL "$OPUS_TARBALL_URL" -o "$tarball"
fi
echo "${OPUS_TARBALL_SHA256} ${tarball}" | sha256sum -c -
tar -xzf "$tarball" -C "$SOURCE_DIR" --strip-components=1
fi
fi
[[ -d "$SOURCE_DIR" ]] || fail "opus source not found: $SOURCE_DIR"
[[ -x "$SOURCE_DIR/configure" || -f "$SOURCE_DIR/configure.ac" ]] || fail "opus source layout not recognized under: $SOURCE_DIR"
SOURCE_DIR="${PROJECT_ROOT}/.tmp/android-opus-src"
rm -rf "$SOURCE_DIR"
mkdir -p "$SOURCE_DIR"
tarball="${PROJECT_ROOT}/.tmp/opus-${OPUS_VERSION}.tar.gz"
url="https://downloads.xiph.org/releases/opus/opus-${OPUS_VERSION}.tar.gz"
curl -fsSL "$url" -o "$tarball"
tar -xzf "$tarball" -C "$SOURCE_DIR" --strip-components=1
SOURCE_DIR="$(cd "$SOURCE_DIR" && pwd)"
mkdir -p "$OUTPUT_DIR"
@@ -105,10 +82,6 @@ OUTPUT_DIR="$(cd "$OUTPUT_DIR" && pwd)"
HOST_TAG="$(uname -s | tr '[:upper:]' '[:lower:]')-x86_64"
TOOLCHAIN="${NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_TAG}"
ANDROID_TOOLCHAIN_FILE="${NDK_ROOT}/build/cmake/android.toolchain.cmake"
[[ -d "$TOOLCHAIN/bin" ]] || fail "NDK LLVM toolchain not found: $TOOLCHAIN"
[[ -f "$ANDROID_TOOLCHAIN_FILE" ]] || fail "NDK CMake toolchain not found: $ANDROID_TOOLCHAIN_FILE"
command -v cmake >/dev/null 2>&1 || fail "cmake is required"
normalize_abis() {
printf '%s\n' "$BUILD_ABIS" | tr ',' ' '
@@ -161,14 +134,6 @@ build_one() {
make install
)
mkdir -p "$prefix/lib" "$prefix/include"
if [[ -f "$prefix/include/opus/opus.h" ]]; then
:
elif [[ -f "$SOURCE_DIR/include/opus/opus.h" ]]; then
mkdir -p "$prefix/include/opus"
cp "$SOURCE_DIR/include/opus/opus.h" "$prefix/include/opus/opus.h"
fi
echo "Built Opus for ${abi}: ${prefix}"
}

View File

@@ -5,13 +5,12 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
SOURCE_DIR=""
OUTPUT_DIR="${PROJECT_ROOT}/dist/android-turbojpeg"
ANDROID_API="${ANDROID_API:-21}"
NDK_ROOT="${ANDROID_NDK_HOME:-${ANDROID_NDK_ROOT:-}}"
BUILD_ABIS="arm64-v8a armeabi-v7a"
JOBS="${JOBS:-$(nproc 2>/dev/null || echo 4)}"
LIBJPEG_TURBO_REPO="${LIBJPEG_TURBO_REPO:-https://github.com/libjpeg-turbo/libjpeg-turbo.git}"
LIBJPEG_TURBO_VERSION="${LIBJPEG_TURBO_VERSION:-3.1.4.1}"
usage() {
cat <<'EOF'
@@ -19,8 +18,6 @@ Usage:
scripts/build-android-turbojpeg.sh [options]
Options:
--source <dir> Existing libjpeg-turbo source checkout. If omitted,
the script clones it into .tmp/android-turbojpeg-src.
--output <dir> Output root. Default: dist/android-turbojpeg
--ndk <dir> Android NDK root. Defaults to ANDROID_NDK_HOME or ANDROID_NDK_ROOT.
--api <level> Android API level. Default: 21.
@@ -46,10 +43,6 @@ fail() {
while [[ $# -gt 0 ]]; do
case "$1" in
--source)
SOURCE_DIR="${2:-}"
shift 2
;;
--output)
OUTPUT_DIR="${2:-}"
shift 2
@@ -79,27 +72,29 @@ done
[[ -n "$NDK_ROOT" ]] || fail "--ndk or ANDROID_NDK_HOME/ANDROID_NDK_ROOT is required"
[[ -d "$NDK_ROOT/toolchains/llvm/prebuilt" ]] || fail "Invalid NDK root: $NDK_ROOT"
if [[ -z "$SOURCE_DIR" ]]; then
SOURCE_DIR="${PROJECT_ROOT}/.tmp/android-turbojpeg-src"
if [[ ! -d "$SOURCE_DIR/.git" ]]; then
rm -rf "$SOURCE_DIR"
git clone --depth 1 "$LIBJPEG_TURBO_REPO" "$SOURCE_DIR"
fi
SOURCE_DIR="${PROJECT_ROOT}/.tmp/android-turbojpeg-src"
rm -rf "$SOURCE_DIR"
repo_url="https://github.com/libjpeg-turbo/libjpeg-turbo.git"
if [[ "${CHINAMIRRO:-0}" == "1" ]]; then
repo_url="${GH_PROXY:-https://gh-proxy.com}"
repo_url="${repo_url%/}/https://github.com/libjpeg-turbo/libjpeg-turbo.git"
fi
[[ -d "$SOURCE_DIR" ]] || fail "libjpeg-turbo source not found: $SOURCE_DIR"
[[ -f "$SOURCE_DIR/CMakeLists.txt" ]] || fail "libjpeg-turbo CMakeLists.txt not found under: $SOURCE_DIR"
echo "Cloning libjpeg-turbo ${LIBJPEG_TURBO_VERSION}: $repo_url"
git init "$SOURCE_DIR"
(
cd "$SOURCE_DIR"
git remote add origin "$repo_url"
git fetch --depth 1 origin "refs/tags/$LIBJPEG_TURBO_VERSION"
git checkout --detach FETCH_HEAD
)
SOURCE_DIR="$(cd "$SOURCE_DIR" && pwd)"
mkdir -p "$OUTPUT_DIR"
OUTPUT_DIR="$(cd "$OUTPUT_DIR" && pwd)"
HOST_TAG="$(uname -s | tr '[:upper:]' '[:lower:]')-x86_64"
TOOLCHAIN="${NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_TAG}"
ANDROID_TOOLCHAIN_FILE="${NDK_ROOT}/build/cmake/android.toolchain.cmake"
[[ -d "$TOOLCHAIN/bin" ]] || fail "NDK LLVM toolchain not found: $TOOLCHAIN"
[[ -f "$ANDROID_TOOLCHAIN_FILE" ]] || fail "NDK CMake toolchain not found: $ANDROID_TOOLCHAIN_FILE"
command -v cmake >/dev/null 2>&1 || fail "cmake is required"
normalize_abis() {
printf '%s\n' "$BUILD_ABIS" | tr ',' ' '