代码之家  ›  专栏  ›  技术社区  ›  donturner

为什么在为Android编译FFmpeg时会出现“错误:无效指令助记符”?

  •  1
  • donturner  · 技术社区  · 6 年前

    我在试着编译 FFmpeg 4.0 对于Android使用 clang

    下面是我的configure命令:

    ./configure \
    --target-os=android \
    --arch=armv7-a \
    --enable-cross-compile \
    --cc=${ANDROID_NDK}/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang \
    --enable-shared \
    --disable-static 
    

    make -j8 并得到以下错误:

    In file included from libavfilter/vf_mestimate.c:22:
    In file included from ./libavcodec/mathops.h:40:
    ./libavcodec/arm/mathops.h:90:26: error: invalid instruction mnemonic 'itt'
        "cmp   %1, %2  \n\t"
                         ^
    <inline asm>:3:2: note: instantiated into assembly here
        itt   gt      
        ^~~
    

    你知道这是什么原因吗?

    1 回复  |  直到 6 年前
        1
  •  6
  •   Ryan Prichard    6 年前

    我怀疑Clang的目标是主机操作系统而不是arm32。使用 standalone toolchain 解决了这个问题。我注意到构建系统仍在使用我的主机 strip 工具(它不能处理arm二进制文件),所以我通过 --strip

    ${ANDROID_NDK}/build/tools/make_standalone_toolchain.py \
        --arch arm --api 16 --install-dir /tmp/standalone-toolchain
    
    ./configure \
    --target-os=android \
    --arch=armv7-a \
    --enable-cross-compile \
    --cc=/tmp/standalone-toolchain/bin/clang \
    --strip=/tmp/standalone-toolchain/bin/arm-linux-androideabi-strip \
    --enable-shared \
    --disable-static 
    
    make -j...
    

    CC  libavdevice/v4l2.o
    libavdevice/v4l2.c:135:9: error: assigning to 'int (*)(int, unsigned long, ...)' from incompatible type
          '<overloaded function type>'
            SET_WRAPPERS();
            ^~~~~~~~~~~~~~
    libavdevice/v4l2.c:121:17: note: expanded from macro 'SET_WRAPPERS'
        s->ioctl_f  = prefix ## ioctl;      \
                    ^           ~~~~~
    /tmp/standalone-toolchain/bin/../sysroot/usr/include/bits/ioctl.h:56:5: note: candidate function has type mismatch at 2nd
          parameter (expected 'unsigned long' but has 'unsigned int')
    int ioctl(int __fd, unsigned __request, ...) __overloadable __enable_if(1, "") __RENAME(ioctl);
        ^
    /tmp/standalone-toolchain/bin/../sysroot/usr/include/bits/ioctl.h:36:5: note: candidate function has type mismatch at 2nd
          parameter (expected 'unsigned long' but has 'int')
    int ioctl(int __fd, int __request, ...);
        ^
    

    关于ioctl的第二个参数的类型有分歧。glibc用类型声明它 unsigned long

    int ioctl(int fd, unsigned long request, ...);
    

    Bionic (和musl)用 int :

    int ioctl(int fildes, int request, ... /* arg */);
    

    类似的问题也发生在 PulseAudio and musl

    diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
    index 10a0ff0dd6..1b9c6e760b 100644
    --- a/libavdevice/v4l2.c
    +++ b/libavdevice/v4l2.c
    @@ -95,7 +95,11 @@ struct video_data {
         int (*open_f)(const char *file, int oflag, ...);
         int (*close_f)(int fd);
         int (*dup_f)(int fd);
    +#ifdef __GLIBC__
         int (*ioctl_f)(int fd, unsigned long int request, ...);
    +#else
    +    int (*ioctl_f)(int fd, int request, ...);
    +#endif
         ssize_t (*read_f)(int fd, void *buffer, size_t n);
         void *(*mmap_f)(void *start, size_t length, int prot, int flags, int fd, int64_t offset);
         int (*munmap_f)(void *_start, size_t length);
    

    之后,项目建设成功。

    • 独立工具链: --arch arm64
    • 独立工具链: --api 21
    • --arch=aarch64
    • 配置: --strip=/.../aarch64-linux-android-strip