使用Android NDK r20

时间:2019-08-27 19:47:27

标签: ffmpeg android-ndk

我正在尝试使用Android NDK r20构建FFMPEG 4.2,但是configure遇到了问题。

我关注了Ilia Kosynkin的博客文章(https://medium.com/@ilja.kosynkin/building-ffmpeg-4-0-for-android-with-clang-642e4911c31e),并且对build.sh进行了一些小改动,我在Ubuntu 16 VM上使用API​​级别14的Android NDK r17c成功构建了FFMPEG 4.0.2。 / p>

我将FFMPEG更新为4.2,将Android NDK更新为r20,并得到了这些错误和其他编译器错误。

~/android-ndk/sysroot/usr/include/stdlib.h:61:7: error: expected identifier or '('
char* getenv(const char* __name);
      ^
./config.h:17:19: note: expanded from macro 'getenv'
#define getenv(x) NULL
                  ^
~/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/8.0.7/include/stddef.h:105:18: note: expanded from macro 'NULL'
#  define NULL ((void*)0)

还有许多这样的东西:

./libavutil/libm.h:54:32: error: static declaration of 'cbrt' follows non-static declaration
static av_always_inline double cbrt(double x)
                               ^
~/android-ndk/sysroot/usr/include/math.h:191:8: note: previous declaration is here
double cbrt(double __x);
       ^

除了cbrt以外,还重新定义了大约十二种其他与数学相关的函数(例如lrint,round,trunc,inet_aton)。我打开生成的config.h,注释掉#define getenv(x) NULL,并将诸如#define HAVE_CBRT 0之类的一堆定义更改为#define HAVE_CBRT 1。我分别运行makemake install,构建成功。

所以我的问题是,是否可以将ffmpeg选项传递给configure来生成config.h,而不必为获得成功的构建而进行修改?

编辑:来自config.log的其他信息。

似乎check_mathfunc中的configure对于NDK r20来说是失败的,但我不知道为什么。这是一个链接命令无法检查truncf的示例。该错误对我来说没有任何意义。

~/android-ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ld
    -L~/android-ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x
    -L~/android-ndk/platforms/android-29/arch-arm/usr/lib
    --fix-cortex-a8 -lc --sysroot=~/android-ndk/sysroot -fPIE -pie
    -o /tmp/ffconf.1OTX8pa8/test /tmp/ffconf.1OTX8pa8/test.o -lgcc

~/android-ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ld:
    fatal error: -f/--auxiliary may not be used without -shared

编辑2:该错误似乎是由 -pie 选项(创建与位置无关的可执行文件)引起的。早期版本的FFMPEG在android的 configure 脚本中没有这两行:

add_cflags -fPIE
add_ldexeflags -fPIE, -pie

如果我将 -shared 添加到add_ldexeflags,则会出现错误“ -shared和-pie不兼容”。如果将 -pie 替换为 -shared ,则check_mathfunc成功,但是我不知道这是否正确。 -fPIE 要求 -shared ,但不能与 -pie 一起使用。

-共享替换 -pie 似乎可以修复config.h文件,但是现在我在{{1}的构建过程中得到了'sys/sysctl.h' file not found }。 NDK r20有2个libavutil实例,而NDK r17c有1个实例,但它们都不在名为sysctl.h的目录中。

编辑3:我将把这个问题归因于FFMPEG sys脚本中的一个错误。 configure通过生成一个使用该函数的小型源文件,然后编译并链接所生成的文件,来检查该函数是否存在。如果有任何故障,则该功能不可用。对于NDK r17c,configure失败,并且构建不包含check_func sysctl功能。由于某种原因,NDK r20的测试成功了,因为sysctl不会验证check_func是否存在,它只是原型sys/sysctl.h并对其进行调用。我通过向名为sysctl()的{​​{1}}添加一个试图包含configure的函数来解决了这个问题。我现在克服了这个错误,并有了一个关于隐式声明无效的新错误。我必须假设它在check_sysfunc中也是一种缺陷,希望这些不会过多。

2 个答案:

答案 0 :(得分:1)

直接将FOR %%f IN (*.wav) DO ( set "el = %%f" echo %el% echo %%f echo %%f:wav=mp3% ) 传递给ld是错误的。那是一个编译器标志。链接器标志的拼写为-fPIE-pie-fPIE,这是一个完全不同的参数:

https://linux.die.net/man/1/ld

  

-f名称   --auxiliary = name创建ELF共享库时,将内部DT_AUXILIARY字段设置为指定的名称。这告诉动态   链接器,共享对象的符号表应用作   共享对象名称的符号表上的辅助过滤器。如果你   稍后将程序与此过滤器对象链接,然后在运行时   在程序中,动态链接器将看到DT_AUXILIARY字段。如果   动态链接器解析过滤器对象中的所有符号,   首先将检查共享库中是否有定义   名称。如果有一个,将使用它代替在   过滤器对象。共享对象名称不必存在。就这样   共享对象名称可用于提供替代方法   某些功能的实现,可能用于调试或用于   机器的特定性能。

     

可以多次指定此选项。 DT_AUXILIARY条目   将按照它们在命令行中出现的顺序创建。

关于其他问题:

  

NDK r20有2个sysctl.h实例,NDK r17c有1个实例,但是它们都在名为sys的目录中。

我刚刚提交了https://github.com/android-ndk/ndk/issues/1068,但不确定是否会解决该问题。显然不鼓励使用它。修复不使用的源可能是更好的选择。

答案 1 :(得分:0)

我目前正在尝试与您做相同的事情。显然,这个家伙(不是我)设法用NDK r20编译ffmpeg4.2。到目前为止,它似乎可以与ARCH=armv7a

一起使用

[Youtube] https://www.youtube.com/watch?v=RP8SEAhcq5M [Github] https://github.com/binglingziyu/ffmpeg-android-build

[P.s。我没有足够的声誉来发表评论...所以是的...]