Android 源碼本地編譯腳本 & 編譯Android系統

編譯系統的方法有很多種,使用Docker 或者是使用jenkins編譯,方法千萬種.網上有很多的方法,這裏就不再說了篇文章主要是針對本地編譯.

最近學習了腳本,也嘗試寫了一個Android系統編譯的腳本,重點分析一下腳本,算是對之前學習腳本的一個小小的總結.

1.一套Android源碼

2.Ubuntu環境 以及JDK環境

正常本地編譯步驟

1.source build/envsetup.sh

2.lunch xxx

3.make -j8 2>&1 |tee build.log (make就可以,這樣寫兩個目的:1.多核編譯 2.輸出編譯的log)

爲了偷懶,也爲了自己學的腳本有用武之地,寫了一個 腳本進行編譯,放到源碼根目錄使用方法如下:

./androidbuild.sh  all/systemimg/bootimg userdebug/user

./androidbuild.sh  all/systemimg/bootimg userdebug/user clean

androidbuild.sh 內容如下:

主要邏輯還是用的版本編譯步驟,只是簡化成了腳本

TARGET="msm8953_64" 這個需要改變成你想要的版本前綴

#!/bin/bash
##############################編譯Android 系統腳本######################################
# 設置編譯環境變量
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin:$PATH

#設置所在目錄
export ROOT_PATH=$(pwd)
#設置編譯的版本  
TARGET="msm8953_64"

#查看CUP 處理個數 最大允許4核

cpu_count=`cat /proc/cpuinfo |grep processor|wc -l`
if [ "$cpu_count" -gt "4" ];then
	cpu_count=4
fi

# 設置編譯環緩存文件
setup_ccache() {
    export CCACHE_DIR=../.ccache
    export USE_CCACHE=1
}

#刪除編譯緩存
delete_ccache() {
    prebuilts/misc/linux-x86/ccache/ccache -C
    rm -rf $CCACHE_DIR
}

create_ccache() {
    echo -e "\nINFO: Setting CCACHE with 10 GB\n"
    setup_ccache
    delete_ccache
    prebuilts/misc/linux-x86/ccache/ccache -M 10G
}

# 校驗使用腳本輸入的參數變量
if [ $# -eq 0 ]; then
    echo -e "ERROR: Missing argument: build param\n"
	echo -e "eg:[Donot make clean] ./androidbuild.sh all/systemimg/bootimg userdebug/user"
	echo -e "eg:[make clean]       ./androidbuild.sh all/systemimg/bootimg userdebug/user clean"
    exit 1
fi
# 校驗使用腳本輸入的參數變量
if [ $# -gt 3 ]; then
    echo -e "\nERROR: Extra inputs. \n"
    exit 1
fi

#創建文件保存編譯log
if [ -z $LOG_FILE ]; then
    LOG_FILE=$TARGET-$2
	echo $LOG_FILE
fi

#環境預熱 也就是普通編譯的第一步
source ./build/envsetup.sh

#設置 lunch 的目標版本
if [ "$2" == "eng" -o "$2" == "userdebug" -o "$2" == "user" ]; then
	lunch $TARGET-$2
else
	echo -e "Error: Wrong inputs. please input eng/userdebug/user"
	exit 1
fi

#是否清除上一次的編譯緩存 進行重新編譯
if [ "$3" == "clean" ]; then
    echo -e "\nINFO: Notice make clean!!!!!!!!\n"
	for time in {10..1}
	do
		echo -e "\nINFO: Make Clean in $time ..."
		sleep 1
	done
    # 執行 clean操作
	make clean
else
    # 如果不是 刪除上次生成好的編譯文件
	rm -rf out/target/product/msm8953_64/system/
	rm -rf out/target/product/msm8953_64/kernel
	rm -rf out/target/product/msm8953_64/*.zip
	rm -rf out/target/product/msm8953_64/obj/PACKAGING/target_files_intermediates/*
	rm -rf out/target/product/msm8953_64/*.img
	rm -rf out/target/product/msm8953_64/*.bin
	rm -rf out/target/product/msm8953_64/*.txt
fi

# 執行 更新api 主要針對對framework進行了修改的操作,不然系統識別不到你的新更改
make update-api -j$cpu_count

# 分爲三個編譯 主要使用的是make命令
# 編譯鏡像
if [ "$1" == "systemimg" ]; then
    echo -e "\nINFO: Build systemimage for $TARGET\n"
    make systemimage -j$cpu_count  | tee $LOG_FILE.log
# 編譯boot
elif [ "$1" == "bootimg" ]; then
    echo -e "\nINFO: Build bootimage for $TARGET\n"
    make bootimage -j$cpu_count | tee $LOG_FILE.log
# 編譯全部
elif [ "$1" == "all" ]; then
    echo -e "\nINFO: Build all image and otapackage for $TARGET\n"
    make -j$cpu_count  | tee $LOG_FILE-img.log
    make otapackage -j$cpu_count  | tee $LOG_FILE-ota.log
else
	echo -e "Error: Wrong inputs. please input all/ota/systemimg/bootimg"
	exit 1
fi

# 上一條命令執行後退出的狀態  正常退出返回 0 非正常退出返回 1
if [ ! $? -eq 0 ]; then
    echo "make error"
    exit -1
fi

#後面爲編譯完成後的操作
############################保存編譯文件的存放文件夾###################################
yourdate=`date +%Y_%m_%d`
echo $yourdate

local_backuppath=$ROOT_PATH"/IMAGES_"$yourdate
echo $local_backuppath
mkdir -p $local_backuppath

###########################將編譯好的文件拷貝到上面的文件夾########################################
cp out/target/product/msm8953_64/$TARGET*.zip $local_backuppath
cp out/target/product/msm8953_64/*.img $local_backuppath
cp out/target/product/msm8953_64/obj/PACKAGING/target_files_intermediates/$TARGET*.zip  $local_backuppath
echo "######## 拷貝完成 ########"

if false; then
############################保存編譯的app 到 APPVERSION.txt 
  僅僅是用於查看 apk 列表########################################
APKPATH=$ROOT_PATH"/out/target/product/msm8953_64/system/app"
echo "print log to APPVERSION.txt"

app_lists=`find $APKPATH | grep ".apk" | grep -vE "Bluetooth|CertInstaller|HTMLViewer|KeyChain|Wallpapers|MDummyAPK|MTv|UserDictionaryProvider|PacProcessor"`

APPVERSION=$local_backuppath/AppVersion.txt
# 如果 AppVersion.txt 存在則爲上次編譯的文件 執行刪除操作
if [ -f $APPVERSION ];then
	rm $APPVERSION
fi

PROPPATH=$ROOT_PATH"/out/target/product/msm8953_64/system/build.prop"
#用等號分割 獲取 ro.build.date.utc 版本
utc=`cat $PROPPATH | grep "ro.build.date.utc" | awk -F "=" '{print $2}'`
# 用等號分割 獲取 ro.build.description版本
description=`cat $PROPPATH | grep "ro.build.description=" | awk -F "=" '{print $2}'`
# 將以上信息存儲到 AppVersion.txt
echo ">>>>>>>" > $APPVERSION
echo "utc="$utc >> $APPVERSION
echo "description="$description >> $APPVERSION
echo "<<<<<<<" >> $APPVERSION

for app in $app_lists
do
    #    echo $app
    info=`out/host/linux-x86/bin/aapt dump badging $app  | grep -E "package: name=|application: label="`
    apkName=`echo $app | awk -F"/" '{print $NF}'`
    appName=`echo $info | grep "application: label=" | awk -F"label=" '{print $NF}' | awk -F"'" '{print $2}'`
    packageName=`echo $info | grep "package: name=" | awk -F"'" '{print $2}'`
	versionCode=`echo $info | grep "versionCode=" | awk -F"'" '{print $4}'`
    versionName=`echo $info | grep "versionName=" | awk -F"'" '{print $6}'`
# 將本地編譯好的 APP 信息寫入 AppVersion.txt 僅僅是用於查看
    echo "apkName="$apkName >> $APPVERSION
    echo "appName="$appName >> $APPVERSION
    echo "packageName="$packageName >> $APPVERSION
    echo "versionCode="$versionCode >> $APPVERSION
    echo "versionName="$versionName >> $APPVERSION
    echo "-----------------------------\n"  >> $APPVERSION
done
fi

可以根據自己意願進行修改

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章