1153 lines
30 KiB
Batchfile
1153 lines
30 KiB
Batchfile
@echo off
|
|
REM ------------------------------------------------------------------
|
|
REM
|
|
REM lgndata.cmd : (Engine of Language Neutral build)
|
|
REM generate various control files to control the flow of Language Neutral build
|
|
REM Files may be generated by this script
|
|
REM $nttree\\build_logs\\LgNeutral\\lgnlist.txt -0
|
|
REM $nttree\\build_logs\\LgNeutral\\lgntobuildlist.txt -g
|
|
REM $nttree\\build_logs\\LgNeutral\\lgnbuildlist.txt -i
|
|
REM $nttree\\build_logs\\LgNeutral\\lgnsnapt.txt -s
|
|
REM $nttree\\build_logs\\LgNeutral\\lgncmflist.txt -m
|
|
REM Copy RCBinary & Mofified Binary to $nttree -c
|
|
REM Check the state of last LGNT build and recover the
|
|
REM state terminated abnormally -v
|
|
REM [Note] {RAZZLETOOLPATH} . "\\PostBuildScripts\\lgnexclude.txt contains the exclude list
|
|
REM for Language Neutral
|
|
REM
|
|
REM You will see many places in pbuild.dat for this command.
|
|
REM Language Neutral build support incremental build. It also can be restarted correctly from a
|
|
REM abnormally terminated state.
|
|
REM
|
|
REM Copyright (c) Microsoft Corporation. All rights reserved.
|
|
REM
|
|
REM ------------------------------------------------------------------
|
|
perl -x "%~f0" %*
|
|
goto :EOF
|
|
#!perl
|
|
use strict;
|
|
use File::Basename;
|
|
use IO::File;
|
|
|
|
use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
|
|
use lib $ENV{RAZZLETOOLPATH};
|
|
use PbuildEnv;
|
|
use ParseArgs;
|
|
use Logmsg;
|
|
use cksku;
|
|
use ReadSetupFiles;
|
|
|
|
|
|
BEGIN {
|
|
$ENV{SCRIPT_NAME} = 'lgndata.cmd';
|
|
}
|
|
|
|
sub Usage { print<<USAGE; exit(1) }
|
|
lgndata [ -?] [-0] [-g] [-i] [-s] [-c]
|
|
-0 generate lgnlist.txt which contains qualified binaries to be processed
|
|
-g generate lgntobuildlist.txt which contains binaries to be processed
|
|
-i generate lgnbuildlist.txt which contains list of LGN resource binaries
|
|
-s do a snap shot from Ntreee\\ , for those files listed in PostBuildScripts\\ lgnlist.txt
|
|
-c copy Modified bin and RC bin from nttree\\build_logs\\LgNeutra to nttree
|
|
-v Verify if last build terminated correctly. If it's not the case, recover it.
|
|
|
|
USAGE
|
|
|
|
# Global variables
|
|
|
|
my ($lang, $fCreateQualified,$fGenerate, $fInitial, $fSnap, $fCopy, $fVerify, $SnapFilePath, $fGenerateCMFList);
|
|
my ( $Neutral_LogDir, $LGNToBuildList, $LGNBuildList, $LGNCMFList ,$LGNSnapt, $LGNSnapBak, $LGNExcludeList , $LGNList, $LGNStatus, $LGNTCopyLock );
|
|
my( @FILE_LIST, $LogFilename );
|
|
my( $TempDir, $TempDiffFile, $TempDiffFile1 );
|
|
my( $CodeBinDir, $OrigBinDir, $RCBinDir, $CMFBinDir, $CodeBinPath, $OrigBinPath, $RCBinPath, $CMFBinPath );
|
|
my( $nttree, $razpath, $TempDir);
|
|
my ($STS_Freshs, $STS_OK, $STS_ToBuildList, $STS_BuildList, $STS_CMFList, $STS_Copy, $STS_RemoveRC, $STS_Unknown);
|
|
my ($STS_CopyLock, $STS_CopyStart);
|
|
my($fNeedGenerateCMF);
|
|
|
|
|
|
$fGenerate =0;
|
|
$fInitial =0;
|
|
$fSnap =0;
|
|
$fCopy =0;
|
|
$fVerify =0;
|
|
$fGenerateCMFList = 0;
|
|
##################
|
|
#
|
|
# parse command line
|
|
#
|
|
##################
|
|
parseargs( '?' => \&Usage,
|
|
'0' => \$fCreateQualified,
|
|
'g' => \$fGenerate,
|
|
'i' => \$fInitial,
|
|
's' => \$fSnap,
|
|
'c' => \$fCopy,
|
|
'v' => \$fVerify,
|
|
'm' => \$fGenerateCMFList,
|
|
'l:' => \$lang,
|
|
'p:' => \$SnapFilePath
|
|
);
|
|
|
|
&Main();
|
|
|
|
#
|
|
# Check if Language Neutral is enabled or not
|
|
#
|
|
sub IsLGNActivated()
|
|
{
|
|
my ($MUI_MAGIC, $Result);
|
|
|
|
$Result = 0;
|
|
|
|
$MUI_MAGIC= $ENV{ "MUI_MAGIC" };
|
|
|
|
if ( defined($MUI_MAGIC))
|
|
{
|
|
$Result=1;
|
|
}
|
|
return $Result
|
|
|
|
}
|
|
#
|
|
# Check if we need generate CMF (Compact Resource File)
|
|
#
|
|
sub IsCMFActivated()
|
|
{
|
|
my ($MUI_MAGIC_CMF, $Result);
|
|
|
|
$Result = 0;
|
|
|
|
$MUI_MAGIC_CMF= $ENV{ "MUI_MAGIC_CMF" };
|
|
|
|
if ( defined($MUI_MAGIC_CMF))
|
|
{
|
|
$Result=1;
|
|
}
|
|
return $Result
|
|
}
|
|
|
|
sub Main {
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
# Begin Main code section
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
# Return when you want to exit on error
|
|
#
|
|
my ($bUseDefault, $Path, $Mylang);
|
|
|
|
if ( ! &IsLGNActivated())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if ( ! defined($lang))
|
|
{
|
|
$lang = $ENV{LANG};
|
|
if (! defined($lang))
|
|
{
|
|
$lang="usa";
|
|
}
|
|
}
|
|
|
|
$Mylang="\L$lang";
|
|
if ( $Mylang ne "usa")
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#
|
|
# Should we generate CMF (Compact resource file ?)
|
|
#
|
|
$fNeedGenerateCMF=&IsCMFActivated();
|
|
$Logmsg::DEBUG = 0; # set to 1 to activate logging of dbgmsg's
|
|
$LogFilename = $ENV{ "LOGFILE" };
|
|
if ( ! defined( $LogFilename ) )
|
|
{
|
|
$TempDir = $ENV{ "TMP" };
|
|
$LogFilename = "$TempDir\\$0.log";
|
|
}
|
|
|
|
$CodeBinDir=$ENV{ "CodeBinDir" };
|
|
if ( ! defined( $CodeBinDir) )
|
|
{
|
|
$CodeBinDir="CodeBin";
|
|
}
|
|
$RCBinDir=$ENV{ "RcBinDir" };
|
|
if ( ! defined( $RCBinDir) )
|
|
{
|
|
$RCBinDir="RCBin";
|
|
}
|
|
$OrigBinDir=$ENV{ "OrigBinDir" };
|
|
if ( ! defined( $OrigBinDir) )
|
|
{
|
|
$OrigBinDir="OrigBin";
|
|
}
|
|
$CMFBinDir=$ENV{ "CMFBinDir" };
|
|
if ( ! defined( $CMFBinDir) )
|
|
{
|
|
$CMFBinDir="CMFBin";
|
|
}
|
|
timemsg( "Beginning ...");
|
|
|
|
|
|
# set up paths to important files
|
|
$nttree = $ENV{ "_NTPostBld" };
|
|
$razpath= $ENV{ "RazzleToolPath" };
|
|
$TempDir = $ENV{ "TMP" };
|
|
|
|
|
|
$Neutral_LogDir = $nttree."\\build_logs\\LgNeutral";
|
|
$LGNToBuildList = $Neutral_LogDir."\\lgntobuildlist.txt";
|
|
$LGNBuildList = $Neutral_LogDir."\\lgnbuildlist.txt";
|
|
$LGNCMFList = $Neutral_LogDir."\\lgncmflist.txt";
|
|
$LGNSnapt = $Neutral_LogDir."\\lgnsnap.txt";
|
|
$LGNSnapBak = $Neutral_LogDir."\\lgnsnap.txt.bak";
|
|
$LGNExcludeList = $razpath."\\PostBuildScripts\\lgnexclude.txt";
|
|
$LGNList = $Neutral_LogDir."\\lgnlist.txt";
|
|
$LGNStatus = $Neutral_LogDir."\\lgnStatusLock.txt";
|
|
$LGNTCopyLock = $Neutral_LogDir."\\lgnCopyLock.txt";
|
|
$TempDiffFile = $Neutral_LogDir."\\lgbindiff.txt";
|
|
$TempDiffFile1 = $Neutral_LogDir."\\lgbindiff1.txt";
|
|
|
|
$OrigBinPath = "$Neutral_LogDir\\$OrigBinDir";
|
|
$CodeBinPath ="$Neutral_LogDir\\$CodeBinDir";
|
|
$RCBinPath ="$Neutral_LogDir\\$RCBinDir";
|
|
$CMFBinPath ="$Neutral_LogDir\\$CMFBinDir";
|
|
|
|
$STS_Freshs = "Fresh";
|
|
$STS_OK = "OK";
|
|
$STS_ToBuildList="ToBuildList";
|
|
$STS_RemoveRC="RemoveRC";
|
|
$STS_BuildList="BuildList";
|
|
$STS_CMFList="CMFList";
|
|
$STS_Copy="CopyBin";
|
|
$STS_Unknown="Unknown";
|
|
$STS_CopyLock ="CopyLock";
|
|
$STS_CopyStart ="StartCopyBin";
|
|
|
|
# Create three BIN folder if they are not exist
|
|
|
|
unless( -d $Neutral_LogDir )
|
|
{
|
|
if (system("md $Neutral_LogDir") != 0)
|
|
{
|
|
errmsg("Fatal: $Neutral_LogDir doesn't exist");
|
|
exit(1);
|
|
}
|
|
}
|
|
unless ( -d $OrigBinPath)
|
|
{
|
|
if (system("md $OrigBinPath") != 0)
|
|
{
|
|
errmsg("Fatal: can't create $OrigBinPath");
|
|
exit(1);
|
|
}
|
|
}
|
|
unless ( -d $CodeBinPath)
|
|
{
|
|
if (system("md $CodeBinPath") != 0)
|
|
{
|
|
errmsg("Fatal: can't create CodeBinPath");
|
|
exit(1);
|
|
}
|
|
}
|
|
unless ( -d $RCBinPath)
|
|
{
|
|
if (system("md $RCBinPath") != 0)
|
|
{
|
|
errmsg("Fatal: can't create $RCBinPath");
|
|
exit(1);
|
|
}
|
|
}
|
|
unless ( -d $CMFBinPath)
|
|
{
|
|
if (system("md $CMFBinPath") != 0)
|
|
{
|
|
errmsg("Fatal: can't create $CMFBinPath");
|
|
exit(1);
|
|
}
|
|
}
|
|
if ($fCreateQualified)
|
|
{
|
|
if (! &CreateQualified())
|
|
{
|
|
errmsg("Generate $LGNList Failed");
|
|
}
|
|
|
|
}
|
|
elsif ($fGenerate)
|
|
{
|
|
if (!&DoGenerateToBuildList())
|
|
{
|
|
errmsg("Generate $LGNToBuildList failed");
|
|
}
|
|
}
|
|
elsif ( $fInitial)
|
|
{
|
|
if (!&DoGenerateBuildList())
|
|
{
|
|
errmsg("Generate $LGNBuildList failed");
|
|
}
|
|
}
|
|
elsif ( $fGenerateCMFList)
|
|
{
|
|
if (!&DoGenerateCMFList())
|
|
{
|
|
errmsg("Generate $LGNCMFList failed");
|
|
}
|
|
}
|
|
elsif ( $fSnap)
|
|
{
|
|
if (defined($SnapFilePath))
|
|
{
|
|
$bUseDefault=1;
|
|
$Path = $SnapFilePath;
|
|
}
|
|
else
|
|
{
|
|
$bUseDefault = 0;
|
|
$Path="Null";
|
|
}
|
|
|
|
if (!&DoGenerateSnap($bUseDefault,$Path))
|
|
{
|
|
errmsg("Generate $LGNSnapt failed");
|
|
}
|
|
}
|
|
elsif ($fCopy)
|
|
{
|
|
if (! &DoCopyLGNBinary())
|
|
{
|
|
errmsg("Copy LGN binary failed");
|
|
}
|
|
|
|
}
|
|
elsif ($fVerify)
|
|
{
|
|
#
|
|
# Check the last state. If last build process terminated abnormally, recover it.
|
|
#
|
|
&DoVerify();
|
|
}
|
|
else
|
|
{
|
|
&Usage();
|
|
}
|
|
|
|
timemsg( "Finished." );
|
|
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
# End Main code section
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
}
|
|
|
|
#
|
|
# Check LGN's last status
|
|
# LGN process should work/restart correctly from any interrupted state.
|
|
# for example, operator cancels the execution of the script in the middle way, then restart.
|
|
# Possible value in StatusLock
|
|
# (0) Fresh
|
|
# (1) ToBuildList
|
|
# (2) BuildList
|
|
# (3) CopyBin
|
|
# (4) OK
|
|
#
|
|
sub GetLastStatus
|
|
{
|
|
my (@Bufs);
|
|
|
|
if ( ! -e $LGNStatus )
|
|
{
|
|
return $STS_Freshs;
|
|
}
|
|
unless (open(INFILE, $LGNStatus))
|
|
{
|
|
errmsg("Fatal: can't open input for status file $LGNStatus");
|
|
return $STS_Unknown;
|
|
}
|
|
@Bufs=<INFILE>;
|
|
close(INFILE);
|
|
chomp($Bufs[0]);
|
|
logmsg("Current Status=$Bufs[0]");
|
|
return $Bufs[0];
|
|
|
|
|
|
}
|
|
sub LogStatus
|
|
{
|
|
my ($TheStatus) = @_;
|
|
my ($Result);
|
|
|
|
$Result = 0;
|
|
|
|
unless (open(OUTFILE, ">$LGNStatus"))
|
|
{
|
|
errmsg("Fatal: can't create status file $LGNStatus");
|
|
return $Result;
|
|
}
|
|
print (OUTFILE "$TheStatus\n");
|
|
close(OUTFILE);
|
|
$Result = 1;
|
|
return $Result;
|
|
|
|
}
|
|
|
|
#
|
|
# Generate lgnlist.txt which contains qualified files to be processed
|
|
#
|
|
# Input : $nttree\\*.*
|
|
# Input : {RAZZLETOOLPATH} . "\\PostBuildScripts\\lgnexclude.txt (Exclude List)
|
|
# Output: $nttree\\build_logs\\LgNeutral\\lgnlist.txt
|
|
#
|
|
sub CreateQualified
|
|
{
|
|
my %FileTypeTbl = (
|
|
".exe" => 1,
|
|
".dll" => 1,
|
|
".cpl" => 1,
|
|
".ocx" => 1,
|
|
".tsp" => 1,
|
|
".scr" => 1,
|
|
".msc" => 1,
|
|
);
|
|
my ($Result, $Line, $Types, %ExcludeList, @Items);
|
|
my(%DrvList);
|
|
|
|
$Result = 0;
|
|
|
|
#
|
|
# Check for output
|
|
#
|
|
unless (open(OUTFILE,">$LGNList"))
|
|
{
|
|
errmsg("Can't open output: $LGNList");
|
|
return $Result;
|
|
}
|
|
|
|
#
|
|
# Check if exclude List exists
|
|
#
|
|
unless (open(INFILE,$LGNExcludeList))
|
|
{
|
|
errmsg("Can open Input: $LGNExcludeList");
|
|
close(OUTFILE);
|
|
return $Result;
|
|
}
|
|
#
|
|
# Read Exclude List and build hashes
|
|
#
|
|
@Items =<INFILE>;
|
|
close(INFILE);
|
|
foreach $Line (@Items)
|
|
{
|
|
chomp($Line);
|
|
$Line =~ s/\s//g;
|
|
if (length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
if (substr($Line,0,1) eq ";")
|
|
{
|
|
next;
|
|
}
|
|
$Line="\L$Line";
|
|
$ExcludeList{$Line}=1;
|
|
}
|
|
#
|
|
# Read Driver List from different flavor
|
|
#
|
|
if (! &ReadDriverList(\%DrvList))
|
|
{
|
|
errmsg("Read Driver List Failed ");
|
|
close(OUTFILE);
|
|
return $Result;
|
|
}
|
|
#
|
|
# Combine driver list to exclude list
|
|
#
|
|
foreach $Line (keys(%DrvList))
|
|
{
|
|
if ( ! defined($ExcludeList{$Line}) )
|
|
{
|
|
$ExcludeList{$Line}=1;
|
|
}
|
|
}
|
|
#
|
|
# Read Directory
|
|
#
|
|
unless (opendir(INDIR,$nttree))
|
|
{
|
|
errmsg("can't open $nttree !!");
|
|
close(OUTFILE);
|
|
return $Result;
|
|
}
|
|
@Items=readdir INDIR;
|
|
foreach $Line (@Items)
|
|
{
|
|
if ( ($Line eq "." ) || ($Line eq "..") )
|
|
{
|
|
next;
|
|
}
|
|
if (length($Line) < 4)
|
|
{
|
|
next;
|
|
}
|
|
$Line="\L$Line";
|
|
$Types = substr($Line,-4,4);
|
|
if ( ! (defined ($FileTypeTbl{$Types}) ) )
|
|
{
|
|
next;
|
|
}
|
|
#
|
|
# Not in the exclude List ?
|
|
#
|
|
if ( ! (defined ($ExcludeList{$Line} ) ) )
|
|
{
|
|
print (OUTFILE "$Line\n");
|
|
}
|
|
}
|
|
close(OUTFILE);
|
|
$Result = 1;
|
|
return $Result;
|
|
}
|
|
|
|
#
|
|
# Read Driver list from different flavor and build the array
|
|
#
|
|
sub ReadDriverList
|
|
{
|
|
my($pHashList) = @_;
|
|
|
|
my ($BigDrvIndex, $PerDrvIndex, $BlaDrvIndex, $SbsDrvIndex, $SrvDrvIndex , $EntDrvIndex , $DtcDrvIndex);
|
|
my ($Path_DrvIndex, $Result, $Flavor, $FilePath, $Line);
|
|
my (@DrvIndexFiles, %CDDataSKUs,%INFPathSKUs);
|
|
|
|
#
|
|
# Do nothing at this moment
|
|
#
|
|
return 1;
|
|
|
|
#
|
|
# Get SKUs
|
|
#
|
|
%CDDataSKUs = map({uc$_ => cksku::CkSku($_, $lang, $ENV{_BuildArch})} qw(PRO PER SRV BLA SBS ADS DTC));
|
|
#
|
|
# Build DRiver INFs for SKUs
|
|
#
|
|
$BigDrvIndex = $nttree . "\\drvindex.inf";
|
|
$PerDrvIndex = $nttree . "\\perinf\\drvindex.inf";
|
|
$BlaDrvIndex= $nttree . "\\blainf\\drvindex.inf";
|
|
$SbsDrvIndex = $nttree . "\\sbsinf\\drvindex.inf";
|
|
$SrvDrvIndex = $nttree . "\\srvinf\\drvindex.inf";
|
|
$EntDrvIndex = $nttree . "\\entinf\\drvindex.inf";
|
|
$DtcDrvIndex= $nttree . "\\dtcinf\\drvindex.inf";
|
|
|
|
# PRO
|
|
$Path_DrvIndex =$BigDrvIndex;
|
|
$INFPathSKUs{"PRO"} = [ ( $Path_DrvIndex) ];
|
|
#PER
|
|
$Path_DrvIndex =$PerDrvIndex;
|
|
$INFPathSKUs{"PER"} = [ ($Path_DrvIndex ) ];
|
|
#SRV
|
|
$Path_DrvIndex =$SrvDrvIndex;
|
|
$INFPathSKUs{"SRV"} = [ ($Path_DrvIndex) ];
|
|
#BLA
|
|
$Path_DrvIndex =$BlaDrvIndex;
|
|
$INFPathSKUs{"BLA"} = [ ($Path_DrvIndex) ];
|
|
#SBS
|
|
$Path_DrvIndex =$SbsDrvIndex;
|
|
$INFPathSKUs{"SBS"} = [ ($Path_DrvIndex) ];
|
|
#ADS (ENT)
|
|
$Path_DrvIndex =$EntDrvIndex;
|
|
$INFPathSKUs{"ADS"} = [ ($Path_DrvIndex) ];
|
|
#DTC
|
|
$Path_DrvIndex =$DtcDrvIndex;
|
|
$INFPathSKUs{"DTC"} = [ ($Path_DrvIndex) ];
|
|
|
|
$Result = 0;
|
|
|
|
foreach $Flavor (keys(%CDDataSKUs))
|
|
{
|
|
#if ( ! defined (INFPathSKUs{$Flavor})
|
|
#{
|
|
# errmsg("ReadDriverList:$Flavor not found in table");
|
|
# return $Result;
|
|
#}
|
|
#($FilePath) = @{$INFPathSKUs{$Flavor}};
|
|
if ( !ReadSetupFiles::ReadDrvIndex( $nttree, $Flavor, \@DrvIndexFiles) )
|
|
{
|
|
errmsg( "Error reading drvindex file, skipping $Flavor." );
|
|
return $Result;
|
|
}
|
|
foreach $Line (@DrvIndexFiles)
|
|
{
|
|
if ( ! defined($$pHashList{$Line}) )
|
|
{
|
|
$$pHashList{$Line} = 1;
|
|
}
|
|
}
|
|
}
|
|
$Result=1;
|
|
|
|
return $Result;
|
|
|
|
|
|
}
|
|
|
|
#
|
|
# Generate the list from which binaries will be processed
|
|
#
|
|
sub DoGenerateToBuildList
|
|
{
|
|
|
|
my ($Fresh, $Result, $Line, $Path, @Bufs, @Diffs, $Item_no);
|
|
my ($Path, $FilePath, $FileName, $Size, $Mtime, $LastStatus, $WindiffCommand);
|
|
|
|
$Result = 0;
|
|
$Item_no=0;
|
|
|
|
#
|
|
# Check last status
|
|
#
|
|
$LastStatus = GetLastStatus();
|
|
|
|
if ( ($LastStatus ne $STS_Freshs ) && ($LastStatus ne $STS_OK) &&
|
|
($LastStatus ne $STS_Copy))
|
|
{
|
|
if ( -e $LGNToBuildList)
|
|
{
|
|
LogStatus($STS_ToBuildList);
|
|
return 1;
|
|
}
|
|
}
|
|
unless (open(INFILE, $LGNList))
|
|
{
|
|
errmsg("Fatal: can't open $LGNList");
|
|
|
|
return $Result;
|
|
}
|
|
@Bufs=<INFILE>;
|
|
|
|
close(INFILE);
|
|
|
|
unless (open(OUTFILE, ">$LGNToBuildList"))
|
|
{
|
|
errmsg("Fatal: can't open output or $LGNToBuildList");
|
|
return $Result;
|
|
}
|
|
|
|
$Fresh=0;
|
|
if ( ! -e $LGNSnapt )
|
|
{
|
|
$Fresh=1;
|
|
|
|
foreach $Line (@Bufs)
|
|
{
|
|
chomp($Line);
|
|
$Line =~ s/\s//g;
|
|
if (length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
$Path="$nttree\\$Line";
|
|
if (-e $Path)
|
|
{
|
|
print (OUTFILE "$Line\n");
|
|
$Item_no++;
|
|
}
|
|
}
|
|
close(OUTFILE);
|
|
}
|
|
else
|
|
#
|
|
# Snap shot exists
|
|
#
|
|
{
|
|
$Fresh=0;
|
|
if (-e $LGNSnapt)
|
|
{
|
|
if (-e $LGNSnapBak)
|
|
{
|
|
if (system("del $LGNSnapBak") != 0)
|
|
{
|
|
errmsg("Fatal:Can't delete $LGNSnapBak");
|
|
return $Result;
|
|
}
|
|
}
|
|
($FileName, $Path ) = fileparse($LGNSnapBak);
|
|
if (system("ren $LGNSnapt $FileName") != 0)
|
|
{
|
|
errmsg("Fatal:Can't rename $LGNSnapt to $LGNSnapBak");
|
|
return $Result;
|
|
}
|
|
}
|
|
#
|
|
# Create the snap files
|
|
#
|
|
if (! &CreateSnapFile($LGNSnapt,\@Bufs))
|
|
{
|
|
errmsg("Fatal:Create $LGNSnapt failed");
|
|
return $Result;
|
|
}
|
|
system("windiff $LGNSnapBak $LGNSnapt -Fx $TempDiffFile");
|
|
FilterWindiff($TempDiffFile,$TempDiffFile);
|
|
#
|
|
# Uniqify the $TempDiffFile
|
|
#
|
|
$WindiffCommand="perl $razpath\\PostBuildScripts\\unique.pl -i\:$TempDiffFile -o\:$TempDiffFile1";
|
|
system("$WindiffCommand" );
|
|
#
|
|
# Now, Read $TempDiffFile1 and create $LGNToBuildList
|
|
#
|
|
unless (open(INFILE, $TempDiffFile1))
|
|
{
|
|
errmsg("can't open $TempDiffFile1");
|
|
return $Result;
|
|
}
|
|
@Diffs=<INFILE>;
|
|
close(INFILE);
|
|
unless (open(OUTFILE, ">$LGNToBuildList"))
|
|
{
|
|
errmsg("Fatal: can't open output or $LGNToBuildList");
|
|
return $Result;
|
|
}
|
|
foreach $Line (@Diffs)
|
|
{
|
|
chomp($Line);
|
|
$Line =~ s/\s//g;
|
|
if (length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
($FilePath, $Size, $Mtime ) = split ( /,+/, $Line);
|
|
chomp($FilePath);
|
|
($FileName, $Path ) = fileparse($FilePath);
|
|
chomp($FileName);
|
|
$FileName =~ s/\s//g;
|
|
print (OUTFILE "$FileName\n");
|
|
}
|
|
close(OUTFILE);
|
|
}
|
|
$Result=1;
|
|
#
|
|
# Log the current state so that we may restart without problem
|
|
#
|
|
&LogStatus($STS_ToBuildList);
|
|
|
|
return $Result;
|
|
}
|
|
|
|
#
|
|
# Generate the list of binaries from which resource are move out.
|
|
#
|
|
sub DoGenerateBuildList
|
|
{
|
|
my ($Result, $Line, @FilesList, $FilePath, $CodePath, $Item_No);
|
|
my($FileName, $Path);
|
|
|
|
$Result = 0;
|
|
|
|
unless (open(OUTFILE, ">$LGNBuildList"))
|
|
{
|
|
errmsg("Can't open output $LGNBuildList");
|
|
return $Result;
|
|
}
|
|
if(!opendir(LOCBINDIR, $CodeBinPath))
|
|
{
|
|
errmsg ("Can't open $CodeBinPath");
|
|
return $Result;
|
|
}
|
|
@FilesList = grep !/^\.\.?\z/ , readdir LOCBINDIR;
|
|
$Item_No=scalar(@FilesList);
|
|
logmsg("CodeBin total:$Item_No");
|
|
close(LOCBINDIR);
|
|
foreach $Line (@FilesList)
|
|
{
|
|
chomp($Line);
|
|
$Line =~ s/\s//g;
|
|
if (length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
($FileName, $Path ) = fileparse($Line);
|
|
#
|
|
# Double check if corr. .mui file exists
|
|
#
|
|
$FilePath = "$RCBinPath\\$FileName.mui";
|
|
$CodePath = "$CodeBinPath\\$FileName";
|
|
if ( (-e $FilePath) && (-e $CodePath))
|
|
{
|
|
print (OUTFILE "$FileName\n");
|
|
}
|
|
else
|
|
{
|
|
errmsg("$Line exits but $FilePath / $CodePath is missed");
|
|
}
|
|
|
|
|
|
}
|
|
close(OUTFILE);
|
|
|
|
#
|
|
# Log the current state so that we may restart without problem
|
|
#
|
|
&LogStatus($STS_BuildList);
|
|
$Result = 1;
|
|
return $Result;
|
|
}
|
|
#
|
|
# Generate the list of CMF (Compact Resource file) which contain binaries, from which resource are move out.
|
|
#
|
|
sub DoGenerateCMFList
|
|
{
|
|
my ($Result, $Line, @FilesList, $FilePath, $Item_No);
|
|
my($FileName, $Path);
|
|
|
|
if ( ! $fNeedGenerateCMF)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
$Result = 0;
|
|
|
|
unless (open(OUTFILE, ">$LGNCMFList"))
|
|
{
|
|
errmsg("Can't open output $LGNCMFList");
|
|
return $Result;
|
|
}
|
|
if(!opendir(LOCBINDIR, $CMFBinPath))
|
|
{
|
|
errmsg ("Can't open $CMFBinPath");
|
|
return $Result;
|
|
}
|
|
@FilesList = grep !/^\.\.?\z/ , readdir LOCBINDIR;
|
|
$Item_No=scalar(@FilesList);
|
|
logmsg("CMFBin total:$Item_No");
|
|
close(LOCBINDIR);
|
|
foreach $Line (@FilesList)
|
|
{
|
|
chomp($Line);
|
|
$Line =~ s/\s//g;
|
|
if (length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
($FileName, $Path ) = fileparse($Line);
|
|
#
|
|
# Double check
|
|
#
|
|
$FilePath = "$CMFBinPath\\$FileName";
|
|
if ( -e $FilePath)
|
|
{
|
|
print (OUTFILE "$FileName\n");
|
|
}
|
|
else
|
|
{
|
|
errmsg("$Line exits but $FilePath is missed");
|
|
}
|
|
|
|
}
|
|
close(OUTFILE);
|
|
#
|
|
# Log the current state so that we may restart without problem
|
|
#
|
|
&LogStatus($STS_CMFList);
|
|
$Result = 1;
|
|
return $Result;
|
|
}
|
|
#
|
|
# Copy Midified Binary and RC binary to $nttree
|
|
#
|
|
# Case: if $fNeedGenerateCMF is true, copy *.cmf from $CMFBinPath
|
|
# else copy *.mui from $RCBinPath
|
|
#
|
|
sub DoCopyLGNBinary
|
|
{
|
|
my ($Result, $ErrCnt, $Line, @Bufs, @Bufs_CMF, $FilePathRC, $FilePathCode, $DestPath);
|
|
|
|
$Result = 0;
|
|
$ErrCnt=0;
|
|
|
|
unless (open(INFILE, $LGNBuildList))
|
|
{
|
|
errmsg("fatal: DoCopyLGNBinary:: can't open input for $LGNBuildList");
|
|
return $Result;
|
|
}
|
|
@Bufs=<INFILE>;
|
|
close(INFILE);
|
|
if ($fNeedGenerateCMF)
|
|
{
|
|
unless (open(INFILE, $LGNCMFList))
|
|
{
|
|
errmsg("fatal: DoCopyLGNBinary:: can't open input for $LGNCMFList");
|
|
return $Result;
|
|
}
|
|
@Bufs_CMF=<INFILE>;
|
|
close(INFILE);
|
|
}
|
|
|
|
#
|
|
# Open a Status file to keep the state so that we may restart correctly
|
|
#
|
|
unless (open(OUTFILE, ">$LGNTCopyLock"))
|
|
{
|
|
errmsg("fatal: DoCopyLGNBinary:: can't open output for $LGNTCopyLock");
|
|
return $Result;
|
|
}
|
|
print (OUTFIULE "$STS_CopyLock");
|
|
close (OUTFILE);
|
|
LogStatus($STS_CopyStart);
|
|
|
|
|
|
foreach $Line (@Bufs)
|
|
{
|
|
chomp($Line);
|
|
$Line =~ s/\s//g;
|
|
if (length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
|
|
$FilePathRC = "$RCBinPath\\$Line.mui";
|
|
$FilePathCode = "$CodeBinPath\\$Line";
|
|
#
|
|
# Copy RCBin only if CMF is not enabled
|
|
#
|
|
if ( ! $fNeedGenerateCMF)
|
|
{
|
|
$DestPath="$nttree\\$Line.mui";
|
|
if ( system("copy/y $FilePathRC $DestPath") != 0)
|
|
{
|
|
$ErrCnt++;
|
|
errmsg("DoCopyLGNBinary:: Can't copy $FilePathRC");
|
|
}
|
|
}
|
|
$DestPath="$nttree\\$Line";
|
|
if ( system("copy/y $FilePathCode $DestPath") != 0)
|
|
{
|
|
$ErrCnt++;
|
|
errmsg("DoCopyLGNBinary:: Can't copy $FilePathCode");
|
|
}
|
|
}
|
|
#
|
|
# Copy CMF files if it's enabled
|
|
#
|
|
if ($fNeedGenerateCMF)
|
|
{
|
|
foreach $Line (@Bufs_CMF)
|
|
{
|
|
chomp($Line);
|
|
$Line =~ s/\s//g;
|
|
if (length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
$FilePathRC = "$CMFBinPath\\$Line";
|
|
$DestPath="$nttree\\$Line";
|
|
if ( system("copy/y $FilePathRC $DestPath") != 0)
|
|
{
|
|
$ErrCnt++;
|
|
errmsg("DoCopyLGNBinary:: Can't copy $FilePathRC");
|
|
}
|
|
}
|
|
}
|
|
if ( $ErrCnt == 0)
|
|
{
|
|
$Result = 1;
|
|
logmsg("DoCopyLGNBinary successfully");
|
|
&LogStatus($STS_Copy);
|
|
}
|
|
else
|
|
{
|
|
errmsg("DoCopyLGNBinary got errors");
|
|
}
|
|
if (-e $LGNTCopyLock)
|
|
{
|
|
if ( system("del $LGNTCopyLock") != 0)
|
|
{
|
|
errmsg("Can't delete $LGNTCopyLock");
|
|
}
|
|
}
|
|
return $Result;
|
|
}
|
|
|
|
sub DoVerify
|
|
{
|
|
#
|
|
# Check if last operation terminated abnormally
|
|
#
|
|
if ( -e $LGNTCopyLock)
|
|
{
|
|
if ( GetLastStatus() eq $STS_CopyStart)
|
|
{
|
|
logmsg("Recover needed");
|
|
DoCopyLGNBinary();
|
|
DoGenerateSnap(0,"Null");
|
|
logmsg("Recover completed");
|
|
}
|
|
if (system("del $LGNTCopyLock") != 0)
|
|
{
|
|
errmsg("Recover: can't delete $LGNTCopyLock");
|
|
}
|
|
}
|
|
return 1;
|
|
|
|
}
|
|
|
|
#
|
|
# Generate Snap File
|
|
# This routine will be called through pbuild table when the last step of language neutral build is
|
|
# executed. Keep a snap of last state will help us to support incremental build.
|
|
#
|
|
sub DoGenerateSnap
|
|
{
|
|
my ($bUseDefault, $AltFilePath) = @_;
|
|
|
|
my ($Result, @Bufs, $FilePath, $FileName, $Path);
|
|
|
|
$Result = 0;
|
|
|
|
#
|
|
# Backup previous Snap file
|
|
#
|
|
if ( ! $bUseDefault)
|
|
{
|
|
if (-e $LGNSnapBak)
|
|
{
|
|
if (system("del $LGNSnapBak") != 0)
|
|
{
|
|
errmsg("Fatal:Can't delete $LGNSnapBak");
|
|
return $Result;
|
|
}
|
|
($FileName, $Path ) = fileparse($LGNSnapBak);
|
|
if (system("ren $LGNSnapt $FileName") != 0)
|
|
{
|
|
errmsg("Fatal:Can't rename $LGNSnapt to $LGNSnapBak");
|
|
return $Result;
|
|
}
|
|
}
|
|
$FilePath = $LGNSnapt;
|
|
}
|
|
else
|
|
{
|
|
$FilePath = $AltFilePath;
|
|
}
|
|
unless (open(INFILE, $LGNList))
|
|
{
|
|
errmsg("Fatal: can't open $LGNList");
|
|
return $Result;
|
|
}
|
|
@Bufs=<INFILE>;
|
|
close(INFILE);
|
|
#
|
|
# Create the snap files
|
|
#
|
|
if (! &CreateSnapFile($FilePath,\@Bufs))
|
|
{
|
|
errmsg("Fatal:Create $FilePath failed");
|
|
return $Result;
|
|
}
|
|
$Result=1;
|
|
return $Result;
|
|
}
|
|
|
|
#
|
|
# Generate Snap File
|
|
#
|
|
# Snap File contains File size and last modification date for the binaries in $nttree
|
|
#
|
|
sub CreateSnapFile
|
|
{
|
|
|
|
my ($OutputPath, $pItemsList) = @_;
|
|
|
|
my ($Line, $Result, $FilePath);
|
|
|
|
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks);
|
|
|
|
$Result = 0;
|
|
|
|
unless (open(OUTFILE, ">$OutputPath"))
|
|
{
|
|
errmsg("Can't open output $FilePath to generate Snap file");
|
|
return $Result;
|
|
}
|
|
|
|
foreach $Line ( @$pItemsList )
|
|
{
|
|
chomp($Line);
|
|
$Line =~ s/\s//g;
|
|
if (length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
$FilePath = "$nttree\\$Line";
|
|
#
|
|
# Get the file status by using stat function
|
|
#
|
|
if (-e $FilePath)
|
|
{
|
|
( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime,
|
|
$ctime, $blksize, $blocks ) = stat( $FilePath );
|
|
#
|
|
# Snap File contains File size and last modification date
|
|
#
|
|
print( OUTFILE "$FilePath , $size , $mtime\n" );
|
|
}
|
|
}
|
|
close( OUTFILE );
|
|
$Result =1;
|
|
|
|
return $Result;
|
|
}
|
|
|
|
#
|
|
# Filter for output of windiff
|
|
# The output of windiff is the comparison of current Snap and previous Snap file
|
|
# We'll understand which Binaries are changed.
|
|
# We use this approach to support Language Neutral Incremental build.
|
|
#
|
|
sub FilterWindiff
|
|
{
|
|
my ($InputFile,$OutputFile) = @_;
|
|
my ($Result, @InfileLines, $Line, $FileName, $Junk );
|
|
|
|
$Result = 0;
|
|
|
|
|
|
unless ( open( INFILE, $InputFile ) )
|
|
{
|
|
errmsg( "Fatal:Failed to open '$InputFile' for reading" );
|
|
return $Result;
|
|
}
|
|
|
|
@InfileLines = <INFILE>;
|
|
close( INFILE );
|
|
|
|
|
|
unless ( open( OUTFILE, ">$OutputFile" ) )
|
|
{
|
|
errmsg( "Fatal:Failed to open '$OutputFile' for writing" );
|
|
return $Result;
|
|
}
|
|
#
|
|
# now parse out the interesting lines from windiff
|
|
#
|
|
foreach $Line ( @InfileLines )
|
|
{
|
|
chomp( $Line );
|
|
|
|
|
|
if ( $Line =~ /\-\- / )
|
|
{
|
|
next;
|
|
}
|
|
( $Junk, $Junk, $FileName, $Junk ) = split( /\s+/, $Line );
|
|
print( OUTFILE "$FileName\n" );
|
|
}
|
|
close( OUTFILE );
|
|
$Result = 1;
|
|
return $Result;
|
|
}
|
|
|