我正在尝试使用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
。我分别运行make
和make 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
中也是一种缺陷,希望这些不会过多。
答案 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。我没有足够的声誉来发表评论...所以是的...]