1. 目录结构
bash
~/t113-mpv/
├── build/
├── install/
├── logs/
├── pkgconfig-merged/
├── src/
├── env.sh
├── pkg-config-t113
└── t113-arm-musl.cross
2. 配置交叉编译环境
env.sh内容如下:
bash
export TINA_SDK=~/t113/Tina-Linux
export SYSROOT=$TINA_SDK/out/t113-mq_r/staging_dir/target
export PREFIX=~/t113-mpv/install
export TOOLCHAIN=$TINA_SDK/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-musl/toolchain
export CROSS_BIN=$TOOLCHAIN/bin
export TARGET=arm-openwrt-linux
export PATH=$CROSS_BIN:$HOME/.local/bin:$PATH
export CC=$CROSS_BIN/${TARGET}-gcc
export CXX=$CROSS_BIN/${TARGET}-g++
export AR=$CROSS_BIN/${TARGET}-ar
export AS=$CROSS_BIN/${TARGET}-as
export LD=$CROSS_BIN/${TARGET}-ld
export RANLIB=$CROSS_BIN/${TARGET}-ranlib
export STRIP=$CROSS_BIN/${TARGET}-strip
export NM=$CROSS_BIN/${TARGET}-nm
export CFLAGS="--sysroot=$SYSROOT -Os -fPIC"
export CXXFLAGS="--sysroot=$SYSROOT -Os -fPIC"
export CPPFLAGS="--sysroot=$SYSROOT"
export LDFLAGS="--sysroot=$SYSROOT -L$PREFIX/lib -Wl,-rpath-link,$PREFIX/lib -Wl,-rpath-link,$SYSROOT/usr/lib -Wl,-rpath-link,$SYSROOT/lib"
加载:
bash
source ~/t113-mpv/env.sh
3. Meson cross file
关键点:
- 不写
sys_root = ...,否则会污染pkg-config的路径解析 pkgconfig指向 wrapper,而不是系统/usr/bin/pkg-config
t113-arm-musl.cross 内容如下:
ini
[binaries]
c = '~/t113/Tina-Linux/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-musl/toolchain/bin/arm-openwrt-linux-gcc'
cpp = '~/t113/Tina-Linux/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-musl/toolchain/bin/arm-openwrt-linux-g++'
ar = '~/t113/Tina-Linux/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-musl/toolchain/bin/arm-openwrt-linux-ar'
strip = '~/t113/Tina-Linux/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-musl/toolchain/bin/arm-openwrt-linux-strip'
pkgconfig = '~/t113-mpv/pkg-config-t113'
[properties]
needs_exe_wrapper = true
c_args = ['--sysroot=~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target', '-Os', '-fPIC']
cpp_args = ['--sysroot=~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target', '-Os', '-fPIC']
c_link_args = ['--sysroot=~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target', '-L~/t113-mpv/install/lib', '-Wl,-rpath-link,~/t113-mpv/install/lib', '-Wl,-rpath-link,~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target/usr/lib', '-Wl,-rpath-link,~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target/lib']
cpp_link_args = ['--sysroot=~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target', '-L~/t113-mpv/install/lib', '-Wl,-rpath-link,~/t113-mpv/install/lib', '-Wl,-rpath-link,~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target/usr/lib', '-Wl,-rpath-link,~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target/lib']
[host_machine]
system = 'linux'
cpu_family = 'arm'
cpu = 'armv7'
endian = 'little'
4. 基础库编译顺序
4.1 逐库编译
按以下顺序编译:
zlibfreetype第一轮fribidiharfbuzzfreetype第二轮,接入harfbuzzlibass
约定:
bash
export SRC_DIR=~/t113-mpv/src
export BUILD_DIR=~/t113-mpv/build
export PREFIX=~/t113-mpv/install
4.1.1 编 zlib
bash
cd $SRC_DIR
wget https://zlib.net/fossils/zlib-1.3.1.tar.gz
tar xf zlib-1.3.1.tar.gz
cd zlib-1.3.1
CHOST=$TARGET ./configure --prefix=$PREFIX
make -j$(nproc)
make install
验证:
bash
file $PREFIX/lib/libz.so*
结果:
text
libz.so.1.3.1: ELF 32-bit LSB shared object, ARM, EABI5
4.1.2 编 FreeType 第一轮
第一轮先只接 zlib,不接 harfbuzz。
bash
cd $SRC_DIR
wget https://download.savannah.gnu.org/releases/freetype/freetype-2.13.3.tar.xz
tar xf freetype-2.13.3.tar.xz
rm -rf $BUILD_DIR/freetype
mkdir -p $BUILD_DIR/freetype
cd $BUILD_DIR/freetype
$SRC_DIR/freetype-2.13.3/configure \
--host=arm-openwrt-linux \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--with-zlib=yes \
--with-png=no \
--with-harfbuzz=no \
--with-bzip2=no \
--with-brotli=no \
CC="$CC" CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
make -j$(nproc)
make install
4.1.3 编 FriBidi
bash
cd $SRC_DIR
wget https://github.com/fribidi/fribidi/releases/download/v1.0.16/fribidi-1.0.16.tar.xz
tar xf fribidi-1.0.16.tar.xz
rm -rf $BUILD_DIR/fribidi
mkdir -p $BUILD_DIR/fribidi
cd $BUILD_DIR/fribidi
$SRC_DIR/fribidi-1.0.16/configure \
--host=arm-openwrt-linux \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-docs \
CC="$CC" CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
make -j$(nproc)
make install
4.1.4 编 HarfBuzz
这一步必须先清理 pkg-config 环境,不能让 PKG_CONFIG_SYSROOT_DIR 参与。
bash
unset PKG_CONFIG_SYSROOT_DIR
export PKG_CONFIG_LIBDIR=$PREFIX/lib/pkgconfig:$PREFIX/share/pkgconfig
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig:$PREFIX/share/pkgconfig
pkg-config --cflags freetype2
pkg-config --libs freetype2
确认 pkg-config --cflags freetype2 类似:
text
-I~/t113-mpv/install/include/freetype2 -I~/t113-mpv/install/include
然后编译:
bash
cd $SRC_DIR
wget https://github.com/harfbuzz/harfbuzz/releases/download/10.2.0/harfbuzz-10.2.0.tar.xz
tar xf harfbuzz-10.2.0.tar.xz
rm -rf $BUILD_DIR/harfbuzz
mkdir -p $BUILD_DIR/harfbuzz
cd $BUILD_DIR/harfbuzz
meson setup . $SRC_DIR/harfbuzz-10.2.0 \
--cross-file ~/t113-mpv/t113-arm-musl.cross \
--prefix=$PREFIX \
--libdir=lib \
--default-library=shared \
-Dglib=disabled \
-Dgobject=disabled \
-Dicu=disabled \
-Dtests=disabled \
-Ddocs=disabled \
-Dfreetype=enabled \
-Dbenchmark=disabled \
-Dintrospection=disabled
meson compile -C .
meson install -C .
4.1.5 回编 FreeType 第二轮
第二轮把 harfbuzz 接进去。
bash
unset PKG_CONFIG_SYSROOT_DIR
export PKG_CONFIG_LIBDIR=$PREFIX/lib/pkgconfig:$PREFIX/share/pkgconfig
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig:$PREFIX/share/pkgconfig
rm -rf $BUILD_DIR/freetype
mkdir -p $BUILD_DIR/freetype
cd $BUILD_DIR/freetype
$SRC_DIR/freetype-2.13.3/configure \
--host=arm-openwrt-linux \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--with-zlib=yes \
--with-png=no \
--with-harfbuzz=yes \
--with-bzip2=no \
--with-brotli=no \
CC="$CC" CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
make -j$(nproc)
make install
4.1.6 编 libass
bash
unset PKG_CONFIG_SYSROOT_DIR
export PKG_CONFIG_LIBDIR=$PREFIX/lib/pkgconfig:$PREFIX/share/pkgconfig
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig:$PREFIX/share/pkgconfig
cd $SRC_DIR
wget https://github.com/libass/libass/releases/download/0.17.3/libass-0.17.3.tar.xz
tar xf libass-0.17.3.tar.xz
rm -rf $BUILD_DIR/libass
mkdir -p $BUILD_DIR/libass
cd $BUILD_DIR/libass
$SRC_DIR/libass-0.17.3/configure \
--host=arm-openwrt-linux \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-require-system-font-provider \
CC="$CC" CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" \
PKG_CONFIG=/usr/bin/pkg-config
make -j$(nproc)
make install
验证:
bash
pkg-config --modversion libass
pkg-config --cflags libass
pkg-config --libs libass
4.2 FFmpeg 具体编译步骤
4.2.1 合并 pkg-config
(1)原因
mpv 和 FFmpeg 需要同时看到两类 .pc:
install/lib/pkgconfig下自编产物SYSROOT/usr/lib/pkgconfig下的alsa.pc
但不能使用 PKG_CONFIG_SYSROOT_DIR 去污染 install/ 下的 .pc,否则会出现:
ft2build.h not foundinclude被改写成/sysroot/home/...
(2)方案
- 建立 merged 目录:
bash
~/t113-mpv/pkgconfig-merged
- 将
install/lib/pkgconfig/*.pc拷入其中,再复制alsa.pc并把它改成绝对sysroot前缀:
ini
prefix=~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
或者直接使用如下命令:
bash
rm -f ~/t113-mpv/pkgconfig-merged/*
cp -a ~/t113-mpv/install/lib/pkgconfig/*.pc \
~/t113-mpv/pkgconfig-merged/
cp -a ~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target/usr/lib/pkgconfig/alsa.pc \
~/t113-mpv/pkgconfig-merged/
sed -i 's#^prefix=.*#prefix=~/t113/Tina-Linux/out/t113-mq_r/staging_dir/target/usr#' \
~/t113-mpv/pkgconfig-merged/alsa.pc
sed -i 's#^exec_prefix=.*#exec_prefix=${prefix}#' \
~/t113-mpv/pkgconfig-merged/alsa.pc
sed -i 's#^libdir=.*#libdir=${exec_prefix}/lib#' \
~/t113-mpv/pkgconfig-merged/alsa.pc
sed -i 's#^includedir=.*#includedir=${prefix}/include#' \
~/t113-mpv/pkgconfig-merged/alsa.pc
- wrapper 使用的
pkg-config-t113内容如下:
sh
#!/bin/sh
MERGED=~/t113-mpv/pkgconfig-merged
export PKG_CONFIG_DIR=
unset PKG_CONFIG_SYSROOT_DIR
export PKG_CONFIG_LIBDIR="$MERGED"
export PKG_CONFIG_PATH="$MERGED"
exec /usr/bin/pkg-config "$@"
或者直接使用如下命令:
bash
cat > ~/t113-mpv/pkg-config-t113 <<'EOF'
#!/bin/sh
MERGED=~/t113-mpv/pkgconfig-merged
export PKG_CONFIG_DIR=
unset PKG_CONFIG_SYSROOT_DIR
export PKG_CONFIG_LIBDIR="$MERGED"
export PKG_CONFIG_PATH="$MERGED"
exec /usr/bin/pkg-config "$@"
EOF
chmod +x ~/t113-mpv/pkg-config-t113
(3)验证
bash
~/t113-mpv/pkg-config-t113 --modversion libavcodec
~/t113-mpv/pkg-config-t113 --modversion libass
~/t113-mpv/pkg-config-t113 --modversion alsa
4.2.2 编 FFmpeg
这里是最终跑通的版本,关键是 -D_GNU_SOURCE。
bash
export PKG_CONFIG=~/t113-mpv/pkg-config-t113
export EXTRA_CFLAGS="$CFLAGS -D_GNU_SOURCE"
export EXTRA_CXXFLAGS="$CXXFLAGS -D_GNU_SOURCE"
cd $SRC_DIR
wget https://ffmpeg.org/releases/ffmpeg-4.4.4.tar.xz
tar xf ffmpeg-4.4.4.tar.xz
rm -rf $BUILD_DIR/ffmpeg
mkdir -p $BUILD_DIR/ffmpeg
cd $BUILD_DIR/ffmpeg
$SRC_DIR/ffmpeg-4.4.4/configure \
--prefix=$PREFIX \
--cross-prefix=arm-openwrt-linux- \
--arch=arm \
--target-os=linux \
--enable-cross-compile \
--sysroot=$SYSROOT \
--pkg-config=$PKG_CONFIG \
--pkg-config-flags="--static" \
--enable-pic \
--enable-shared \
--disable-static \
--disable-debug \
--disable-doc \
--enable-gpl \
--enable-version3 \
--enable-avcodec \
--enable-avformat \
--enable-avutil \
--enable-swresample \
--enable-swscale \
--enable-postproc \
--enable-avfilter \
--enable-avdevice \
--disable-programs \
--enable-ffmpeg \
--enable-ffprobe \
--disable-ffplay \
--enable-libass \
--enable-zlib \
--enable-alsa \
--extra-cflags="$EXTRA_CFLAGS" \
--extra-cxxflags="$EXTRA_CXXFLAGS" \
--extra-ldflags="$LDFLAGS" \
--extra-libs="-lpthread -lm -ldl -lrt -lass -lfribidi -lharfbuzz -lfreetype -lz -lasound"
make -j$(nproc)
make install
验证:
bash
grep -E 'CONFIG_AVDEVICE|CONFIG_LIBASS|CONFIG_ALSA' config.h
file $PREFIX/lib/libavdevice.so*
file $PREFIX/bin/ffprobe
4.3 mpv / libmpv 具体编译步骤
4.3.1 准备源码
bash
export PKG_CONFIG=~/t113-mpv/pkg-config-t113
cd $SRC_DIR
wget https://github.com/mpv-player/mpv/archive/refs/tags/v0.36.0.tar.gz -O mpv-0.36.0.tar.gz
tar xf mpv-0.36.0.tar.gz
4.3.2 setup
bash
rm -rf $BUILD_DIR/mpv
mkdir -p $BUILD_DIR/mpv
cd $BUILD_DIR/mpv
meson setup . $SRC_DIR/mpv-0.36.0 \
--cross-file ~/t113-mpv/t113-arm-musl.cross \
--prefix=$PREFIX \
--libdir=lib \
--default-library=shared \
-Dcplayer=false \
-Dlibmpv=true \
-Dalsa=enabled \
-Dpulse=disabled \
-Dpipewire=disabled \
-Djack=disabled \
-Dopenal=disabled \
-Doss-audio=disabled \
-Dsndio=disabled \
-Dlua=disabled \
-Djavascript=disabled \
-Duchardet=disabled \
-Drubberband=disabled \
-Ddvdnav=disabled \
-Dlibarchive=disabled \
-Dlibbluray=disabled \
-Dvapoursynth=disabled \
-Dzimg=disabled \
-Djpeg=disabled \
-Dlcms2=disabled \
-Ddrm=disabled \
-Degl=disabled \
-Dgl=disabled \
-Dvulkan=disabled \
-Dwayland=disabled \
-Dx11=disabled \
-Dxv=disabled \
-Dsdl2-video=disabled \
-Dsdl2-audio=disabled \
-Dmanpage-build=disabled \
-Dhtml-build=disabled \
-Dpdf-build=disabled \
-Dtests=false \
-Dbuild-date=false
验证 summary:
bash
grep -E 'libmpv|alsa|libavcodec|libavformat|libavutil|libavfilter|libavdevice' \
~/t113-mpv/logs/mpv-rebuild-setup.log
4.3.3 编译安装
bash
meson compile -C .
meson install -C .
验证:
bash
ls $PREFIX/lib/libmpv.so*
file $PREFIX/lib/libmpv.so.2.1.0
ls $PREFIX/include/mpv
ls $PREFIX/lib/pkgconfig/mpv.pc
5. 踩过的坑
5.1 ft2build.h not found
HarfBuzz 不能用 PKG_CONFIG_SYSROOT_DIR
- 原因:
PKG_CONFIG_SYSROOT_DIR污染了PREFIX下freetype2.pc - 解决:
unset PKG_CONFIG_SYSROOT_DIR,并把PKG_CONFIG_LIBDIR/PKG_CONFIG_PATH明确指向$PREFIX/lib/pkgconfig
5.2 Dependency "libavcodec" not found, tried pkgconfig
mpv 不能只靠环境变量 PKG_CONFIG,Meson 实际优先使用 cross file 里的 pkgconfig 条目,必须显式改成 wrapper。
- 原因:Meson 实际使用的是 cross file 里的
pkgconfig,不是 shell 环境里的PKG_CONFIG - 解决:把
t113-arm-musl.cross里的
ini
pkgconfig = '/usr/bin/pkg-config'
改成:
ini
pkgconfig = '~/t113-mpv/pkg-config-t113'
5.3 ERROR: alsa requested but not found
FFmpeg 的 ALSA 检测在 Tina sysroot 下会卡头文件
- 原因:FFmpeg 的 ALSA 探测源码在 Tina sysroot 下会因为
u_int8_t/u_int16_t/u_int32_t/u_int64_t不可见而编译失败 - 现象:
ffbuild/config.log里出现unknown type name 'u_int8_t' - 解决:给 FFmpeg 增加
--extra-cflags="$CFLAGS -D_GNU_SOURCE"和--extra-cxxflags="$CXXFLAGS -D_GNU_SOURCE"
5.4 链接时不能只写 -lmpv
还要显式补:
libav*libass / fribidi / harfbuzz / freetype / zlib-lasound-ldl -lrt-Wl,-rpath-link