如果是编译Mac OS或linux的ffmpeg库,是比较简单的,不存在交叉编译。直接在Mac OS 或linux的的执行以下命令(下载好ffmpeg的源码:http://ffmpeg.org/releases/ 且cd到源码路径为前提执行下面步骤)
第一步:./configure (后面可以跟其他选项,如果不跟 是默认配置,此命令功能是生成makefile文件,具体的选项后面会讲解到)
./configure --prefix=/Users/feng/third-src/FFmpeg/FFmpeg-dir
第二步:make 或make -j10 (j10是同时开10个线程执行,此命令是执行makefile文件生成二进制文件比如 *.o *.bin *.lib)
make -j10
第二步:make install (把生成的二进制文件安装到configure设置的prefix路径)
make install
看了上面的步骤,是不是觉得很简单,是的,在当前系统编译当前系统的库比较简单,需要的编译的环境工具等等都不要再设置,系统都会设置好了。但是可能configure时需要一些其他的库,根据日志提示安装需要安装的库。这里提供一下安装方:安装和卸载方法
下面讲解iOS和android ffmpeg编译configure,在MAC上编译(可能其他环境有一些不一样,楼主不敢肯定)
其实书写的脚本思路和上面编译步骤差不多,只不过需要指定编译工具编译环境或者需要链接一些第三方库等等。
当然还可以添加源码下载,iOS合并.a android的.a生成.so等等功能。
这里拿一个iOS的脚本来分析:
# 定义宏 用来开启openssl OPENSSL=`pwd`/openssl # 1.裁剪FFMPEG CONFIGURE_FLAGS="--disable-everything \ --disable-debug --disable-programs --disable-doc \ --enable-cross-compile \ --enable-pic --enable-protocol=file \ --enable-network \ --enable-protocol=http --enable-protocol=tcp --enable-protocol=hls \ --enable-parser=h264 --enable-parser=hevc --enable-parser=aac \ --enable-demuxer=h264 --enable-decoder=hevc --enable-demuxer=aac --enable-demuxer=hls \" #1.1.如果开启了openssl 需要增加的裁剪项目 if [ "$OPENSSL" ]; then CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-protocol=https \ --enable-openssl --enable-protocol=crypto --enable-protocol=tls_openssl" fi
#1.2.指定CPU架构,后面用到 ARCHS="arm64"
#1.3.指定支持目标平台的最小版本,后面用到 DEPLOYMENT_TARGET="8.0" for ARCH in $ARCHS do CFLAGS="-arch $ARCH" if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ];then #1.4.如果是模拟器版本,iOS平台SDK路径
PLATFORM="iPhoneSimulator"
CFLAGS="$CFLAGS -mios-simulator-version-min=$DEPLOYMENT_TARGET" else #1.5.如果是真机版本,iOS平台SDK路径
PLATFORM="iPhoneOS"
CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET -fembed-bitcode"
if [ "$ARCH" = "arm64" ];then
EXPORT="GASPP_FIX_XCODE5=1
fi fi
#1.6.如果是真机版本,iOS平台SDK路径 XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]' CC="xcrun -sdk $XCRUN_SDK clang" CXXFLAGS="$CFLAGS" LDFLAGS="$CFLAGS"
#1.7增加第三方库文件路径,openssl
if [ "$OPENSSL" ]
then
CFLAGS="$CFLAGS -I$OPENSSL_PATH/include"
LDFLAGS="$LDFLAGS -L$OPENSSL_PATH/lib"
fi
# 2.configure配置--->生成make file ./configure \ --target-os=darwin \ --arch=$ARCH \ --cc="$CC" \ $CONFIGURE_FLAGS \ --extra-cflags="$CFLAGS" \ --extra-cxxflags="$CXXFLAGS" \ --extra-ldflags="$LDFLAGS" \ --prefix=/Users/feng/third-src/FFmpeg/FFmpeg-iOS/$ARCH \ || exit make clean make -j3 make install $EXPORT || exit 1 cd $CWD done
详解+步骤如下:
1)裁剪
CONFIGURE_FLAGS //FFMPEG 裁剪
有几个常用的解释如下:
--disable-everything \ #禁止所有选项目
--disable-debug \ #禁止debug 调试,开启会有相应的打印,我一般mac下源码调试的时候会开启
--disable-programs \ #禁止生产执行bin程序,ffplay/ffmpeg/ffprobe/ffserver
--disable-doc \ #禁止说明文档share,里面有example列子
--enable-cross-compile \ #允许交叉编译,就是在非A平台编译A平台的库,如在macOS上编译iOS的库
更多请参考:http://blog.csdn.net/u010380485/article/details/54089918
2)设置目标平台系统
--target-os=$TARGET_OS //编译目标平台系统
iOS: TARGET_OS = darwin
android: TARGET_OS = linux
3)设置CPU架构
--arch=$ARCH // 编译支持的CPU架构
iOS:ARCH="arm64 armv7s armv7" //64位arm64和32位armv7s armv7
android:ARCH=arm || ARCH=aarch64 //64位 aarch64 和32位arm
补充一下: a) 就android我特意说明一下几点: android和和ios不一样,只能一个一个版本编译,所以我写了两个ARCH=,而不是ARCH="arm aarch64" 一般开始为了区分,32bits用armeabi表示(通用表示方法),其他的表示64bits 32bits和64bits的NDK路径不一样,不像ios,只要写前面一部分路径,自动识别
b)就ios而言,经常看到,ARCHS="arm64 armv7s armv7 x86_64 i386"
这个需要了解一下Apple移动设备处理器指令集相关的一些细节知识,现在就这做个简要的说明:
模拟器32位(即Mac处理器的指令集):i386、x86
模拟器64位(即Mac处理器的指令集):x86_64
真机32位(即ARM处理器的指令集):armv7、armv7s
真机64位(即ARM处理器的指令集):arm64
armv6、armv7、armv7s、arm64都是ARM处理器的指令集。这些指令集都是向下兼容的,如armv7指令集兼容armv6,只是使用armv6的时候无法发挥出其性能,无法使用armv7的新特性,从而会导致程序执行效率没那么高。
i386、x86_64都是Mac处理器的指令集。i386是针对intel通用微处理器32架构的。x86_64是针对x86架构的64位处理器。iOS模拟器没有arm指令集,所以当使用iOS模拟器的时候会遇到i386、x86_64。
参考资料:http://blog.csdn.net/potato512/article/details/52312565
3)设置编译工具和platform路径
iOS:
a)平台编译工具
--cc="$CC" //编译工具,iOS用Clang,android用gcc 当然gcc各平台也不一样
if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ];then
PLATFORM="iPhoneSimulator"
else
PLATFORM="iPhoneOS"
fi
XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
CC="xcrun -sdk $XCRUN_SDK clang"
备注:PLATFORM是系统自带设置好的环境变量,设置编译工具为Clang的时候,同时把OS的SDK路径也设置好了。(也有可能是在mac下设置的原因吧,如果在其他平台 可能需要设置sysroot和sysinclude吧,具体没有验证)
另外:iOS 开发中 Objective-C 和 Swift 都用的是 Clang / LLVM 来编译的。LLVM是一个模块化和可重用的编译器和工具链技术的集合,Clang 是 LLVM 的子项目,是 C,C++ 和 Objective-C 编译器,目的是提供惊人的快速编译,比 GCC 快3倍。
详细有关Clang:http://blog.csdn.net/vincentiss/article/details/54617915
b)platform SDK的路径
--sysroot=$PATH //平台SDK的路径
--sysinclude=$PATH //平台SDK头文件include的路径
ios只区分模拟和真机版本的SDK路径,CPU架构的不区分,自动识别,
真机版本路径,
PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
模拟器版本路径
PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/"
同时,iOS其实指定平台编译工具路径就能自动找到OS SDK路径了,所以也可以不设置sysroot和sysinclude。(也有可能是在mac下设置的原因吧,如果在其他平台 可能需要设置sysroot和sysinclude吧,具体没有验证)
android:
a)平台编译工具
--cc="$CC" //编译工具,android用gcc 当然可能还需要g++,ld,ar,strip等等
--cross-prefix=$CROSS_PREFIX // //编译工具前缀
export NDK=${NDK_PATH} //NDK_PATH 为NDK路径,环境变量已配置好NDK的android-ndk-r12的路径
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt
export CROSS_PREFIX=$PREBUILT/linux-x86/bin/arm-linux-androideabi-
export CC=$PREBUILT/linux-x86/bin/arm-linux-androideabi-gcc
1)备注这里只export gcc,也就是c工具,如果需要其他工具也需要export,例如需要g++和c++
export cxx=$PREBUILT/linux-x86/bin/arm-linux-androideabi-g++ //g++ (c++)
export ld=$PREBUILT/linux-x86/bin/arm-linux-androideabi-ld //g++ (c++)
2)链接这些工具有两种方式,一种是上面的,直接使用export
还有一种是:--cc="$CC" //CC为路径:$PREBUILT/linux-x86/bin/arm-linux-androideabi-gc
--cc="$C++"////C++为路径:PREBUILT/linux-x86/bin/arm-linux-androideabi-g++
b)platform NDK的路径
--sysroot=$PATH //平台NDK的路径
--sysinclude=$PATH //平台NDK头文件include的路径
ndk下platform就是各个平台的系统库了,这里选在android-14/arch-arm,那么路径为:
PATH=$NDK/platforms/android-14/arch-arm
这里只要指定一个平台的platform就好,不需要在分开指定此platform的lib和include
4) 设置第三方库文件
--extra-cxxflags="$CXXFLAGS" //C++库include文件路径
--extra-cflags="$CFLAGS" //C库include文件路径
--extra-ldflags="$LDFLAGS" //库 lib文件路径
把这三项分在一起,是因为三者相关联,
CFLAGS="-arch $ARCH"
CXXFLAGS="$CFLAGS"
LDFLAGS="$CFLAGS"
if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ];then
CFLAGS="$CFLAGS -mios-simulator-version-min=$DEPLOYMENT_TARGET"
else
CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET -fembed-bitcode"
if [ "$ARCH" = "arm64" ]
then
EXPORT="GASPP_FIX_XCODE5=1"
fi
fi
#增加第三方openssl库文件路径
if [ "$OPENSSL" ]
then
CFLAGS="$CFLAGS -I${OPENSSL_PATH}/include"
LDFLAGS="$LDFLAGS -L${OPENSSL_PATH}/lib"
fi
--extra-cflags="$CFLAGS" \
--extra-cxxflags="$CXXFLAGS" \
--extra-ldflags="$LDFLAGS" \
备注:1)如果你需要链接第三方库,比如openssl,除了上面的CONFIGURE_FLAGS裁剪需要打开相应的权限外,这里也需要添加第三方的头文件include和lib
2)查看二进制可执行文件引用的动态链接库(otool –L xxxx.dylib)(-L 一定要是大写)
查看二进制可执行文件中的OpenSSL版本号 把 .a 压缩成 .zip 之后用指令: unzip -p XXX.a.zip | strings | grep "OpenSSL" unzip -p libcrypto.a.zip |strings | grep "OpenSSL"
3)另外上面的OPENSSL_PATH我已在环境变量备注好,(如果没有设置可以上面也可以直接写地址)
vim ~/.bash_profile查看如下:
export NDK_PATH=/Users/feng/third-lib/android-ndk-r12
export OPENSSL_PATH=/Users/feng/third-lib/openssl
export PATH=$PATH:~/third-lib/gas-preprocessor-master
export PATH=$PATH:/Users/feng/third-lib/ffmpeg-lib/bin
5)设置安装路径
--prefix=xx //bulid后编译的库的安装路径,比如:--prefix=/Users/feng/third-src/FFmpeg/FFmpeg-iOS/$ARC
大概就这些吧,本想传个附件,但是传不了。
当然编译的过程会出现各种各样的问题,欢迎一起交流