RaspberryPi上のEPGStationコンテナ用にffmpegをビルドする(2023年9月版)

以前、RaspberryPi上にEPGStationをDockerを使ってセットアップしました。 この中でRaspberryPiのハードウェアエンコードが有効なffmpegをビルドしたのですが、 今回軽い気持ちでEPGStationコンテナを最新化しようとしたところこのffmpegのビルドがエラー連発で大苦戦してしまいました。 Dockerfileは変えていなかったので外部の要因によるもののようです。

error: invalid 'asm': invalid operand for code 'w'

まずはビルド中にこのエラー。

In file included from ./libavutil/bswap.h:38,
                 from ./libavutil/intreadwrite.h:25,
                 from libavfilter/vf_curves.c:25:
In function 'av_bswap16',
    inlined from 'parse_psfile' at libavfilter/vf_curves.c:381:5:
./libavutil/aarch64/bswap.h:31:5: error: invalid 'asm': invalid operand for code 'w'
   31 |     __asm__("rev16 %w0, %w0" : "+r"(x));
      |     ^~~~~~~
./libavutil/aarch64/bswap.h:31:5: error: invalid 'asm': invalid operand for code 'w'
In function 'av_bswap16',
    inlined from 'parse_psfile' at libavfilter/vf_curves.c:385:9:
./libavutil/aarch64/bswap.h:31:5: error: invalid 'asm': invalid operand for code 'w'
   31 |     __asm__("rev16 %w0, %w0" : "+r"(x));
      |     ^~~~~~~
./libavutil/aarch64/bswap.h:31:5: error: invalid 'asm': invalid operand for code 'w'
In function 'av_bswap16',
    inlined from 'parse_psfile' at libavfilter/vf_curves.c:388:13:
./libavutil/aarch64/bswap.h:31:5: error: invalid 'asm': invalid operand for code 'w'
   31 |     __asm__("rev16 %w0, %w0" : "+r"(x));
      |     ^~~~~~~
./libavutil/aarch64/bswap.h:31:5: error: invalid 'asm': invalid operand for code 'w'
In function 'av_bswap16',
    inlined from 'parse_psfile' at libavfilter/vf_curves.c:389:13:
./libavutil/aarch64/bswap.h:31:5: error: invalid 'asm': invalid operand for code 'w'
   31 |     __asm__("rev16 %w0, %w0" : "+r"(x));
      |     ^~~~~~~
./libavutil/aarch64/bswap.h:31:5: error: invalid 'asm': invalid operand for code 'w'
CC      libavfilter/vf_deband.o
make: *** [ffbuild/common.mak:67: libavfilter/vf_curves.o] Error 1
make: *** Waiting for unfinished jobs....

RaspberryPi OSは32bit版のはずなのにaarch64の文字列が見えるのが気になる。

$ uname -m
aarch64
$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
$ uname -m
aarch64
$ getconf LONG_BIT
32
$ dpkg --print-architecture
armhf

カーネルは64bit、ユーザーランドは32bitになっている。 コンテナ内も同様。

# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
# getconf LONG_BIT
32
# dpkg --print-architecture
armhf

で見つけたのがこの記事。 RasPi OS 32bitをインストールしたのにaarch64??

どうやら今年のどこかにデフォルト動作が変わり、デフォルトで64bitカーネルで起動するようになったようです。 /boot/config.txtで動作を変更できるので32bitカーネルで起動するように変更。

Raspberry Pi Documentation - The config.txt file

設定ファイルを変更したら再起動。アーキテクチャがarmv7lになっていることを確認します。

$ uname -m
armv7l

これで上のエラーは回避できます。

docker compose buildだとコケる

その後もなぜかdocker compose buildだと./configureの段でエラーになります。

gcc is unable to create an executable file.
If gcc is a cross-compiler, use the --enable-cross-compile option.
Only do this if you know what cross compiling means.
C compiler test failed.

If you think configure made a mistake, make sure you are using the latest
version from Git.  If the latest version fails, report the problem to the
ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.libera.chat.
Include the log file "ffbuild/config.log" produced by configure as this will help
solve the problem.

docker runでコンテナを上げて手動でコマンドを実行していくとエラーにはならない。 しかもdocker buildでもエラーにならず、ビルドは成功した。

いろいろと試行錯誤した結果、あらかじめdocker pull l3tnun/epgstation:master-debianでローカルのイメージを最新化しておくとでなくなったように見えます。 そもそもdocker compose build --pullでビルドしていたのにイメージをPullしていなかった模様。原因は不明。

cc1: error: '-mfloat-abi=hard': selected architecture lacks an FPU

続いてこのエラー。 ./cofigureで上と同じエラーになりますがこちらはdocker runで実行しても再現する。 メッセージにあるようにffbuild/config.logを見てみるとこのエラーが書いてある。

Raspberry Pi (Ubuntu Server) でOpenSSLをビルドする - Qiita

上の記事はOpenSSLのビルドの話ですが、gccの-marchオプションでarmv7-a+fpを指定すればよいとのこと。 同じようにするためにどうすればよいか、configureのソースを眺めてみる。

elif enabled arm; the
    ..
    case $cpu in
        armv*)
            cpuflags="-march=$cpu"
            subarch=$(echo $cpu | sed 's/[^a-z0-9]//g')
        ;;

$cpuの値をそのまま-marchに渡している。 configureには--cpuというオプションがあるようなのでそこで指定すれば$cpuに入るのか?と思いconfigure--cpu=armv7-a+fpオプションを追加してみたところビルドに成功した。

現在のオプション

./configure \
    --prefix=/usr/local \
    --disable-shared \
    --pkg-config-flags=--static \
    --cpu=armv7-a+fp \
    --enable-gpl \
    --enable-libass \
    --enable-libfreetype \
    --enable-libmp3lame \
    --enable-libopus \
    --enable-libtheora \
    --enable-libvorbis \
    --enable-libvpx \
    --enable-libx264 \
    --enable-libx265 \
    --enable-omx \
    --enable-omx-rpi \
    --enable-version3 \
    --enable-libaribb24 \
    --enable-nonfree \
    --disable-debug \
    --disable-doc \

コンテナ化してもなかなか再現性を維持するのは難しい…。

関連記事

comments powered by Disqus