前提介绍:
a.加上extern "C"后,会指示编译器这部分代码按C语言(而不是C++)的方式进行编译
b.https://developer.android.google.cn/ndk/guides/android_mk:官方Android.mk介绍指南
c.看动态库的依赖库有哪些: $ndk64Readelf -d libplay.so
d.看动态库定义的方法:$ndkNm64 -D libplay.soo
e.compile 4 steps :(gcc xxx.c -o xxx)
gcc -E xxx.c -o xxx.i 预处理
gcc -S xxx.i -o xxx.s 汇编
gcc -c xxx.s -o xxx.o 机器代码编译
gcc -C xxx.o -o xxx.a 链接(为了可执行)
run it : ./xxx.a or ./xxx
EScC
export zzm="zengzeming"
export ndkClang="/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang"
export ndkLink="--sysroot=/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/sysroot"
export ndkAr="/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar"
export ndkNm="/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/bin/arm-linux-androideabi-nm"
export ndkClang64="/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android29-clang++"
export ndkAr64="/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar"
export ndkNm64="/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-nm
"
export ndk64Readelf="/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-readelf"
export shell="/bin/bash"
~
1.Cmake
# 导入动态库-->版本有区别,两种方式可尝试导入动态库
#add_library(play SHARED IMPORTED)
#set_target_properties(play PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libplay.so)#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}") #c编译器
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/jniLibs/${CMAKE_ANDROID_ARCH_ABI}") #c++编译器
#message("-------------------------->${CMAKE_SOURCE_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI}")
三方动态库不在src/main/jniLinbs下面,需要重新在app的build.gradle下指定三方库的目录如:
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jni/jniLibs']
}
}
如果测试自己交叉编译的动态库有用到libc++_shared.so,运行时又找不到,需要在app build.gradle下做如下配置(cmake):
externalNativeBuild{
cmake{
arguments "-DANDROID_STL=c++_shared" //配置
abiFilters "arm64-v8a"
}
}
(ndkBuild):在Application.mk下面配置(和Android.mk所在目录一致):
APP_STL := c++_shared
target_link_libraries{
-Wl,--start-grop
这里的静态库可以不用按照链接下顺序来摆放
-Wl,--end-grop
}
2.Android.mk
把三方库放在src/main/jniLibs下,报more than one file .....lib/arm64-v8a/...so 就把库放在其他位置,应该是Android studio 自己编译配置的路径有冲突问题,就把库放其他位置就行(我测试的是Android8.0)
交叉编译要加上-soname 指定链接so库名字,不加可能会报找不到库。$ndkClang64 $ndkLink -fPIC-shared -Wl,-soname,libplay.so play.c -o libplay.so
(-Wl选项告诉编译器将后面的参数传递给链接器。)还有注意编译方式extern "C"以c方式编译。以防报未定义问题。
3.linux上简单编译c/c++的杂记:
ar rcs -o libadd.a add.o(二进制打包成静态库)格式:(ar rcs -o [目标文件] [源文件][源文件])
gcc main.c -o main -L . -ladd(链接静态库)格式:-L链接库的目录 -l库的名字(和动态库链接是一样的)
ar t lib.. 查看静态库包含哪些o文件
ldd 查看链接了哪些库
clang -shared -fPIC hello.c -o libhello.so(打包动态库)(ldconfig:了一个动态链接库,若想使其被系统共享,可以执行一下”ldconfig 目录名”这个命令。
此命令的功能在于让ldconfig将指定目录下的动态链接库被系统共享起来,
意即:在缓存文件/etc/ld.so.cache中追加进指定目录下的共享库。)
readelf -d .so看库的依赖库有哪些
nm -D .so看so里面的源文件涉及到的函数
4.看手机的cpu架构:adb shell getprop ro.product.cpu.abi
5.mk官方参考:https://developer.android.google.cn/ndk/guides/android_mk
6.编译普通的ffmpeg脚本(ffmpeg源码目录下执行 sh xxx.sh 或者/bin/bash xxx.sh):
#!/bin/bash
#define my var
NDKPATH=/zengzeming/ndk/android-ndk-r21-beta2
PREFIX=/zengzeming/ffmpeg/ffmpeg-4.2.2/ffmpegCompileOutFiles/arm64-v8a
COMPILETOOLSPATH=/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/bin
SYSROOTPATH=/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/sysroot
./configure \
--prefix=$PREFIX \
--enable-cross-compile \
--target-os=android \
--arch=aarch64 \
--cross-prefix=$COMPILETOOLSPATH/aarch64-linux-android29- \
--ar=$COMPILETOOLSPATH/aarch64-linux-android-ar \
--nm=$COMPILETOOLSPATH/aarch64-linux-android-nm \
--ranlib=$COMPILETOOLSPATH/aarch64-linux-android-ranlib \
--sysroot=$SYSROOTPATH \
--extra-cflags="-g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fno-limit-debug-info -fno-experimental-isel -fPIC" \
--disable-shared \
--enable-static \
--enable-small \
--disable-programs \
--disable-avdevice \
--disable-encoders \
--disable-muxers \
--disable-filters \
make clean
make install
7.带有rtmp的ffmpeg 脚本(ffmpeg源码目录下执行 sh xxx.sh 或者/bin/bash xxx.sh)
#!/bin/bash
#define my var
NDKPATH=/zengzeming/ndk/android-ndk-r21-beta2
PREFIX=/zengzeming/ffmpeg/ffmpeg-4.2.2/ffmpegCompileOutFiles/arm64-v8a_rtmp
COMPILETOOLSPATH=/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/bin
SYSROOTPATH=/zengzeming/ndk/android-ndk-r21-beta2/toolchains/llvm/prebuilt/linux-x86_64/sysroot
RTMPPATH=/zengzeming/ffmpeg/rtmp/rtmpSource/rtmpdump1/arm64-v8a
./configure \
--prefix=$PREFIX \
--enable-cross-compile \
--target-os=android \
--arch=aarch64 \
--cross-prefix=$COMPILETOOLSPATH/aarch64-linux-android29- \
--ar=$COMPILETOOLSPATH/aarch64-linux-android-ar \
--nm=$COMPILETOOLSPATH/aarch64-linux-android-nm \
--strip=$COMPILETOOLSPATH/aarch64-linux-android-strip \
--ranlib=$COMPILETOOLSPATH/aarch64-linux-android-ranlib \
--sysroot=$SYSROOTPATH \
--extra-cflags="-g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fno-limit-debug-info -fno-experimental-isel -fPIC -I$RTMPPATH//include/librtmp" \
--extra-ldflags="-L$RTMPPATH/lib"
--extra-libs="-lrtmp"
--disable-shared \
--enable-static \
--enable-small \
--enable-librtmp \
--disable-programs \
--disable-avdevice \
--disable-encoders \
--disable-muxers \
--disable-filters \
make clean
make install
8.rtmp脚本编译(ibrtmp结合ffmpeg可操作直播流,也是在源码下执行 sh xxx.sh 或者/bin/bash xxx.sh):
#!/bin/bash
make clean && make install \
SYS=android \
prefix=/zengzeming/ffmpeg/rtmp/rtmpSource/rtmpdump/arm64-v8a \
CRYPTO= \
SHARED= \
XDEF=-DNO_SSL \
CC=$ndkClang64 \
LD= $ndkLd \
XCFLAGS=$ndkLink \
XLDFLAGS=$ndkLink \
AR=$ndkAr64
来源:oschina
链接:https://my.oschina.net/u/2987490/blog/3157722