编译系统的方法有很多种,使用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
可以根据自己意愿进行修改