WebRTC从m73~m74之间的某个提交开始,安卓编译出来的静态库使用时会报如下错误:
gngenout/android_arm/Debug--args=--args='target_os="android"target_cpu="arm"'ninja-Cout/android_arm/Debugwebrtc:webrtc编译完毕后,静态库路径为out/android_arm/Debug/obj/webrtc/libwebrtc.a。
findwebrtc-name"*.h"|xargs-I{}cp--parents{}
cmake_minimum_required(VERSION3.4.1)set(CWD${CMAKE_CURRENT_LIST_DIR})add_library(try-webrtcSHAREDsrc/main/cpp/try-webrtc.cpp)include_directories(libs/webrtc/include)add_definitions(-DWEBRTC_POSIX=1-DWEBRTC_ANDROID=1-DWEBRTC_LINUX=1)#Includelibrariesneededfortry-webrtclibtarget_link_libraries(try-webrtcandroidlog${CWD}/libs/webrtc/lib/libwebrtc.a)要点:
android{//...defaultConfig{//...ndk.abiFilters=['armeabi-v7a']externalNativeBuild{cmake{arguments=['-DANDROID_TOOLCHAIN=clang','-DANDROID_STL=c++_shared']cppFlags'-std=c++11-fno-rtti'}}}externalNativeBuild{cmake{path"CMakeLists.txt"}}//...}要点:
安卓系统默认只提供了一个非常简单的C++运行时环境:system。它不包含STL、异常、RTTI等特性,那我们的代码里面就不能使用这些特性,例如不能使用std::string或者std::vector,不能使用try-catch,不能使用typeid操作符。不过好在NDK提供了其他辅助的运行时环境,它们能提供不同的STL实现,异常和RTTI支持。
如何选择运行时环境,主要考虑两个问题:哪个STL实现?静态还是动态?
选择哪个STL实现,可以参考以下方面:
由于我们这里并不追求极致的稳定性,当然更主要还是因为WebRTC是用libc++编译的,所以我选用了libc++这一运行时环境。前面就已经提到,我们必须使用libc++runtime,否则会报一大堆undefinedreference错误,这是因为各个运行时库的二进制接口并不兼容,编译的时候混用STL实现,很容易遇到undefinedreference错误。
最后,依赖库可以动态与静态混用,只要编译使用的STL一致即可,而C++运行时库其实也是我们的依赖库,因此我们使用静态还是动态版本,与其他依赖库没有直接关系,即使用c++_shared或者c++_static与其他的依赖库没有直接关系。
很多开源项目提供的都是利用Autotools构建,即./autogen.sh&&./configure&&makeinstall的方式,但这样编出来的库目标平台并不是安卓,无法直接用于NDK开发。如果直接使用这样编出来的静态库,编译时可能会报错noarchivesymboltable(runranlib)。
cd/vagrant/restclient-cpp-0.4.4envPATH=/vagrant/standalone-r15c-arm-libc++/bin:$PATH\CC=arm-linux-androideabi-clang\CXX=arm-linux-androideabi-clang++\RANLIB=arm-linux-androideabi-ranlib\LD=arm-linux-androideabi-ld\AR=arm-linux-androideabi-ar\CROSS_COMPILE=arm-linux-androideabi\./configure--host=arm-linux-androideabi\--target=arm-linux-androideabi\--prefix=`pwd`/out#编辑Makefile,增加-I/vagrant/curl-7.55.1/out/includeenvPATH=/vagrant/standalone-r15c-arm-libc++/bin:$PATH\CC=arm-linux-androideabi-clang\CXX=arm-linux-androideabi-clang++\RANLIB=arm-linux-androideabi-ranlib\LD=arm-linux-androideabi-ld\AR=arm-linux-androideabi-ar\CROSS_COMPILE=arm-linux-androideabi\makeinstalllibcurl.a:
cd/vagrant/curl-7.55.1envPATH=/vagrant/standalone-r15c-arm-libc++/bin:$PATH\CC=arm-linux-androideabi-clang\CXX=arm-linux-androideabi-clang++\RANLIB=arm-linux-androideabi-ranlib\LD=arm-linux-androideabi-ld\AR=arm-linux-androideabi-ar\CROSS_COMPILE=arm-linux-androideabi\./configure--host=arm-linux-androideabi\--target=arm-linux-androideabi\--prefix=`pwd`/outenvPATH=/vagrant/standalone-r15c-arm-libc++/bin:$PATH\CC=arm-linux-androideabi-clang\CXX=arm-linux-androideabi-clang++\RANLIB=arm-linux-androideabi-ranlib\LD=arm-linux-androideabi-ld\AR=arm-linux-androideabi-ar\CROSS_COMPILE=arm-linux-androideabi\makeinstalllibz.a:
cd/vagrant/zlib-1.2.11envPATH=/vagrant/standalone-r15c-arm-libc++/bin:$PATH\CC=arm-linux-androideabi-clang\CXX=arm-linux-androideabi-clang++\RANLIB=arm-linux-androideabi-ranlib\LD=arm-linux-androideabi-ld\AR=arm-linux-androideabi-ar\CROSS_COMPILE=arm-linux-androideabi\./configure--prefix=`pwd`/outenvPATH=/vagrant/standalone-r15c-arm-libc++/bin:$PATH\CC=arm-linux-androideabi-clang\CXX=arm-linux-androideabi-clang++\RANLIB=arm-linux-androideabi-ranlib\LD=arm-linux-androideabi-ld\AR=arm-linux-androideabi-ar\CROSS_COMPILE=arm-linux-androideabi\makeinstall2018.06.03Update:zlib不需要自己编译,安卓系统已经带着了,在target_link_libraries里增加z即可。