引用静态库报错
error: ../../../../libs//libavcodec.a(allcodecs.o): incompatible target error: ../../../../libs//libavcodec.a(avpicture.o): incompatible target error: ../../../../libs//libavcodec.a(decode.o): incompatible target error: ../../../../libs//libavcodec.a(utils.o): incompatible target error: ../../../../libs//libavformat.a(allformats.o): incompatible target error: ../../../../libs//libavformat.a(options.o): incompatible target error: ../../../../libs//libavformat.a(utils.o): incompatible target error: ../../../../libs//libavutil.a(channel_layout.o): incompatible target error: ../../../../libs//libavutil.a(frame.o): incompatible target error: ../../../../libs//libavutil.a(mem.o): incompatible target error: ../../../../libs//libavutil.a(samplefmt.o): incompatible target
翻译过来就是目标不兼容。
于是又翻过头去查找之前编译的问题。
重新编译FDK-AAC
发现其实在编译过程中有报错,通过修改了下源码编译通过了。
重新编译FFmpeg
重新一点点得分析编译Log,确定没有报错出现,再把生成的.a文件导入到AS里,还是有如下错误:
FAILED: cmd.exe /C "cd . && D:\Android\Sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=armv7-none-linux-androideabi --gcc-toolchain=D:/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 --sysroot=D:/Android/Sdk/ndk-bundle/sysroot -fPIC -isystem D:/Android/Sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=19 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -frtti -fexceptions -std=c++11 -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++ --sysroot D:/Android/Sdk/ndk-bundle/platforms/android-19/arch-arm -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--fix-cortex-a8 -Wl,--exclude-libs,libunwind.a -LD:/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libaudiodecoder.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\armeabi-v7a\libaudiodecoder.so CMakeFiles/audiodecoder.dir/src/main/cpp/Mp3Decoder.cpp.o CMakeFiles/audiodecoder.dir/src/main/cpp/ffmpegmp3decoder.cpp.o CMakeFiles/audiodecoder.dir/src/main/cpp/mp3decoder_controller.cpp.o ../../../../libs//libavcodec.a ../../../../libs//libavdevice.a ../../../../libs//libavfilter.a ../../../../libs//libavformat.a ../../../../libs//libavutil.a ../../../../libs//libswresample.a ../../../../libs//libswscale.a -llog -latomic -lm "D:/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a" "D:/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++abi.a" "D:/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libandroid_support.a" "D:/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libunwind.a" "-ldl" && cd ." ../../../../libs//libavformat.a(utils.o):utils.c:function update_stream_avctx: error: undefined reference to 'av_parser_close' ../../../../libs//libavformat.a(utils.o):utils.c:function free_stream: error: undefined reference to 'av_parser_close' ../../../../libs//libavformat.a(utils.o):utils.c:function parse_packet: error: undefined reference to 'av_parser_parse2' ../../../../libs//libavformat.a(utils.o):utils.c:function parse_packet: error: undefined reference to 'av_parser_close' ../../../../libs//libavformat.a(utils.o):utils.c:function ff_read_frame_flush: error: undefined reference to 'av_parser_close' ../../../../libs//libavformat.a(utils.o):utils.c:function read_frame_internal: error: undefined reference to 'av_parser_init' ../../../../libs//libavformat.a(utils.o):utils.c:function avformat_find_stream_info: error: undefined reference to 'av_parser_init' ../../../../libs//libavformat.a(utils.o):utils.c:function avformat_find_stream_info: error: undefined reference to 'avcodec_pix_fmt_to_codec_tag' ../../../../libs//libavformat.a(utils.o):utils.c:function avformat_find_stream_info: error: undefined reference to 'avpriv_get_raw_pix_fmt_tags' ../../../../libs//libavformat.a(utils.o):utils.c:function av_apply_bitstream_filters: error: undefined reference to 'av_bitstream_filter_filter' ../../../../libs//libavformat.a(id3v2.o):id3v2.c:function id3v2_read_internal.part.0: error: undefined reference to 'uncompress' ../../../../libs//libavformat.a(rtmpproto.o):rtmpproto.c:function rtmp_open: error: undefined reference to 'inflateInit_' ../../../../libs//libavformat.a(rtmpproto.o):rtmpproto.c:function rtmp_open: error: undefined reference to 'inflate' ../../../../libs//libavformat.a(rtmpproto.o):rtmpproto.c:function rtmp_open: error: undefined reference to 'inflateEnd' clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
经过一番分析,在一篇文章中我发现是cMakeLists.txt中的target_link_libraries问题,静态链接库是有顺序的。*target_link_libraries里库文件的顺序符合gcc链接顺序的规则,即被依赖的库放在依赖它的库的后面。这一点很重要,通过调整链接库的顺序,解决了一大半的报错。
然而还是有下面的报错:
> Build command failed. Error while executing process D:\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build G:\NDKProject\Mp3Encoder\.cxx\cmake\debug\armeabi-v7a --target audiodecoder} [1/1] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\armeabi-v7a\libaudiodecoder.so FAILED: cmd.exe /C "cd . && D:\Android\Sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=armv7-none-linux-androideabi --gcc-toolchain=D:/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 --sysroot=D:/Android/Sdk/ndk-bundle/sysroot -fPIC -isystem D:/Android/Sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=19 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -frtti -fexceptions -std=c++11 -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++ --sysroot D:/Android/Sdk/ndk-bundle/platforms/android-19/arch-arm -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--fix-cortex-a8 -Wl,--exclude-libs,libunwind.a -LD:/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libaudiodecoder.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\armeabi-v7a\libaudiodecoder.so CMakeFiles/audiodecoder.dir/src/main/cpp/Mp3Decoder.cpp.o CMakeFiles/audiodecoder.dir/src/main/cpp/ffmpegmp3decoder.cpp.o CMakeFiles/audiodecoder.dir/src/main/cpp/mp3decoder_controller.cpp.o ../../../../libs//libavformat.a ../../../../libs//libavdevice.a ../../../../libs//libavfilter.a ../../../../libs//libavcodec.a ../../../../libs//libavutil.a ../../../../libs//libswresample.a ../../../../libs//libswscale.a -llog -latomic -lm "D:/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a" "D:/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++abi.a" "D:/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libandroid_support.a" "D:/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libunwind.a" "-ldl" && cd ." ../../../../libs//libavformat.a(id3v2.o):id3v2.c:function id3v2_read_internal.part.0: error: undefined reference to 'uncompress' ../../../../libs//libavformat.a(rtmpproto.o):rtmpproto.c:function rtmp_open: error: undefined reference to 'inflateInit_' ../../../../libs//libavformat.a(rtmpproto.o):rtmpproto.c:function rtmp_open: error: undefined reference to 'inflate' ../../../../libs//libavformat.a(rtmpproto.o):rtmpproto.c:function rtmp_open: error: undefined reference to 'inflateEnd' clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation) ninja: build stopped: subcommand failed.
参考jni封装ffmpeg接口遇到的错误修改方法,原来是ffmpeg4.0中依赖了libz库,书中使用的ffmpeg2.8版本的还没有依赖,该库是系统库,所以可以直接使用。于是修改cMakeLists.txt如下:
target_link_libraries(audiodecoder z) //首先链接libz库 target_link_libraries(audiodecoder avformat) target_link_libraries(audiodecoder avdevice) target_link_libraries(audiodecoder avfilter) target_link_libraries(audiodecoder avcodec) target_link_libraries(audiodecoder avutil) target_link_libraries(audiodecoder swresample) target_link_libraries(audiodecoder swscale)
又解决了一部分报错。
还剩下一个报错:
../../../../libs//libavformat.a: error adding symbols: File in wrong format
原来是因为gradle配置问题,参考Android Studio 解决:error adding symbols: File in wrong format clang++.exe: error: linker command failed with exit code 1,于是修改gradle如下:
defaultConfig { applicationId "com.flyscale.mp3encoder" minSdkVersion 19 compileSdkVersion(26) targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { cppFlags " -frtti -fexceptions -std=c++11 " abiFilters 'armeabi-v7a', 'arm64-v8a' cFlags "-DSTDC_HEADERS" } } //指定CPU架构过滤,注意如果你使用的NDK版本大于17,要使用armeabi-v7a,因为如ndk17以后主不支持armeabi了 ndk{ abiFilters 'armeabi-v7a' } }
如果你使用的NDK大于17会报错如下:
Error:ABIs [arm64-v8a] are not supported for platform. Supported ABIs are [armeabi, armeabi-v7a
解决方法就是指明armeabi-v7a等,参[Error:ABIs [arm64-v8a] are not supported for platform. Supported ABIs are armeabi, armeabi-v7a
至此解决了关于NDK编译的问题。