#! /usr/bin/env bash
#
# Copyright (C) 2013-2014 Bilibili
# Copyright (C) 2013-2014 Zhang Rui <[email protected]>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#下面这句我认为是错误的,应该是if [ -z "$ANDROID_SDK" -o -z "$ANDROID_NDK" ]; then
#-z判断是否我空 -o 是or或者的意思
if [ -z "$ANDROID_NDK" -o -z "$ANDROID_NDK" ]; then
echo "You must define ANDROID_NDK, ANDROID_SDK before starting."
echo "They must point to your NDK and SDK directories.\n"
exit 1
fi
#REQUEST_TARGET 我们要编译的平台比如arm64 armv7a all等
REQUEST_TARGET=$1
REQUEST_SUB_CMD=$2
ACT_ABI_32="armv5 armv7a x86"
ACT_ABI_64="armv5 armv7a arm64 x86 x86_64"
ACT_ABI_ALL=$ACT_ABI_64
#UNAME_Smac电脑最后为Darwin
UNAME_S=$(uname -s)
#下面这段会形成-j+线程的数目,我的电脑最后会形成-j8
FF_MAKEFLAGS=
if which nproc >/dev/null
then
FF_MAKEFLAGS=-j`nproc`
elif [ "$UNAME_S" = "Darwin" ] && which sysctl >/dev/null
then
FF_MAKEFLAGS=-j`sysctl -n machdep.cpu.thread_count`
fi
do_sub_cmd () {
SUB_CMD=$1
if [ -L "./android-ndk-prof" ]; then
rm android-ndk-prof
fi
#android-ndk-prof会形成一个软连接
#最后的命令会执行ndk-build -j线程的数目
if [ "$PARAM_SUB_CMD" = 'prof' ]; then
echo 'profiler build: YES';
ln -s ../../../../../../ijkprof/android-ndk-profiler/jni android-ndk-prof
else
echo 'profiler build: NO';
ln -s ../../../../../../ijkprof/android-ndk-profiler-dummy/jni android-ndk-prof
fi
case $SUB_CMD in
prof)
$ANDROID_NDK/ndk-build $FF_MAKEFLAGS
;;
clean)
$ANDROID_NDK/ndk-build clean
;;
rebuild)
$ANDROID_NDK/ndk-build clean
$ANDROID_NDK/ndk-build $FF_MAKEFLAGS
;;
*)
$ANDROID_NDK/ndk-build $FF_MAKEFLAGS
;;
esac
}
#如果我们target是arm64,那么我们就会进入ijkplayer/ijkplayer-arm64/src/main/jni目录,最后执行ndk-build命令
do_ndk_build () {
PARAM_TARGET=$1
PARAM_SUB_CMD=$2
case "$PARAM_TARGET" in
armv5|armv7a)
cd "ijkplayer/ijkplayer-$PARAM_TARGET/src/main/jni"
do_sub_cmd $PARAM_SUB_CMD
cd -
;;
arm64|x86|x86_64)
cd "ijkplayer/ijkplayer-$PARAM_TARGET/src/main/jni"
if [ "$PARAM_SUB_CMD" = 'prof' ]; then PARAM_SUB_CMD=''; fi
do_sub_cmd $PARAM_SUB_CMD
cd -
;;
esac
}
case "$REQUEST_TARGET" in
"")
do_ndk_build armv7a;
;;
armv5|armv7a|arm64|x86|x86_64)
do_ndk_build $REQUEST_TARGET $REQUEST_SUB_CMD;
;;
all32)
for ABI in $ACT_ABI_32
do
do_ndk_build "$ABI" $REQUEST_SUB_CMD;
done
;;
all|all64)
for ABI in $ACT_ABI_64
do
do_ndk_build "$ABI" $REQUEST_SUB_CMD;
done
;;
clean)
for ABI in $ACT_ABI_ALL
do
do_ndk_build "$ABI" clean;
done
;;
*)
echo "Usage:"
echo " compile-ijk.sh armv5|armv7a|arm64|x86|x86_64"
echo " compile-ijk.sh all|all32"
echo " compile-ijk.sh all64"
echo " compile-ijk.sh clean"
;;
esac
以target是arm64为例,
最后是在ijkplayer/ijkplayer-arm64/src/main/jni下执行最后执行ndk-build命令。
我们进入ijkplayer/ijkplayer-arm64/src/main/jni看下里面的mk文件
android/ijkplayer/ijkplayer-arm64/src/main/jni/Application.mk
# Copyright (c) 2013-2014 Bilibili
# copyright (c) 2013-2014 Zhang Rui <[email protected]>
#
# This file is part of ijkPlayer.
#
# ijkPlayer is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# ijkPlayer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with ijkPlayer; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
APP_OPTIM := release #在release模式下,将编译生成被优化了的二进制的机器码,而debug模块用来生成便于调试的未被优化的二进制机器码。
APP_PLATFORM := android-21 #编译平台
APP_ABI := arm64-v8a #cpu架构
NDK_TOOLCHAIN_VERSION=4.9 #gcc版本
APP_PIE := false
APP_STL := stlport_static #使用STLport作为静态库
#c语言编译参数
APP_CFLAGS := -O3 -Wall -pipe \
-ffast-math \
-fstrict-aliasing -Werror=strict-aliasing \
-Wno-psabi -Wa,--noexecstack \
-DANDROID -DNDEBUG
Android.mk
# Copyright (c) 2013 Bilibili
# copyright (c) 2013 Zhang Rui <[email protected]>
#
# This file is part of ijkPlayer.
#
# ijkPlayer is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# ijkPlayer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with ijkPlayer; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
LOCAL_PATH := $(call my-dir)
MY_APP_JNI_ROOT := $(realpath $(LOCAL_PATH))
MY_APP_PRJ_ROOT := $(realpath $(MY_APP_JNI_ROOT)/..)
MY_APP_ANDROID_ROOT := $(realpath $(MY_APP_PRJ_ROOT)/../../../..)
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
MY_APP_FFMPEG_OUTPUT_PATH := $(realpath $(MY_APP_ANDROID_ROOT)/contrib/build/ffmpeg-armv7a/output)
MY_APP_FFMPEG_INCLUDE_PATH := $(realpath $(MY_APP_FFMPEG_OUTPUT_PATH)/include)
endif
ifeq ($(TARGET_ARCH_ABI),armeabi)
MY_APP_FFMPEG_OUTPUT_PATH := $(realpath $(MY_APP_ANDROID_ROOT)/contrib/build/ffmpeg-armv5/output)
MY_APP_FFMPEG_INCLUDE_PATH := $(realpath $(MY_APP_FFMPEG_OUTPUT_PATH)/include)
endif
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
MY_APP_FFMPEG_OUTPUT_PATH := $(realpath $(MY_APP_ANDROID_ROOT)/contrib/build/ffmpeg-arm64/output)
MY_APP_FFMPEG_INCLUDE_PATH := $(realpath $(MY_APP_FFMPEG_OUTPUT_PATH)/include)
endif
ifeq ($(TARGET_ARCH_ABI),x86)
MY_APP_FFMPEG_OUTPUT_PATH := $(realpath $(MY_APP_ANDROID_ROOT)/contrib/build/ffmpeg-x86/output)
MY_APP_FFMPEG_INCLUDE_PATH := $(realpath $(MY_APP_FFMPEG_OUTPUT_PATH)/include)
endif
ifeq ($(TARGET_ARCH_ABI),x86_64)
MY_APP_FFMPEG_OUTPUT_PATH := $(realpath $(MY_APP_ANDROID_ROOT)/contrib/build/ffmpeg-x86_64/output)
MY_APP_FFMPEG_INCLUDE_PATH := $(realpath $(MY_APP_FFMPEG_OUTPUT_PATH)/include)
endif
include $(call all-subdir-makefiles)
定义不同cpu架构ffmpeg库的位置,然后include $(call all-subdir-makefiles)编译每个子目录
通过下面的图片
可以知道 android-ndk-profiler 生成了静态库
ffmpeg是动态库
ijkmedia又是调用子目录
最后我们发现ijkplayer,ijksdl是include $(BUILD_SHARED_LIBRARY)动态库
其余是include $(BUILD_STATIC_LIBRARY)静态库
所以最后我们输出的是三个动态so