mac上编译一些iOS最新版本第三方库的脚本--ffmpeg, fdk-aac, x264, libcurl, opessl

󰃭 2019-04-02

1. 编译 ffmpeg 相关库脚本

  1. 没有用到脚本内自动下载 ffmpeg 源代码,自己下载的最近的 4.1 版本代码
  2. 把脚本放在源代码目录下编译,最后生成的 FFmpeg-iOS 目录放在ios项目目录下
  3. 在项目中添加头文件查找路径,增加编译库
  4. 注意依赖关系,先编译 x264,fdk-acc(如果使用的话), 最后编译 ffmpeg,根据实际情况修改 ffmpeg 编译脚本中的路径

1.1 fdk-acc 库

版本 fdk-aac-2.0.0

#!/bin/sh

CONFIGURE_FLAGS="--enable-static --with-pic=yes --disable-shared --disable-debug"

ARCHS="x86_64 armv7 armv7s arm64"

# 源文件名
SOURCE="fdk-aac-2.0.0"
FAT="fdk-aac-ios"

SCRATCH="scratch"
# thin当前脚本下的自定义文件,用于接收编译后的头文件和静态库
THIN=`pwd`/"thin"

COMPILE="y"
LIPO="y"

if [ "$*" ]
then
    if [ "$*" = "lipo" ]
    then
        # skip compile
        COMPILE=
    else
        ARCHS="$*"
        if [ $# -eq 1 ]
        then
            # skip lipo
            LIPO=
        fi
    fi
fi

if [ "$COMPILE" ]
then
    CWD=`pwd`
    for ARCH in $ARCHS
    do
        echo "building $ARCH..."
        mkdir -p "$SCRATCH/$ARCH"
        cd "$SCRATCH/$ARCH"

        CFLAGS="-arch $ARCH"

        if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]
        then
            PLATFORM="iPhoneSimulator"
            CPU=
            if [ "$ARCH" = "x86_64" ]
            then
                CFLAGS="$CFLAGS -mios-simulator-version-min=7.0"
            HOST="--host=x86_64-apple-darwin"
            else
                CFLAGS="$CFLAGS -mios-simulator-version-min=7.0"
            HOST="--host=i386-apple-darwin"
            fi
        else
            PLATFORM="iPhoneOS"
            if [ $ARCH = arm64 ]
            then
                HOST="--host=aarch64-apple-darwin"
                    else
                HOST="--host=arm-apple-darwin"
                fi
            CFLAGS="$CFLAGS -fembed-bitcode"
        fi

        XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
        CC="xcrun -sdk $XCRUN_SDK clang -Wno-error=unused-command-line-argument-hard-error-in-future"
        AS="$CWD/$SOURCE/extras/gas-preprocessor.pl $CC"
        CXXFLAGS="$CFLAGS"
        LDFLAGS="$CFLAGS"

        $CWD/$SOURCE/configure \
            $CONFIGURE_FLAGS \
            $HOST \
            $CPU \
            CC="$CC" \
            CXX="$CC" \
            CPP="$CC -E" \
                    AS="$AS" \
            CFLAGS="$CFLAGS" \
            LDFLAGS="$LDFLAGS" \
            CPPFLAGS="$CFLAGS" \
            --prefix="$THIN/$ARCH"

        make -j4 install
        cd $CWD
    done
fi

if [ "$LIPO" ]
then
    echo "building fat binaries..."
    mkdir -p $FAT/lib
    set - $ARCHS
    CWD=`pwd`
    cd $THIN/$1/lib
    for LIB in *.a
    do
        cd $CWD
        lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB
    done

    cd $CWD
    cp -rf $THIN/$1/include $FAT
fi

1.2 编译 x264 视频编解码库

**版本 从git 获取的最新源代码 **

#!/bin/sh

CONFIGURE_FLAGS="--enable-static --enable-pic --disable-cli"

ARCHS="arm64 x86_64 armv7 armv7s"

# directories
SOURCE="x264"
FAT="x264-iOS"

SCRATCH="scratch-x264"
# must be an absolute path
THIN=`pwd`/"thin-x264"

COMPILE="y"
LIPO="y"

if [ "$*" ]
then
	if [ "$*" = "lipo" ]
	then
		# skip compile
		COMPILE=
	else
		ARCHS="$*"
		if [ $# -eq 1 ]
		then
			# skip lipo
			LIPO=
		fi
	fi
fi

if [ "$COMPILE" ]
then
	CWD=`pwd`
	for ARCH in $ARCHS
	do
		echo "building $ARCH..."
		mkdir -p "$SCRATCH/$ARCH"
		cd "$SCRATCH/$ARCH"
		CFLAGS="-arch $ARCH"
                ASFLAGS=

		if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]
		then
		    PLATFORM="iPhoneSimulator"
		    CPU=
		    if [ "$ARCH" = "x86_64" ]
		    then
		    	CFLAGS="$CFLAGS -mios-simulator-version-min=7.0"
		    	HOST=
		    else
		    	CFLAGS="$CFLAGS -mios-simulator-version-min=5.0"
			HOST="--host=i386-apple-darwin"
		    fi
		else
		    PLATFORM="iPhoneOS"
		    if [ $ARCH = "arm64" ]
		    then
		        HOST="--host=aarch64-apple-darwin"
			XARCH="-arch aarch64"
		    else
		        HOST="--host=arm-apple-darwin"
			XARCH="-arch arm"
		    fi
                    CFLAGS="$CFLAGS -fembed-bitcode -mios-version-min=7.0"
                    ASFLAGS="$CFLAGS"
		fi

		XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
		CC="xcrun -sdk $XCRUN_SDK clang"
		if [ $PLATFORM = "iPhoneOS" ]
		then
		    export AS="$CWD/$SOURCE/tools/gas-preprocessor.pl $XARCH -- $CC"
		else
		    export -n AS
		fi
		CXXFLAGS="$CFLAGS"
		LDFLAGS="$CFLAGS"

		CC=$CC $CWD/$SOURCE/configure \
		    $CONFIGURE_FLAGS \
		    $HOST \
		    --extra-cflags="$CFLAGS" \
		    --extra-asflags="$ASFLAGS" \
		    --extra-ldflags="$LDFLAGS" \
		    --prefix="$THIN/$ARCH" || exit 1

		make -j4 install || exit 1
		cd $CWD
	done
fi

if [ "$LIPO" ]
then
	echo "building fat binaries..."
	mkdir -p $FAT/lib
	set - $ARCHS
	CWD=`pwd`
	cd $THIN/$1/lib
	for LIB in *.a
	do
		cd $CWD
		lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB
	done

	cd $CWD
	cp -rf $THIN/$1/include $FAT
fi

1.3 编译ffmpeg

版本 ffmpeg-4.1

#!/bin/sh

# directories
FF_VERSION="4.1"
#FF_VERSION="snapshot-git"
if [[ $FFMPEG_VERSION != "" ]]; then
  FF_VERSION=$FFMPEG_VERSION
fi
SOURCE="ffmpeg-$FF_VERSION"
FAT="FFmpeg-iOS"

SCRATCH="scratch-ffmpeg"
# must be an absolute path
THIN=`pwd`/"thin-ffmpeg"

# absolute path to x264 library
X264=`pwd`/../x264-iOS

# FDK_AAC=`pwd`/../fdk-aac-ios

CONFIGURE_FLAGS="--enable-cross-compile --disable-debug --disable-programs \
                 --disable-doc --enable-pic --enable-small \
                 --disable-decoders --enable-decoder=flv,matroska,aac,mp2,mp3,mp4,h264,mjpeg,mpeg2video,mpeg4 \
                 --enable-decoder=mpegvideo,mpegtsraw,mpegts,mpegps \
                 --disable-demuxers \
                 --enable-demuxer=flv,mp2,mp3,mp4,h264,y4m,matroska,rm,rmvb,wav,acc,hls,mov,m4v,avi,pcm_s16le,rawvideo \
                 --disable-muxers \
                 --enable-muxer=flv,mp2,mp3,mp4,h264,y4m,matroska,rm,rmvb,wav,acc,hls,mov,m4v,avi,pcm_s16le,rawvideo \
                 --disable-encoders --enable-encoder=aac,mpeg4,libx264 \
                 --disable-filters \
                 --enable-filter=transpose \
                 --enable-bsf=aac_adtstoasc \
                 --enable-gpl \
                 --enable-libx264"

if [ "$X264" ]
then
	CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-gpl --enable-libx264"
fi

if [ "$FDK_AAC" ]
then
	CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-libfdk-aac --enable-nonfree"
fi

# avresample
#CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-avresample"

ARCHS="arm64 armv7 x86_64 armv7s"

COMPILE="y"
LIPO="y"

DEPLOYMENT_TARGET="8.0"

if [ "$*" ]
then
	if [ "$*" = "lipo" ]
	then
		# skip compile
		COMPILE=
	else
		ARCHS="$*"
		if [ $# -eq 1 ]
		then
			# skip lipo
			LIPO=
		fi
	fi
fi

if [ "$COMPILE" ]
then
	if [ ! `which yasm` ]
	then
		echo 'Yasm not found'
		if [ ! `which brew` ]
		then
			echo 'Homebrew not found. Trying to install...'
                        ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" \
				|| exit 1
		fi
		echo 'Trying to install Yasm...'
		brew install yasm || exit 1
	fi
	if [ ! `which gas-preprocessor.pl` ]
	then
		echo 'gas-preprocessor.pl not found. Trying to install...'
		(curl -L https://github.com/libav/gas-preprocessor/raw/master/gas-preprocessor.pl \
			-o /usr/local/bin/gas-preprocessor.pl \
			&& chmod +x /usr/local/bin/gas-preprocessor.pl) \
			|| exit 1
	fi

	if [ ! -r $SOURCE ]
	then
		echo 'FFmpeg source not found. Trying to download...'
		curl http://www.ffmpeg.org/releases/$SOURCE.tar.bz2 | tar xj \
			|| exit 1
	fi

	CWD=`pwd`
	for ARCH in $ARCHS
	do
		echo "building $ARCH..."
		mkdir -p "$SCRATCH/$ARCH"
		cd "$SCRATCH/$ARCH"

		CFLAGS="-arch $ARCH"
		if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]
		then
		    PLATFORM="iPhoneSimulator"
		    CFLAGS="$CFLAGS -mios-simulator-version-min=$DEPLOYMENT_TARGET"
		else
		    PLATFORM="iPhoneOS"
		    CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET -fembed-bitcode"
		    if [ "$ARCH" = "arm64" ]
		    then
		        EXPORT="GASPP_FIX_XCODE5=1"
		    fi
		fi

		XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
		CC="xcrun -sdk $XCRUN_SDK clang"

		# force "configure" to use "gas-preprocessor.pl" (FFmpeg 3.3)
		if [ "$ARCH" = "arm64" ]
		then
		    AS="gas-preprocessor.pl -arch aarch64 -- $CC"
		else
		    AS="gas-preprocessor.pl -- $CC"
		fi

		CXXFLAGS="$CFLAGS"
		LDFLAGS="$CFLAGS"
		if [ "$X264" ]
		then
			CFLAGS="$CFLAGS -I$X264/include"
			LDFLAGS="$LDFLAGS -L$X264/lib"
		fi
		if [ "$FDK_AAC" ]
		then
			CFLAGS="$CFLAGS -I$FDK_AAC/include"
			LDFLAGS="$LDFLAGS -L$FDK_AAC/lib"
		fi

		TMPDIR=${TMPDIR/%\/} $CWD/$SOURCE/configure \
		    --target-os=darwin \
		    --arch=$ARCH \
		    --cc="$CC" \
		    --as="$AS" \
		    $CONFIGURE_FLAGS \
		    --extra-cflags="$CFLAGS" \
		    --extra-ldflags="$LDFLAGS" \
		    --prefix="$THIN/$ARCH" \
		|| exit 1

		make -j4 install $EXPORT || exit 1
		cd $CWD
	done
fi

if [ "$LIPO" ]
then
	echo "building fat binaries..."
	mkdir -p $FAT/lib
	set - $ARCHS
	CWD=`pwd`
	cd $THIN/$1/lib
	for LIB in *.a
	do
		cd $CWD
		echo lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB 1>&2
		lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB || exit 1
	done

	cd $CWD
	cp -rf $THIN/$1/include $FAT
fi

echo Done

2. 编译 libcurl 相关库脚本

注意依赖关系,编译使用过程与上面 ffmpeg 的编译过程类似

2.1 编译 openssl

版本 openssl-1.1.1b

#!/bin/bash

TMP_DIR=/tmp/build_openssl_$$
CROSS_TOP_SIM="`xcode-select --print-path`/Platforms/iPhoneSimulator.platform/Developer"
CROSS_SDK_SIM="iPhoneSimulator.sdk"

CROSS_TOP_IOS="`xcode-select --print-path`/Platforms/iPhoneOS.platform/Developer"
CROSS_SDK_IOS="iPhoneOS.sdk"

export CROSS_COMPILE=`xcode-select --print-path`/Toolchains/XcodeDefault.xctoolchain/usr/bin/

function build_for ()
{
  PLATFORM=$1
  ARCH=$2
  CROSS_TOP_ENV=CROSS_TOP_$3
  CROSS_SDK_ENV=CROSS_SDK_$3

  make clean

  export CROSS_TOP="${!CROSS_TOP_ENV}"
  export CROSS_SDK="${!CROSS_SDK_ENV}"
  ./Configure $PLATFORM "-arch $ARCH -fembed-bitcode" no-asm no-ssl3 no-comp no-hw no-engine no-async --prefix=${TMP_DIR}/${ARCH} || exit 1
  # problem of concurrent build; make -j8
  make && make install_sw || exit 2
  unset CROSS_TOP
  unset CROSS_SDK
}

function pack_for ()
{
  LIBNAME=$1
  mkdir -p ${TMP_DIR}/lib/
  ${DEVROOT}/usr/bin/lipo \
	${TMP_DIR}/x86_64/lib/lib${LIBNAME}.a \
	${TMP_DIR}/armv7s/lib/lib${LIBNAME}.a \
	${TMP_DIR}/arm64/lib/lib${LIBNAME}.a \
	-output ${TMP_DIR}/lib/lib${LIBNAME}.a -create
}

curl -O https://raw.githubusercontent.com/sinofool/build-openssl-ios/master/patch-conf.patch
#cp ../patch-conf.patch .
patch Configurations/10-main.conf < patch-conf.patch

build_for ios64sim-cross x86_64 SIM || exit 2
build_for ios-cross armv7s IOS || exit 4
build_for ios64-cross arm64 IOS || exit 5

pack_for ssl || exit 6
pack_for crypto || exit 7

cp -r ${TMP_DIR}/armv7s/include ${TMP_DIR}/
curl -O https://raw.githubusercontent.com/sinofool/build-openssl-ios/master/patch-include.patch
#cp ../build-openssl-ios/patch-include.patch .
patch -p3 ${TMP_DIR}/include/openssl/opensslconf.h < patch-include.patch

DFT_DIST_DIR=${HOME}/Desktop/openssl-ios-dist/
DIST_DIR=${DIST_DIR:-$DFT_DIST_DIR}
mkdir -p ${DIST_DIR}
cp -r ${TMP_DIR}/include ${TMP_DIR}/lib ${DIST_DIR}

2.2 编译 libssh2

版本 libssh2-1.8.2

#!/bin/bash
VERSION="1.8.2"
#
###########################################################################
#
# Don't change anything here
SDKVERSION=`xcrun -sdk iphoneos --show-sdk-version`
CURRENTPATH=`pwd`
ARCHS="x86_64 armv7 armv7s arm64"
DEVELOPER=`xcode-select -print-path`
##########
set -e
if [ ! -e libssh2-${VERSION}.tar.gz ]; then
	echo "Downloading libssh2-${VERSION}.tar.gz"
    # curl -O https://www.libssh2.org/download/libssh2-${VERSION}.tar.gz
else
	echo "Using libssh2-${VERSION}.tar.gz"
fi

echo "Checking file: libssh2-${VERSION}.tar.gz"
# md5=`md5 -q libssh2-${VERSION}.tar.gz`
# if [ $md5 != "071004c60c5d6f90354ad1b701013a0b" ]
# then
# 	echo "File corrupt, please download again."
# 	exit 1
# else
# 	echo "Checksum verified."
# fi

mkdir -p bin
mkdir -p lib
mkdir -p src

for ARCH in ${ARCHS}
do
	if [[ "${ARCH}" == "i386" || "${ARCH}" == "x86_64" ]];
	then
		PLATFORM="iPhoneSimulator"
	else
		PLATFORM="iPhoneOS"
	fi
	echo "Building libssh2 for ${PLATFORM} ${SDKVERSION} ${ARCH}"
	echo "Please stand by..."

	export DEVROOT="${DEVELOPER}/Platforms/${PLATFORM}.platform/Developer"
	export SDKROOT="${DEVROOT}/SDKs/${PLATFORM}${SDKVERSION}.sdk"
    echo "DEVEROOT" ${DEVROOT}
    echo "SDKROOT" ${SDKROOT}

	export LD=${DEVROOT}/usr/bin/ld
	export CC=${DEVELOPER}/usr/bin/gcc
	export CXX=${DEVELOPER}/usr/bin/g++
	export AR=${DEVELOPER}/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar
	export AS=${DEVELOPER}/Toolchains/XcodeDefault.xctoolchain/usr/bin/as
	export NM=${DEVELOPER}/Toolchains/XcodeDefault.xctoolchain/usr/bin/nm
	export RANLIB=${DEVELOPER}/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib
	export LDFLAGS="-arch ${ARCH} -pipe -no-cpp-precomp -isysroot ${SDKROOT} -L${CURRENTPATH}/bin/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/lib -miphoneos-version-min=7.0"
	export CFLAGS="-arch ${ARCH} -pipe -no-cpp-precomp -isysroot ${SDKROOT} -I${CURRENTPATH}/bin/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/include -miphoneos-version-min=7.0"
	export CPPFLAGS="-arch ${ARCH} -pipe -no-cpp-precomp -isysroot ${SDKROOT} -I${CURRENTPATH}/bin/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/include -miphoneos-version-min=7.0"

	mkdir -p "${CURRENTPATH}/bin/${PLATFORM}${SDKVERSION}-${ARCH}.sdk"

	LOG="${CURRENTPATH}/bin/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/build-libssh2-${VERSION}.log"
	echo ${CURRENTPATH}/bin/${PLATFORM}${SDKVERSION}-${ARCH}.sdk

    echo "hello"
	HOST="${ARCH}"
	if [ "${ARCH}" == "arm64" ];
	then
		HOST="aarch64"
	fi

	if [ "$1" == "openssl" ];
	then
        echo "world"
		./configure --host=${HOST}-apple-darwin --prefix="${CURRENTPATH}/bin/${PLATFORM}${SDKVERSION}-${ARCH}.sdk" --with-openssl --with-libssl-prefix=/tmp/build_openssl_66969/${ARCH} --disable-shared --enable-static
	else
		./configure --host=${HOST}-apple-darwin --prefix="${CURRENTPATH}/bin/${PLATFORM}${SDKVERSION}-${ARCH}.sdk" --with-libgcrypt --with-libgcrypt-prefix=${CURRENTPATH}/bin/${PLATFORM}${SDKVERSION}-${ARCH}.sdk --disable-shared --enable-static  >> "${LOG}" 2>&1
	fi

	make
	make install
	cd ${CURRENTPATH}
	rm -rf src/libssh2-${VERSION}

done

echo "Build library..."
lipo -create ${CURRENTPATH}/bin/iPhoneSimulator${SDKVERSION}-x86_64.sdk/lib/libssh2.a ${CURRENTPATH}/bin/iPhoneOS${SDKVERSION}-armv7.sdk/lib/libssh2.a ${CURRENTPATH}/bin/iPhoneOS${SDKVERSION}-armv7s.sdk/lib/libssh2.a ${CURRENTPATH}/bin/iPhoneOS${SDKVERSION}-arm64.sdk/lib/libssh2.a -output ${CURRENTPATH}/lib/libssh2.a
mkdir -p ${CURRENTPATH}/include/libssh2
echo "Building done."

2.3 编译 curl

版本 curl-7.64.0

#!/bin/sh

 export OUTDIR=buildlib
 export IPHONEOS_DEPLOYMENT_TARGET="7.0"
 export CC=`xcrun -find -sdk iphoneos gcc`
 LIBSSH2=`pwd`/../libssh2-1.8.2

function build(){
 ARCH=$1
 HOST=$2
 SDKDIR=$3

 export CFLAGS="-arch ${ARCH} -pipe -Os -gdwarf-2 -DCURL_MAX_WRITE_SIZE=4194304 -isysroot ${SDKDIR} -miphoneos-version-min=${IPHONEOS_DEPLOYMENT_TARGET} -fembed-bitcode"

 export LDFLAGS="-arch ${ARCH} -isysroot ${SDKDIR}"

 # ./configure --host="${HOST}-apple-darwin" --disable-shared --enable-static --without-zlib --disable-smtp --disable-pop3 --disable-imap --disable-tftp --disable-telnet --disable-rtsp --disable-ldap
 ./configure --host="${HOST}-apple-darwin" --enable-static --enable-smb --with-darwinssl --with-libssh2=${LIBSSH2} --without-zlib

 make -j `sysctl -n hw.logicalcpu_max`
 cp lib/.libs/libcurl.a $OUTDIR/libcurl-${ARCH}.a

 make clean
}

 mkdir -p $OUTDIR

build armv7   armv7   `xcrun --sdk iphoneos --show-sdk-path`
build armv7s  armv7s  `xcrun --sdk iphoneos --show-sdk-path`
build arm64    arm    `xcrun --sdk iphoneos --show-sdk-path`
build x86_64  x86_64  `xcrun --sdk iphonesimulator --show-sdk-path`

 lipo -arch armv7 $OUTDIR/libcurl-armv7.a \
    -arch armv7s $OUTDIR/libcurl-armv7s.a \
    -arch arm64 $OUTDIR/libcurl-arm64.a \
    -arch x86_64 $OUTDIR/libcurl-x86_64.a \
    -create -output $OUTDIR/libcurl_all.a

 ls $OUTDIR```