makeMtk.perl java
#!/usr/bin/perl
my $DEBUG = 0; # enable/disable script debugging message node
setBuildEnvVars("./mbldenv.sh");
# End python
$myCmd = "makeMtk"; #$0 android
#space check for build path
$result = `pwd`;
@number = split(" ",$result);
die "****************************************************************************** \
You are building in a directory whose absolute path contains a space character: \
$result \
Please move your source tree to a path that does not contain any spaces. \
****************************************************************************** \
Directory names containing spaces not supported\n" if($#number != 0);
@keywords = ('\[','\]','\(','\)','\{','\}');
foreach $k (@keywords)
{
@number = split($k,$result);
die "****************************************************************************** \
You are building in a directory whose absolute path contains a special character: \
$result \
Please move your source tree to a path that does not contain \"$k\". \
****************************************************************************** \
Directory names containing spaces not supported\n" if($#number != 0);
}
$performanceChk = 0;
($performanceChk == 1) && print &CurrTimeStr . " Enter $myCmd\n"; git
@chkDirs = qw(mediatek mediatek/config mediatek/build/tools);
foreach $m (@chkDirs)
{
die "Folder \"$m\" does NOT exist!\nPlease help confirm Mediatek release package.\n" if (!-d $m);
} api
@arguments = ();
my $product = "";
$project = "";
$action = "";
@mOpts = ();
$ini = "makeMtk.ini";
$enINI = (-e $ini) ? 1 : 0;
(($#ARGV < 0) || (($#ARGV < 1) && (($enINI == 0) && (lc($ARGV[0]) !~ /^[listp|banyan_addon|banyan_addon_x86]/)))) && &Usage; app
$tee = "FALSE"; svn
# mapping table between flag in project name and corresponding product
my $products =
{
"phone" => "phone",
"ph" => "phone",
"tablet" => "tablet",
"tb" => "tablet",
"tv" => "tv",
"default" => "phone"
}; post
@actions =
qw(
new n bm_new remake r bm_remake clean c listproject listp
drvgen codegen emigen nandgen custgen javaoptgen ptgen run-preprocess remove-preprocessed
check-modem update-modem sign-image encrypt-image sign-modem check-dep
dump-memusage gen-relkey check-appres
rel-cust modem-info bindergen mrproper
); ui
my @ABSNativeActions =
qw(
customimage bootimage systemimage recoveryimage secroimage cacheimage factoryimage
userdataimage userdataimage-nodeps target-files-package
sdk win_sdk banyan_addon banyan_addon_x86 cts otapackage dist updatepackage
update-api mm snod dump-comp-build-info
);
push(@actions , @ABSNativeActions);
@modules = qw(android kernel dr k preloader pl lk);
@orgARGV = @ARGV ;
while ($#ARGV != -1)
{
if ($ARGV[0] =~ /^-(t|te|tee)/)
{
$tee = "TRUE";
}
elsif ($ARGV[0] =~ /^-h|help/)
{
&Usage;
}
elsif ($ARGV[0] =~ /^-(o|op|opt)=(.*)$/)
{
@mOpts = split(",", $2);
}
elsif ($ARGV[0] =~ /^-smart$/)
{
unshift(@mOpts, "MTK_DEPENDENCY_AUTO_CHECK=true");
}
elsif ($ARGV[0] =~ /^(listp|listproject)/)
{
&p_system("perl mediatek/build/tools/listP.pl");
exit 0;
}
elsif ($ARGV[0] =~ /check-env|chk-env/)
{
&chkMustEnv;
exit 0;
}
else
{
if (-e $ARGV[0])
{
$is_new = "false";
foreach $temp (@ARGV)
{
if ($temp eq "n" || $temp eq "new")
{
$is_new = "true";
}
}
if ($is_new eq "true")
{
system("./sndmk.pl $ARGV[0]");
}
else
{
system("./sndmk.pl $ARGV[0] r");
}
$project = lc(&get_project_name($ARGV[0]));
}
else
{
$project = lc($ARGV[0]);
}
&sync_bootanim_to_target($project);
&sync_lk_and_taget_proucct_mk_file($project);
&auto_generated_artifacts_by_target_product($project);
$project = "generic" if ($project eq "emulator");
if (!-e "mediatek/config/${project}/ProjectConfig.mk")
{
if (-e $ini)
{
open (FILE_HANDLE, "<$ini") or die "cannot open $ini\n";
while (<FILE_HANDLE>)
{
if (/^(\S+)\s*=\s*(\S+)/)
{
$keyname = $1;
$${keyname} = $2;
}
}
close FILE_HANDLE;
$project = lc($project);
die "Can NOT find project Makefile "
. "mediatek/config/${project}/ProjectConfig.mk from $ini\n"
if (!-e "mediatek/config/${project}/ProjectConfig.mk");
}
}
else
{
shift(@ARGV);
}
die "Can NOT recognize project Makefile "
. "mediatek/config/${project}/ProjectConfig.mk from command\n"
if (!-e "mediatek/config/${project}/ProjectConfig.mk");
$action = lc($ARGV[0]);
shift(@ARGV);
@arguments = @ARGV ;
@ARGV = ();
}
shift(@ARGV);
}
exit 1;
foreach $prj ("mediatek/config/${project}/ProjectConfig.mk", "mediatek/config/common/ProjectConfig.mk")
{
open (FILE_HANDLE, "<$prj") or die "cannot open $prj\n";
while (<FILE_HANDLE>)
{
if (/^(\S+)\s*=\s*(\S+)/)
{
$ENV{$1} = $2;
}
}
close FILE_HANDLE;
}
if (($project ne "banyan_addon") && ($project ne "banyan_addon_x86")) {
die "Lack off the action.\nIt should be one of (@actions)\nOr try $myCmd -h\n" if ($action eq "");
}
#p_system("perl mediatek/build/tools/flavor_configuration.pl $project $ENV{\"CUSTOM_KERNEL_LCM\"}");
#&writeINI;
my $flavor = "";
if ( $project =~ /\[(.*)\]/ )
{
$flavor = $1;
$project =~ s/\[(.*)\]//;
}
if ($project =~ /^(tablet)/ || $project =~ /_(ph|tb|tv|phone|tablet)$/)
{
my $key = (defined $1)? $1 : "default";
$product = $products->{$key};
}
@acts = split(",", $action);
foreach $uAct (@acts)
{
$isFound = 0;
foreach $sAct (@actions)
{
if ($uAct eq $sAct)
{
$isFound = 1;
last;
}
}
die "Unknown the action: $uAct.\nPlease use $myCmd -h, if you need help!\n" if ($isFound == 0);
if (($uAct eq "bm_remake") || ($uAct eq "bm_new"))
{
$uAct =~ s/^bm_//;
push(@mOpts, "-k");
}
if ($uAct eq "mm")
{
$MM_PATH = shift(@arguments);
die "the given path does not exist!" if (! -d $MM_PATH);
$snod = shift(@arguments) if ($#arguments == 0);
die "the target behind mm must be snod, not $snod" if (($snod ne "") && ($snod ne "snod"));
}
($uAct = "new") if ($uAct eq "n");
($uAct = "clean") if ($uAct eq "c");
($uAct = "remake") if ($uAct eq "r");
if (($uAct eq "remake") || ($uAct eq "bm_remake"))
{
unshift(@mOpts, "MTK_DEPENDENCY_AUTO_CHECK=true");
if (-e $ini)
{
open (FILE_HANDLE, "<$ini") or die "cannot open $ini\n";
while (<FILE_HANDLE>)
{
if (/^(\S+)\s*=\s*(\S+)/)
{
$keyname = $1;
if ($keyname eq "build_mode") {$${keyname} = $2;}
}
}
foreach $i (@mOpts)
{
@temp = split("=","$i");
if ($temp[0] eq "TARGET_BUILD_VARIANT")
{
$TARGET_BUILD_VARIANT = $temp[1];
}
}
if ($TARGET_BUILD_VARIANT eq "") { $TARGET_BUILD_VARIANT = "eng"; }
if ($build_mode ne $TARGET_BUILD_VARIANT) { print "WARNING *** : Previous build is $build_mode build, and now is $TARGET_BUILD_VARIANT build\n"; }
}
}
}
&writeINI;
#print "@acts\n";
my $signSubStr;
if ($action eq "gen-relkey")
{
if ($#arguments >= 0)
{
die "Wrong command line arguments, do NOT set any more arguments after 'gen-relkey'.\n"
. "Please try $myCmd -h for help message.\n";
}
else
{
# get signature input
$signSubStr = inputSignSubject();
print "\nYour signature subject is '$signSubStr'\n";
}
}
else
{
my $i = 0;
if ($#arguments >= 0)
{
foreach $uMod (@arguments)
{
$isFound = 0;
foreach $sMod (@modules)
{
if ($uMod eq $sMod)
{
$isFound = 1;
last;
}
}
die "Unknown the module: $uMod.\n"
. "It should be one of (@modules)\nOr try $myCmd -h\n"
if ( ($isFound == 0) && ($arguments[$i - 1] !~ /[k|kernel|dr|android]/) );
($uMod = "preloader") if ($uMod eq "pl");
($uMod = "kernel") if ($uMod eq "k");
($uMod = "android") if ($uMod eq "dr");
if (($uMod eq "kernel") && ($arguments[$i + 1] =~ /^(.*)\//))
{
$KMOD_PATH = $arguments[$i + 1];
$KMOD_PATH =~ s/^kernel\///;
last;
}
if ($uMod eq "android")
{
$DR_MODULE = $arguments[$i + 1];
last;
}
$i += $i + 1;
}
}
else
{
@default_arguments = qw(preloader lk kernel android);
}
}
#logdir should sync with Makefile.yusu
$ENV{"MTK_PROJECT"} = $project;
my $actPttn = join('|', @actions);
if (join(' ', @acts) =~ /($actPttn)/ || $project eq "banyan_addon" || $project eq "banyan_addon_x86")
{
($performanceChk == 1) && print &CurrTimeStr . " run pwd\n";
chomp($mktopdir = `pwd`);
($performanceChk == 1) && print &CurrTimeStr . " finish pwd\n";
push(@mOpts, "ENABLE_TEE=$tee");
push(@mOpts, "PROJECT=$project");
push(@mOpts, "FLAVOR=$flavor");
push(@mOpts, "MKTOPDIR=$mktopdir");
push(@mOpts, "PRODUCT=$product");
if ($action ne "gen-relkey")
{
$logdir = "out/target/product";
&p_system("mkdir -p $logdir") if (!-d $logdir);
my $ABSActPttn = join('|',@ABSNativeActions);
if (join(' ', @acts) =~ /($ABSActPttn)/)
{
foreach my $act (@acts)
{
&p_system("rm -f $logdir/${project}_${act}.log");
&p_system("rm -f $logdir/${project}_${act}.log_err");
}
}
if (join(' ', @acts) =~ /(new|remake|clean)/)
{
@create_arguments = ($#arguments < 0) ? @default_arguments : @arguments;
foreach $uMod (@create_arguments)
{
#p_system("cat /dev/null > $logdir/${uMod}.log");
&p_system("rm -f $logdir/${project}_${uMod}.log");
&p_system("rm -f $logdir/${project}_${uMod}.log_err");
# &p_system("touch $logdir/${project}_${uMod}.log");
}
}
}
}
$cmdArg = "CMD_ARGU=\"@mOpts\"";
$makeCmd = "make -f mediatek/build/makemtk.mk $cmdArg @mOpts";
#print "$makeCmd\n";
$result = 0;
# gen. release key/certificate
if ($action eq "gen-relkey")
{
print "Start to generate release key/certificate for application signing...\n";
$result += &p_system("$makeCmd $action SIGNATURE_SUBJECT=$signSubStr");
(exit 255) if ($result >= 255);
exit $result;
}
$result += &p_system("$makeCmd banyan_addon") if($#acts == -1 && $project eq "banyan_addon");
$result += &p_system("$makeCmd banyan_addon_x86") if($#acts == -1 && $project eq "banyan_addon_x86");
foreach $uAct (@acts)
{
if (($uAct eq "codegen") || ($uAct eq "custgen"))
{
$result += &p_system("$makeCmd $uAct");
}
elsif ($uAct eq "mm")
{
$result += &p_system("$makeCmd $uAct SNOD=$snod MM_PATH=$MM_PATH");
}
else
{
if ($#arguments < 0)
{
if (${uAct} =~ /(new|remake|clean)/)
{
if ($uAct =~ /(new|remake)/)
{
&chkMustEnv;
&chkDep;
}
$result += &p_system("$makeCmd ${uAct}all");
}
else
{
$result += &p_system("$makeCmd $uAct CUR_MODULE=android");
}
}
else
{
foreach $uMod (@arguments)
{
&chkDep("$uMod");
if ( ($KMOD_PATH ne "") && ($uMod eq "kernel") )
{
$result += &p_system("$makeCmd $uAct CUR_MODULE=$uMod KMOD_PATH=$KMOD_PATH");
last;
}
elsif ( ($DR_MODULE ne "") && ($uMod eq "android") )
{
$result += &p_system("$makeCmd $uAct CUR_MODULE=$uMod DR_MODULE=$DR_MODULE");
last;
}
else
{
$result += &p_system("$makeCmd $uAct CUR_MODULE=$uMod");
}
}
}
}
}
($performanceChk == 1) && print &CurrTimeStr . " write ini\n";
($performanceChk == 1) && print &CurrTimeStr . " Exit $myCmd\n";
(exit 255) if ($result >= 255);
exit $result;
sub CurrTimeStr
{
my($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
return (sprintf "%4.4d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
}
sub Usage
{
warn << "__END_OF_USAGE";
Usage: (makeMtk|mk) [options] project actions [modules]
Options:
-t, -tee : Print log information on the standard-out.
-o, -opt=bypass_argument_to_make
: Pass extra arguments to make.
-h, -help : Print this message and exit.
Projects:
one of available projects.
Actions:
listp, listproject
: List all available projects.
check-env : Check if build environment is ready.
check-dep : Check feature dependency.
n, new : Clean and perform a full build.
c, clean : Clean the immediate files(such as, objects, libraries etc.).
r, remake : Rebuild(target will be updated if any dependency updats).
mrproper : Remove all generated files + config + various backup files in Kbuild process.
bm_new : "new" + GNU make's "-k"(keep going when encounter error) feature.
bm_remake : "remake" + GNU make's "-k"(keep going when encounter error) feature.
mm : Build module through Android native command "mm"
emigen : Generate EMI setting source code.
nandgen : Generate supported NAND flash device list.
codegen : Generate trace DB(for META/Cather etc. tools used).
drvgen : Generate driver customization source.
custgen : Generate customization source.
javaoptgen : Generate the global java options.
ptgen : Generate partition setting header & scatter file.
bindergen : Generate binder related information
sign-image : Sign all the image generated.
encrypt-image : Encrypt all the image generated.
update-api : Android default build action
(be executed if system setting or anything removed from API).
check-modem : Check modem image consistency.
upadte-modem : Update modem image located in system.img.
modem-info : Show modem version
gen-relkey : Generate releasekey for application signing.
check-appres : Check unused application resource.
sdk : Build sdk package.
win_sdk : Build sdk package with a few Windows tools.
banyan_addon : Build MTK sdk addon.
banyan_addon_x86 :Build MTK sdk x86 addon.
cts : Build cts package.
bootimage : Build boot image(boot.img).
cacheimage : Build cache image(cache.img).
systemimage : Build system image(system.img).
snod : Build system image without dependency.
(that is, ONLY pack the system image, NOT checking its dependencies.)
recoveryimage : Build recovery image(recovery.img).
secroimage : Build secro image(secro.img).
factoryimage : Build factory image(factory.img).
userdataimage : Build userdata image(userdata.img).
userdataimage-nodeps
: Build userdata image without dependency.
(that is, ONLY pack the userdata image, NOT checking its dependencies.)
target-files-package
: Build the target files package.
(A zip of the directories that map to the target filesystem.
This zip can be used to create an OTA package or filesystem image
as a post-build step.)
updatepackage : Build the update package.
dist : Build distribution package.
Modules:
pl, preloader : Specify to build preloader.
lk : Specify to build little kernel.
k, kernel : Specify to build kernel.
dr, android : Specify to build android.
NULL : Specify to build all components/modules in default.
k <module path>
: Specify to build kernel component/module with the source path.
dr <module name>
: Specify to build android component/module with module name.
Example:
./mk -t e1k emigen
: Generate EMI setting source code.
./mk -o=TARGET_BUILD_VARIANT=user e1k n
: Start a user mode full build.
./mk listp : List all available projects.
./mk e1k bootimage
: Build bootimage for e1k project.
./mk e1k bm_new k
: Build kernel for e1k project.
./makeMtk e1k c,bm_remake pl k
: Clean & Build preloader and kernel for e1k project.
./makeMtk e1k n k kernel/xxx/xxx
: Build(full build) kernel component/module
under the path "kernel/xxx/xxx" for e1k project.
./makeMtk e1k r dr Gallery
: Rebuild android module named Gallery for e1k project.
./makeMtk e1k mm packages/apps/Settings
: Change Directory to packages/apps/Settings and execute "mm"
__END_OF_USAGE
exit 1;
}
sub writeINI
{
@iniFields = qw(project build_mode);
open (FILE_HANDLE, ">$ini") or die "cannot open $ini\n";
foreach $m (@iniFields)
{
foreach $i (@mOpts)
{
@temp = split("=","$i");
if ($temp[0] eq "TARGET_BUILD_VARIANT")
{ $build_mode = $temp[1];}
}
if ($m eq "build_mode" && $build_mode eq "")
{
print FILE_HANDLE "$m = eng\n";
}
else
{
$value = $${m};
print FILE_HANDLE "$m = $value\n";
}
}
close FILE_HANDLE;
}
sub p_system
{
my ($cmd) = @_;
my ($debugp) = 0;
my $result;
($debugp != 0) && print("$cmd\n");
($performanceChk == 1) && print &CurrTimeStr . " system $cmd\n";
$result = system("$cmd");
($performanceChk == 1) && print &CurrTimeStr . " exit $cmd\n";
return $result;
}
sub chkMustEnv
{
my $result;
print "\n**********checking Env************\n";
&p_system("chmod 755 mediatek/build/tools/checkEnv.py");
$result = &p_system("python mediatek/build/tools/checkEnv.py -a >checkenv.log 2>&1");
if ($result == 0)
{
print " Your building environment is OK\n"
. " The detail information is in \"checkenv.log\"!\n"
. "*************************************************\n";
}
else
{
print "Please check your building environment First!\n\n";
if ($tee eq "TRUE")
{
system("cat checkenv.log");
}
else
{
open FILE, "<checkenv.log";
while(<FILE>)
{
print if(/FAIL|WARNING/);
}
close(FILE);
}
die "\n The detail information is in \"checkenv.log\"!\n"
. "***********************************************\n";
}
}
sub chkDep
{
my $module = $_[0];
my $string = $module;
if (!$module)
{
$string = all;
}
# print "*********************************\n \"$string\" Dependency Checking...\n";
my $result;
$result = &p_system("CUR_MODULE=$module make -f mediatek/build/makemtk.mk check-dep $cmdArg @mOpts > $logdir/${project}_check-dep.log 2>&1");
&p_system("cat $logdir/${project}_check-dep.log");
if ($result)
{
&p_system("cp -f $logdir/${project}_check-dep.log $logdir/${project}_check-dep.log_err");
die "Please check all dependency error First !!";
}
}
sub setBuildEnvVars
{
my $bldProfile = shift;
die "\"$bldProfile\" does NOT exist!\n" if (!-e $bldProfile);
# Todo: error handling for '. $bldProfile' command
my $envVarList = `. $bldProfile && env | grep ".*=.*"`;
map
{
chomp;
$ENV{$1}=$2 if (/(.*)=(.*)/);
} split(/\n/, $envVarList);
if ($DEBUG)
{
print "[START LOGGING]: Current build environment variables setting...\n";
print "PATH=$ENV{PATH}\n";
print "ANDROID_JAVA_HOME=$ENV{ANDROID_JAVA_HOME}\n";
print "JAVA_HOME=$ENV{JAVA_HOME}\n";
print "PYTHONPATH=$ENV{PYTHONPATH}\n";
print "[END LOGGING]\n";
}
}
# interactive mode for inputting signature subject
sub inputSignSubject
{
my $signature =
{
'0-C' => ['C', '', 'Country Name (2 letter code)'],
'1-ST' => ['ST', '', 'State or Province Name (full name)'],
'2-L' => ['L', '', 'Locality Name (eg, city)'],
'3-O' => ['O', '', 'Organization Name (eg, company)'],
'4-OU' => ['OU', '', 'Organizational Unit Name (eg, section)'],
'5-CN' => ['CN', '', 'Common Name (eg, your name or your server hostname)'],
'6-emailAddress' => ['emailAddress', '', 'Contact email address']
};
my $subjectStr = "";
print "Please enter the signature subject as follows.\n";
foreach my $k (sort keys %$signature)
{
while (1)
{
if (!$signature->{$k}[1])
{
# print promote message
print "$signature->{$k}[2]: ";
$signature->{$k}[1] = <STDIN>;
chomp $signature->{$k}[1];
if ($signature->{$k}[1])
{
$subjectStr .= "/$signature->{$k}[0]=$signature->{$k}[1]";
last;
}
}
}
}
return $subjectStr;
}
sub get_project_name
{
my ($cmd_str) = @_;
$cmd_str =~ s/".\/"//;
@list_temp = split "/", $cmd_str;
die "worry path! ".$list_temp[0] if ($list_temp[0] ne "custom");
return $list_temp[1];
}
sub sync_bootanim_to_target{
my ($target_product) = @_;
my $default_bootanim_path = "./3rdparty/system/bootanim";
my $custom_bootanim_path = "./mediatek/config/$target_product/bootanim";
my $goal_path = "./mediatek/binary/packages_common";
my $target_bootanim_path = "./mediatek/binary/packages_common/bootanim";
if (-e $target_bootanim_path)
{
system("rm -Rf $target_bootanim_path");
}
system("cp -Rf $default_bootanim_path $goal_path");
if (-e $custom_bootanim_path)
{
system("cp -Rf $custom_bootanim_path/* $target_bootanim_path");
}
}
sub sync_lk_and_taget_proucct_mk_file{
my ($target_product) = @_;
my $src_lk_mk = "mediatek/config/$target_product/lk_project.mk";
my $dst_lk_mk = "bootable/bootloader/lk/project/".$target_product.".mk";
my $src_target_product ="mediatek/config/$target_product/target_product.mk";
my $dst_target_product ="build/target/product/".$target_product.".mk";
system("cp -f $src_lk_mk $dst_lk_mk");
system("cp -f $src_target_product $dst_target_product");
}
sub auto_generated_artifacts_by_target_product{
my ($target_product) = @_;
my $common_artifacts_path = "vendor/mediatek/mbk72_wet_common/artifacts/";
my $target_project_artifacts_path = "vendor/mediatek/$target_product/artifacts/";
my $out_artifacts_path = "vendor/mediatek/out/$target_product/artifacts/";
my $common_product_dir_name = $out_artifacts_path . "out/target/product/mbk72_wet_common/";
my $new_product_dir_name = $out_artifacts_path . "out/target/product/$target_product";
my $target_txt_file_path = $out_artifacts_path . "target.txt";
my $target_txt_bak_file_path = $out_artifacts_path . "target.txt.bak";
if (-d $common_artifacts_path){
if(!-d $out_artifacts_path){
system("mkdir -p $out_artifacts_path");
}
else
{
system("rm -fr $out_artifacts_path");
}
system("rsync -av --exclude=.svn --exclude=.git --exclude=.cvs $common_artifacts_path $out_artifacts_path > sync_common_to_auto_generated_artifacts.log 2>&1\n");
system("mv -f $common_product_dir_name $new_product_dir_name");
}
if(-e $target_project_artifacts_path){
system("rsync -av --exclude=.svn --exclude=.git --exclude=.cvs $target_project_artifacts_path $out_artifacts_path > sync_".$target_product."_to_auto_generated_artifacts.log 2>&1\n");
}
if(-e $target_txt_file_path){
open(FILER,"<$target_txt_file_path")|| die "Can't open $target_txt_file_path\n";
open(FILEW,">$target_txt_bak_file_path") || die "Can't open $target_txt_bak_file_path\n";
while(<FILER>){
my $line= $_;
$line =~ s/mbk72_wet_common/$target_product/g;
print FILEW "$line";
}
close(FILER);
close(FILEW);
system("mv -f $target_txt_bak_file_path $target_txt_file_path");
}
}
sndmk.pl
#!/usr/bin/perl -w
if (@ARGV < 1 || @ARGV > 2)
{
print "error\n";
exit 0;
}
local $main_fold = ".";
local $main_cust_folder = "./3rdparty";
local $config_path = "./mediatek/config";
local $custom_path = "./mediatek/custom";
local $bak_main_folder = "./_build_bak";
local $bak_revert_files = "./_build_bak/revert_files.xml";
local $clean_del_files = "./_build_bak/del_files.xml";
local $clean_del_folders = "./_build_bak/del_folders.xml";
local $bak_end_flag = "./_build_bak/flag_end";
local $apk_goal_path = "./mediatek/binary/packages_common/custom_apk";
local $apk_mk_file = "./mediatek/binary/packages_common/custom_apk/Android.mk";
local $apk_android_default_head = "LOCAL_PATH := \$(call my-dir)\n";
local $apk_android_default_body =
"include \$(CLEAR_VARS)
LOCAL_MODULE := INSETRT
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \$(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := \$(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_MODULE_PATH := \$(TARGET_OUT)/app
ifeq (\$(strip \$(MTK_CIP_SUPPORT)), yes)
LOCAL_MODULE_PATH := \$(TARGET_CUSTOM_OUT)/app
endif
include \$(BUILD_PREBUILT)
";
local $mak_file;
local $mak_path;
local $project_name;
local @cust_folders;
local @cust_pri;
local @m_copy_files;
local @m_goal_files;
local @m_new_folders;
local @m_bak_files;
local @m_config_copy_paths;
local @m_custom_copy_paths;
local @m_apk_copy_paths;
local @m_data_apk_copy_paths;
local @project_config_head;
local @project_config_value;
local $all_config = 0;
local $is_new = "true";
&clean;
if ($ARGV[0] eq "clean")
{
exit 1;
}
if (@ARGV > 1)
{
$is_new = "false" if ($ARGV[1] eq "r");
}
#建立備份目錄
&system_cmd("mkdir ".$bak_main_folder);
##初始化mak文件、mak目錄
&count_cmd($ARGV[0]);
##獲得工程名
&get_project_name($ARGV[0]);
##收集mak文件中的配置信息
&cust_count;
&paths_count;
if ($is_new eq "true")
{
©_default;
}
&bak_files;
©_files;
©_mak_path;
&change_config;
©_apk;
exit 1;
##初始化mak文件、mak目錄
sub count_cmd
{
local ($cmd_str) = @_;
die "cmd error!" if (!-e $cmd_str);
if ($cmd_str =~ /.mak$/)
{
$mak_file = $cmd_str;
$mak_path = $cmd_str;
$mak_path =~ tr/.mak//d;
}
else
{
$mak_path = $cmd_str;
$mak_file = $cmd_str.".mak";
}
}
##獲得工程名
##
##return 例如:p1_v11_jb3_e
sub get_project_name
{
my ($cmd_str) = @_;
$cmd_str =~ s/\.\///;
@list_temp = split "/", $cmd_str;
die "worry path! ".$list_temp[0] if ($list_temp[0] ne "custom");
$project_name = $list_temp[1];
}
sub cust_count
{
local @mk_texts;
local @info_heads;
local @info_value;
if (-e $mak_file)
{
open(FILE_TEMP, $mak_file);
@mk_texts = <FILE_TEMP>;
close(FILE_TEMP);
&get_cust_info(*mk_texts, *info_heads, *info_value);
&get_cust_path(*info_heads, *info_value);
}
else
{
print "Can't found mak file. $mak_file \n";
exit 0;
}
}
sub get_cust_info
{
local (*mk_texts, *info_heads, *info_value) = @_;
my $i = 0;
my $j = 0;
my $position = 0;
my $text_temp;
while($i < @mk_texts)
{
$position = index($mk_texts[$i], "#");
if ($position == -1)
{
$text_temp = $mk_texts[$i];
}
elsif ($position < 1)
{
$i++;
next;
}
else
{
$text_temp = substr($mk_texts[$i], 0, $position);
}
if ($text_temp =~ /=/)
{
$position = index($text_temp, "=");
$info_heads[$j] = substr($text_temp, 0, $position);
$info_heads[$j] =~ tr/ \t\r\n//d;
$info_value[$j] = substr($text_temp, $position+1);
for (;$i < @mk_texts;)
{
if ($info_value[$j] =~ /\\\n$/)
{
$i++;
$info_value[$j] = $info_value[$j].$mk_texts[$i];
}
else
{
last;
}
}
$info_value[$j] =~ tr/\t\r\n\\/ /d;
$info_value[$j] =~ s/ +/ /g;
$info_value[$j] =~ s/^ //;
$info_value[$j] =~ s/ $//;
$j++;
}
$i++;
}
}
sub get_cust_path
{
local (*info_heads, *info_value) = @_;
my $i = 0;
my $j = 0;
my $k = 0;
my $text_temp;
my $path_temp;
my @child_list;
my $b_single = 0;
my @count_list;
my $path_pri = 0;
for ($i = 0; $i < @info_heads; $i++)
{
if ($info_heads[$i] =~ /^3RD_/)
{
print "$info_heads[$i]\n";
$true_head = $info_heads[$i];
$true_head =~ s/3RD_//;
$b_single = 0;
$path_pri = 0;
$path_temp = $main_cust_folder."/".lc($true_head);
print "$path_temp\n";
if (-e $path_temp)
{
opendir(DIR, $path_temp);
@child_list = readdir(DIR);
for ($k = 0; $k < @child_list; $k++)
{
$text_temp = lc($child_list[$k]);
if ($text_temp eq "flag_single")
{
$b_single = 1;
}
elsif (lc($child_list[$k]) =~ /^flag_pri/)
{
$text_temp =~ tr/[0-9]//cd;
$path_pri = $text_temp;
}
}
closedir(DIR);
}
else
{
next;
}
@count_list = split " ", $info_value[$i];
foreach $temp (@count_list)
{
if ($temp =~ /^CONFIG_/)
{
$path_temp = $main_cust_folder."/".lc($true_head)."/flag_".lc($temp);
die "3rd config error! $path_temp" if (!-e $path_temp);
open(FILE_TEMP, $path_temp);
$text_temp = <FILE_TEMP>;
close(FILE_TEMP);
$text_temp =~ tr/\t\r\n\\/ /d;
$text_temp =~ s/ +/ /g;
$text_temp =~ s/^ //;
$text_temp =~ s/ $//;
@config_list = split " ", $text_temp;
foreach $config_temp (@config_list)
{
$cust_folders[$j] = $main_cust_folder."/".lc($true_head)."/".$config_temp;
die "3rd error! +$cust_folders[$j] \n" if (!-e $cust_folders[$j]);
$cust_pri[$j] = $path_pri;
$j++;
}
}
else
{
##存儲路徑例如:./3rdparty/app/e9890td
$cust_folders[$j] = $main_cust_folder."/".lc($true_head)."/".$temp;
die "3rd error! +$cust_folders[$j] \n" if (!-e $cust_folders[$j]);
$cust_pri[$j] = $path_pri;
$j++;
}
}
}
else
{
$project_config_head[$all_config] = $info_heads[$i];
$project_config_value[$all_config] = $info_value[$i];
$all_config++;
}
}
}
sub paths_count
{
my $i = 0;
my $j = 0;
my @sort_list;
my $copy_temp;
for ($i = 0; $i < @cust_folders; $i++)
{
$sort_list[$i] = $i;
}
for ($i = 0; $i < @cust_folders-1; $i++)
{
for ($j = $i+1; $j < @cust_folders; $j++)
{
if ($cust_pri[$sort_list[$j]] < $cust_pri[$sort_list[$i]])
{
$copy_temp = $sort_list[$j];
$sort_list[$j] = $sort_list[$i];
$sort_list[$i] = $copy_temp;
}
}
}
for ($i = 0; $i < @cust_folders; $i++)
{
&get_path($cust_folders[$sort_list[$i]], $main_fold);
}
if (-e "$mak_path/3rdparty")
{
&get_path("$mak_path/3rdparty", $main_fold);
}
}
sub get_path
{
my($copy_path, $goal_path) = @_;
opendir (DIR, $copy_path);
my @child_list = readdir (DIR);
closedir(DIR);
for (my $i = 0; $i < @child_list; $i++)
{
if ($child_list[$i] eq "." || $child_list[$i] eq "..")
{
}
elsif (-d $copy_path."/".$child_list[$i])
{
if ($child_list[$i] =~ /^LINK_APK/)
{
$m_apk_copy_paths[@m_apk_copy_paths] = $copy_path."/".$child_list[$i];
}
elsif ($child_list[$i] =~ /^LINK_DATA_APK/)
{
$m_data_apk_copy_paths[@m_data_apk_copy_paths] = $copy_path."/".$child_list[$i];
}
elsif ($child_list[$i] =~ /^LINK_LIB/)
{
&add_folder($copy_path."/".$child_list[$i], "./vendor/mediatek/$project_name/artifacts/out/target/product/$project_name/system/lib");
&get_child_path($copy_path."/".$child_list[$i], "./vendor/mediatek/$project_name/artifacts/out/target/product/$project_name/system/lib");
}
elsif ($child_list[$i] =~ /^LINK_MEDIA/)
{
&add_folder($copy_path."/".$child_list[$i], "./vendor/mediatek/$project_name/artifacts/out/target/product/$project_name/system/media");
&get_child_path($copy_path."/".$child_list[$i], "./vendor/mediatek/$project_name/artifacts/out/target/product/$project_name/system/media");
}
elsif ($child_list[$i] =~ /^LINK_/)
{
if (-e "$copy_path/flag_".lc($child_list[$i]))
{
open(FILE_TEMP, "$copy_path/flag_".lc($child_list[$i]));
$goal_path = <FILE_TEMP>;
close(FILE_TEMP);
$goal_path =~ s/PROJECT/$project_name/g;
&add_folder($copy_path."/".$child_list[$i], $goal_path);
&get_child_path($copy_path."/".$child_list[$i], $goal_path);
}
}
else
{
$re = &add_folder($copy_path."/".$child_list[$i], $goal_path."/".$child_list[$i]);
if ($re == 1)
{
&get_child_path($copy_path."/".$child_list[$i], $goal_path."/".$child_list[$i]);
}
}
}
}
}
###參數說明#####
####$1:./3rdparty/app/e9890td/packages/apps/Settings
####$2:./packages/apps/Settings
sub get_child_path
{
my($copy_path, $goal_path) = @_;
opendir(CHILD_PATH, $copy_path);
my @child_list = readdir (CHILD_PATH);
closedir(CHILD_PATH);
for (my $i = 0; $i < @child_list; $i++)
{
$path_temp = $copy_path."/".$child_list[$i];
if ($child_list[$i] eq "." || $child_list[$i] eq "..")
{
}
elsif (-d $path_temp)
{
$re = &add_folder($copy_path."/".$child_list[$i], $goal_path."/".$child_list[$i]);
if ($re == 1)
{
&get_child_path($copy_path."/".$child_list[$i], $goal_path."/".$child_list[$i]);
}
}
else
{
&add_file($copy_path."/".$child_list[$i], $goal_path."/".$child_list[$i]);
}
}
}
###參數說明#####
####$1:./3rdparty/app/e9890td/packages/apps/Settings
####$2:./packages/apps/Settings
sub add_folder
{
my($copy_path, $goal_path) = @_;
if ($copy_path !~ /^\.\//)
{
$copy_path = ".\/".$copy_path;
}
if ($goal_path !~ /^\.\//)
{
$goal_path = ".\/".$goal_path;
}
if ($copy_path =~ /CONFIG/)
{
$m_config_copy_paths[@m_config_copy_paths] = $copy_path;
return 0;
}
if ($copy_path =~ /CUSTOM/)
{
$m_custom_copy_paths[@m_custom_copy_paths] = $copy_path;
return 0;
}
if ($goal_path =~ /PROJECT/)
{
$goal_path =~ s/PROJECT/$project_name/g;
}
if (!(-e ($goal_path)))
{
for ($i = 0; $i < @m_new_folders; $i++) {
if ($goal_path eq $m_new_folders[$i])
{
last;
}
}
if ($i >= @m_new_folders)
{
$m_new_folders[@m_new_folders] = $goal_path;
}
}
return 1;
}
sub add_file
{
my($copy_file, $goal_file) = @_;
my $path_temp;
if ($copy_file !~ /^\.\//)
{
$copy_file = ".\/".$copy_file;
}
if ($goal_file !~ /^\.\//)
{
$goal_file = ".\/".$goal_file;
}
for ($i = 0; $i < @m_goal_files; $i++)
{
if ($goal_file eq $m_goal_files[$i])
{
last;
}
}
if ($i < @m_goal_files)
{
$m_copy_files[$i] = $copy_file;
}
else
{
$new_idx = @m_copy_files;
if (-e $goal_file)
{
$m_bak_files[@m_bak_files] = $goal_file;
$path_temp = $goal_file;
$path_temp =~ s/\.\//$bak_main_folder\//;
$position = rindex($path_temp, "/");
$path_temp = substr($path_temp, 0, $position);
for ($i = 0; $i < @m_bak_new_folders; $i++)
{
if ($m_bak_new_folders[$i] eq $path_temp)
{
last;
}
}
if ($i >= @m_bak_new_folders)
{
$m_bak_new_folders[@m_bak_new_folders] = $path_temp;
}
}
$m_copy_files[$new_idx] = $copy_file;
$m_goal_files[$new_idx] = $goal_file;
}
}
sub bak_files
{
my $path_temp;
my $v = @m_bak_new_folders;
for ($i = 0; $i < @m_bak_new_folders; $i++)
{
if (!(-e ($m_bak_new_folders[$i])))
{
&system_cmd("mkdir -p ".$m_bak_new_folders[$i]);
}
}
for ($i = 0; $i < @m_bak_files; $i++)
{
$path_temp = $m_bak_files[$i];
$path_temp =~ s/\.\//$bak_main_folder\//;
print $m_bak_files[$i]." ".$path_temp."\n";
&system_cmd("cp -pf ".$m_bak_files[$i]." ".$path_temp);
}
if (@m_bak_files > 0)
{
open(FILE_TEMP, ">".$bak_revert_files);
for ($i = 0; $i < @m_bak_files; $i++)
{
print FILE_TEMP $m_bak_files[$i];
print FILE_TEMP "\n";
}
close(FILE_TEMP);
}
if (@m_goal_files > 0)
{
open(FILE_TEMP, ">".$clean_del_files);
for ($i = 0; $i < @m_goal_files; $i++)
{
if (!(-e $m_goal_files[$i]))
{
print FILE_TEMP $m_goal_files[$i];
print FILE_TEMP "\n";
}
}
close(FILE_TEMP);
}
if (@m_data_apk_copy_paths > 0)
{
$m_new_folders[@m_new_folders] = "./vendor/mediatek/$project_name/artifacts/out/target/product/$project_name/system/appbackup";
$m_new_folders[@m_new_folders] = "./vendor/mediatek/$project_name/artifacts/out/target/product/$project_name/data/app";
}
if (@m_new_folders > 0)
{
open(FILE_TEMP, ">".$clean_del_folders);
for ($i = 0; $i < @m_new_folders; $i++)
{
print FILE_TEMP $m_new_folders[$i];
print FILE_TEMP "\n";
}
close(FILE_TEMP);
}
open(FILE_TEMP, ">".$bak_end_flag);
print FILE_TEMP "end";
close(FILE_TEMP);
}
sub copy_files
{
for ($i = 0; $i < @m_new_folders; $i++)
{
print $m_new_folders[$i]."\n";
&system_cmd("mkdir -p ".$m_new_folders[$i]);
}
for ($i = 0; $i < @m_copy_files; $i++)
{
print $m_copy_files[$i]." ".$m_goal_files[$i]."\n";
&system_cmd("cp -pf ".$m_copy_files[$i]." ".$m_goal_files[$i]);
}
&system_cmd("cp -f ".$main_cust_folder."/Android.mk ".$bak_main_folder);
}
sub clean
{
if (-e $bak_end_flag)
{
if (-e $clean_del_files)
{
open(FILE_TEMP, $clean_del_files);
@del_files = <FILE_TEMP>;
for ($i = 0; $i < @del_files; $i++)
{
$del_files[$i] =~ tr/\n//d;
if (-e $del_files[$i])
{
print "del $del_files[$i]\n";
&system_cmd("rm -f ".$del_files[$i]);
}
}
close(FILE_TEMP);
}
if (-e $clean_del_folders)
{
open(FILE_TEMP, $clean_del_folders);
@del_folders = <FILE_TEMP>;
for ($i = 0; $i < @del_folders; $i++)
{
$del_folders[$i] =~ tr/\n//d;
print "del $del_folders[$i]\n";
if (-e $del_folders[$i])
{
&system_cmd("rm -rf ".$del_folders[$i]);
}
}
close(FILE_TEMP);
}
if (-e $bak_revert_files)
{
open(FILE_TEMP, $bak_revert_files);
@revert_files = <FILE_TEMP>;
for ($i = 0; $i < @revert_files; $i++)
{
$revert_files[$i] =~ tr/\n//d;
$path_temp = $revert_files[$i];
$path_temp =~ s/\.\//$bak_main_folder\//;
if (-e $path_temp)
{
print "revert $path_temp\n";
&system_cmd("cp -pf ".$path_temp." ".$revert_files[$i]);
}
}
close(FILE_TEMP);
}
&system_cmd("rm -f ".$bak_end_flag);
}
if (-e $bak_main_folder)
{
&system_cmd("rm -rf ".$bak_main_folder);
}
print "clean\n";
}
sub copy_default
{
my $copy_path = $config_path."/default/".$project_name;
my $goal_path = $config_path."/".$project_name;
if (-e $goal_path)
{
&system_cmd("rm -rf ".$goal_path);
}
die "Can't found default path ".$copy_path if (!-d $copy_path);
&system_cmd("cp -Rpf ".$copy_path." ".$goal_path);
$copy_path = $custom_path."/default/".$project_name;
$goal_path = $custom_path."/".$project_name;
if (-e $goal_path)
{
&system_cmd("rm -rf ".$goal_path);
}
die "Can't found default path" if (!-d $copy_path);
&system_cmd("cp -Rpf ".$copy_path." ".$goal_path);
}
sub copy_mak_path
{
my $copy_path = $mak_path."/config";
my $goal_path = $config_path."/".$project_name;
foreach $temp (@m_config_copy_paths)
{
&system_cmd("cp -pa ".$temp."/* ".$goal_path);
}
if (-e $copy_path)
{
&system_cmd("cp -Rpf ".$copy_path."/* ".$goal_path);
}
$copy_path = $mak_path."/custom";
$goal_path = $custom_path."/".$project_name;
foreach $temp (@m_custom_copy_paths)
{
&system_cmd("cp -Rpf ".$temp."/* ".$goal_path);
}
if (-e $copy_path)
{
&system_cmd("cp -Rpf ".$copy_path."/* ".$goal_path);
}
}
sub change_config
{
my $config_file = $config_path."/".$project_name."/ProjectConfig.mk";
my $i = 0;
my $j = 0;
my @head_list;
my @value_list;
my @is_new;
my $position = 0;
my $line_temp;
if ($all_config == 0)
{
return;
}
for ($i = 0; $i < $all_config; $i++)
{
if ($project_config_head[$i] =~ /^NEW_/)
{
$head_list[$i] = $project_config_head[$i];
$head_list[$i] =~ tr/^NEW_//;
$value_list[$i] = $project_config_value[$i];
$is_new[$i] = 1;
}
else
{
$head_list[$i] = $project_config_head[$i];
$value_list[$i] = $project_config_value[$i];
$is_new[$i] = 0;
}
}
open(FILE_TEMP, $config_file);
my @file_text = <FILE_TEMP>;
close(FILE_TEMP);
for ($i = 0; $i < @file_text;)
{
$position = index($file_text[$i], "#");
if ($position == -1)
{
$text_temp = $file_text[$i];
}
elsif ($position < 1)
{
$i++;
next;
}
else
{
$text_temp = substr($file_text[$i], 0, $position);
}
if ($text_temp =~ /=/)
{
$position = index($text_temp, "=");
$text_temp = substr($text_temp, 0, $position);
for ($j = 0; $j < $all_config; $j++)
{
if ($text_temp =~ /$head_list[$j]/)
{
$file_text[$i] = $head_list[$j]."=".$value_list[$j]."\n";
$is_new[$j] = 2;
last;
}
}
}
$i++;
}
$i = @file_text;
$file_text[$i] = "\n\n";
$i++;
for ($j = 0; $j < $all_config; $j++)
{
die "Mak config error! $head_list[$j] = $value_list[$j] $is_new[$j]" if ($is_new[$j] == 0);
if ($is_new[$j] == 1)
{
$file_text[$i] = $head_list[$j]."=".$value_list[$j]."\n";
$i++;
}
}
open(FILE_TEMP, ">".$config_file);
print FILE_TEMP @file_text;
close(FILE_TEMP);
}
sub copy_apk
{
my @result_list;
if (@m_apk_copy_paths > 0) {
if (-e $apk_goal_path)
{
system_cmd("rm -Rf $apk_goal_path");
}
system_cmd("mkdir -p $apk_goal_path");
foreach $copy_temp (@m_apk_copy_paths)
{
system_cmd("cp -Rpf ".$copy_temp."/* ".$apk_goal_path);
}
opendir(DIR, $apk_goal_path);
@child_list = readdir(DIR);
closedir(DIR);
for ($i = 0; $i < @child_list; $i++)
{
if ($child_list[$i] =~ /.apk$/i) {
$child_list[$i] =~ s/.apk$//i;
$result_list[@result_list] = $child_list[$i];
}
}
if (@result_list > 0)
{
open(FILE_TEMP, ">$apk_mk_file");
print FILE_TEMP $apk_android_default_head;
foreach $temp (@result_list)
{
$text_temp = $apk_android_default_body;
$text_temp =~ s/INSETRT/$temp/;
print FILE_TEMP $text_temp;
}
close(FILE_TEMP);
open(FILE_TEMP, ">>$config_path/$project_name/target_product.mk");
print FILE_TEMP "\nPRODUCT_PACKAGES +=";
foreach $temp (@result_list)
{
print FILE_TEMP " $temp \\\n";
}
close(FILE_TEMP);
}
}
if (@m_data_apk_copy_paths > 0)
{
$goal_path = "./vendor/mediatek/$project_name/artifacts/out/target/product/$project_name/system/appbackup";
$goal_path_2 = "./vendor/mediatek/$project_name/artifacts/out/target/product/$project_name/data/app";
system_cmd("mkdir -p $goal_path");
system_cmd("mkdir -p $goal_path_2");
foreach $copy_temp (@m_data_apk_copy_paths)
{
system_cmd("cp -Rpf $copy_temp/*.* $goal_path");
system_cmd("cp -Rpf $copy_temp/*.* $goal_path_2");
}
opendir(DIR, $goal_path);
@child_list = readdir(DIR);
closedir(DIR);
$restore_list_file = "$goal_path_2/.restore_list";
open(FILE_TEMP, ">$restore_list_file");
foreach $child_temp (@child_list)
{
if ($child_temp =~ /apk$/i)
{
print FILE_TEMP "/system/appbackup/$child_temp\n";
}
}
close(FILE_TEMP);
}
}
sub string_replace
{
my($main_str, $old_str, $new_str) = @_;
}
sub system_cmd { my($cmd_text) = @_; my $re = system($cmd_text); if ($re < 0) { die "$cmd_text\n"; } elsif ($re == 127) { die "$cmd_text\n"; } }