【发布时间】:2019-08-27 19:47:27
【问题描述】:
我正在尝试使用 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 上使用 Android NDK r17c 为 API 级别 14 构建了 FFMPEG 4.0.2。
我将 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。我运行了make 和make install,构建成功。
所以我的问题是,是否有可以传递给configure 的 ffmpeg 选项,这些选项将生成一个无需修改即可成功构建的 config.h?
编辑:来自 config.log 的其他信息。
似乎configure 中的check_mathfunc 对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 不能与它一起使用,这似乎很奇怪。
用 -shared 替换 -pie 似乎可以修复 config.h 文件,但现在我在构建 libavutil 期间得到了 'sys/sysctl.h' file not found。 NDK r20 有 2 个 sysctl.h 实例,NDK r17c 有 1 个实例,但它们都不在名为 sys 的目录中。
编辑 3:我将把它归结为 FFMPEG configure 脚本中的一个错误。 configure 通过生成一个使用该函数的小源文件然后编译和链接生成的文件来检查函数是否存在。如果出现任何故障,该功能将不可用。对于 NDK r17c,check_func sysctl 失败并且构建排除了sysctl 功能。由于某种原因,NDK r20 的测试成功,因为check_func 不验证sys/sysctl.h 是否存在,它只是原型sysctl() 并调用它。我通过向configure 添加一个名为check_sysfunc 的函数来解决这个问题,该函数试图包含sys/sysctl.h。我现在克服了这个错误,并有了一个关于隐式声明无效的新错误。我不得不假设这也是configure 的一个缺陷,希望不会有太多这样的情况。
【问题讨论】:
标签: ffmpeg android-ndk