Reputation: 544
I have been trying to compile ffmpeg into a static library in order to use it in my android application, but i couldn't get it to work.
Im working with FFmpeg 3.2.4, and ndk r13b, using bash on windows 10(Ubuntu 14.04).
Here is what i did:
I made a stand alone toolchain for x86_64 and api 21 using:
python make_standalone_toolchain.py --api 21 --arch x86_64 --install-dir {}
Made a configuration script:
./configure \
--target-os=android \
--arch=x86_64 \
--prefix=/home/david/ffmpeg_x86_64_build \
--cross-prefix=/home/david/x86_64_toolchain/bin/x86_64-linux-android-\
--sysroot=/home/david/x86_64_toolchain/sysroot \
--enable-cross-compile \
--pkg-config-flags="--static" \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-doc \
--disable-htmlpages \
--disable-manpages \
--disable-podpages \
--disable-txtpages \
--extra-cflags="-fPIC" \
--extra-cxxflags="-fPIC"
--disable-shared --enable-static \
--enable-yasm
make
make install
It produced an FFmpeg executable, however when i ran it on my API 23 emulator, i got an error message:error: only position independent executables (PIE) are supported.
Even that i used -fPic
How can i fix it ? Also i'm not sure about my configuration, there wasn't up to date sources on how to compile it correctly for every ABI (arm,arm64,x86,x86_64,mips,mips64) that i need for my application. I have seen many script, and im not too familiar with compiling native code, so i wasn't sure what settings i need, for example like C flags and etc.
To be precise on how i tried to configure FFmpeg :
I would greatly appreciate some help on how to configure and compile this correctly.
Thanks to @Alex Cohn i have been able to compile ffmpeg, however i couldn't get it to compile using --enable-ssl however i have been faced with a problem.
Since we are providing a system root, the compiler won't look for files on my host machine, so we will need need to compile ssl for android from source. I have used this library OpenSSL-For-Android, and used the precompiled library.
I added to the configure file these lines:
--extra-cflags='-m32 -fPIE -I./OpenSSL-For-Android/openssl-1.0.2j/include' \
--extra-ldflags='-m32 -Wl,-eh-frame-hdr -Wl,-m,elf_i386 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -fPIE -pie -L./OpenSSL-For-Android/openssl-1.0.2j/lib/x86'
I tried telling the config, that it should search for the headers of openssl here, and that it should link against this library here.
But it fails on this test as stated on config.log:
BEGIN /tmp/ffconf.JVeoLDmr.c
1 extern int SSL_library_init();
2 int main(void){ SSL_library_init(); }
END /tmp/ffconf.JVeoLDmr.c
/home/david/ndk/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-linux-android-gcc --sysroot=/home/david/ndk/platforms/android-9/arch-x86/ -isysroot /home/david/ndk/platforms/android-9/arch-x86/ -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Dstrtod=avpriv_strtod -DPIC -m32 -fPIE -I./OpenSSL-For-Android/openssl-1.0.2j/include -std=c99 -fomit-frame-pointer -fPIC -pthread -c -o /tmp/ffconf.x5yr8e11.o /tmp/ffconf.JVeoLDmr.c
/home/david/ndk/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-linux-android-gcc -m32 -Wl,-eh-frame-hdr -Wl,-m,elf_i386 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -fPIE -pie -L./OpenSSL-For-Android/openssl-1.0.2j/lib/x86 --sysroot=/home/david/ndk/platforms/android-9/arch-x86/ -isysroot /home/david/ndk/platforms/android-9/arch-x86/ -Wl,--as-needed -Wl,-z,noexecstack -o /tmp/ffconf.mxzx6kFL /tmp/ffconf.x5yr8e11.o -lssl -lcrypto -lws2_32 -lgdi32 -lm -pthread
/home/david/ndk/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: error: cannot find -lssl
/home/david/ndk/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: error: cannot find -lws2_32
/home/david/ndk/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: error: cannot find -lgdi32
/tmp/ffconf.x5yr8e11.o:ffconf.JVeoLDmr.c:function main: error: undefined reference to 'SSL_library_init'
And it seems like it doesn't use the precompiled shared library i passed it(since it's compiled for Android) and doesn't find another instance of openssl, since the sysroot is the Android AOSP one (this is what I am thinking, please correct me if I'm wrong - I'm not experienced enough in this field ) . How can this be fixed ? I have seen some setups with PKG-Config, but i have no clue as how to configure it correctly.
Upvotes: 2
Views: 1896
Reputation: 57203
Try this command line for armeabi-v7a:
../../ffmpeg/configure --target-os=linux --enable-cross-compile \
--enable-pthreads --enable-small \
--arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp \
--enable-armv5te --enable-inline-asm \
--enable-neon --enable-thumb --enable-fast-unaligned --enable-runtime-cpudetect \
--cross-prefix=%NDK_ROOT%/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi- \
--sysroot=%NDK_ROOT%/platforms/android-9/arch-arm/ \
--disable-everything --disable-doc --disable-shared --disable-avdevice \
--disable-postproc --disable-network --disable-iconv --disable-zlib --disable-ffplay --disable-ffprobe --disable-ffserver --disable-swscale-alpha \
--enable-demuxer='h264,matroska,mpegts,rawvideo,mpegps,yuv4mpegpipe,flv,mov,mpegvideo,nut,avi' \
--enable-filter='scale,fps,framestep,pad,crop' --enable-protocol='file,pipe' \
--enable-muxer='h264,rawvideo,yuv4mpegpipe,matroska,mpegts,mp4,mov,nut,avi' \
--enable-bsf=h264_mp4toannexb --enable-parser=mpeg4video \
--enable-encoder=rawvideo --enable-decoder=rawvideo \
--extra-cflags='-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -fPIE' \
--extra-ldflags='-fPIE -pie'
And this for x86:
../../ffmpeg/configure --target-os=linux --enable-cross-compile \
--enable-pthreads --enable-small \
--arch=x86 --enable-runtime-cpudetect --enable-yasm \
--cross-prefix=%NDK_ROOT%/toolchains/x86-4.9/prebuilt/windows-x86_64/bin/i686-linux-android- \
--sysroot=%NDK_ROOT%/platforms/android-9/arch-x86/ \
--disable-everything --disable-doc --disable-shared --disable-avdevice \
--disable-postproc --disable-network --disable-iconv --disable-zlib --disable-ffplay --disable-ffprobe --disable-ffserver --disable-swscale-alpha \
--enable-demuxer='h264,matroska,mpegts,rawvideo,mpegps,yuv4mpegpipe,flv,mov,mpegvideo,nut,avi' \
--enable-filter='scale,fps,framestep,pad,crop' --enable-protocol='file,pipe' \
--enable-muxer='h264,rawvideo,yuv4mpegpipe,matroska,mpegts,mp4,mov,nut,avi' \
--enable-bsf=h264_mp4toannexb --enable-parser=mpeg4video \
--enable-encoder=rawvideo --enable-decoder=rawvideo \
--extra-cflags='-m32 -fPIE' \
--extra-ldflags='-m32 -Wl,-eh-frame-hdr -Wl,-m,elf_i386 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -fPIE -pie'
I prefer to run configure not from the ffmpeg directory, but rather from obj/local/armeabi-v7a
and obj/local/x86
- this way I can keep the object files in separate directories, and can make for different ABI without running ./configure again. I don't need NDK standalone toolchain here.
You need yasm to compile for x86. The set of --enable- flags suit my current needs, not necessarily your needs.
Upvotes: 3