480 lines
14 KiB
Batchfile
480 lines
14 KiB
Batchfile
@rem ='
|
|
@echo off
|
|
REM ------------------------------------------------------------------
|
|
REM
|
|
REM SYMCD.cmd
|
|
REM Create Symbol CD.
|
|
REM
|
|
REM Copyright (c) Microsoft Corporation. All rights reserved.
|
|
REM
|
|
REM ------------------------------------------------------------------
|
|
perl -x "%~f0" %*
|
|
goto :EOF
|
|
REM ';
|
|
|
|
#!perl
|
|
use strict;
|
|
use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
|
|
use lib $ENV{RAZZLETOOLPATH};
|
|
|
|
use PbuildEnv;
|
|
use ParseArgs;
|
|
use File::Basename;
|
|
use IO::File;
|
|
use Win32;
|
|
use File::Path;
|
|
use File::Copy;
|
|
use IO::File;
|
|
use Logmsg;
|
|
|
|
#
|
|
# SFS: SYMBOL FILESPECS
|
|
# SFN: SYMBOL FILENAMES
|
|
# ST: SYMBOL TOOL
|
|
# SDIR: SYMBOL DIRECTORIES
|
|
# SOPT: SYMBOL OPTIONS
|
|
# COPT: COMMAND OPTIONS
|
|
#
|
|
my (%SFS, %SFN, %ST, %SDIR, %SOPT, %COPT);
|
|
|
|
my ($NTPostBld, $BuildArch, $BuildType, $RazzleToolPath, $BuildLogs, $Lang, $CoverageBuild,
|
|
$MungePath, $SymbolCD, $CabSize, $SymbolCDHandle, $Delegate, $ARCH, %DontShip, %SymBad,
|
|
$FileScope
|
|
);
|
|
|
|
sub Usage { print<<USAGE; exit(1) }
|
|
Munge public symbols
|
|
|
|
SymCD [-l lang] [-f filescope]
|
|
-l lang to specify which language
|
|
-f filescope to specify the filelist under pp directory
|
|
|
|
USAGE
|
|
|
|
|
|
#
|
|
# parse the command line arguments
|
|
#
|
|
parseargs(
|
|
'l:' => \$Lang,
|
|
# 'p:' => \$Project,
|
|
'f:' => \$FileScope,
|
|
|
|
'?' => \&Usage,
|
|
);
|
|
|
|
&main;
|
|
|
|
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
#
|
|
# Munge public symbols
|
|
#
|
|
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
sub main
|
|
{
|
|
&Initial_Variables();
|
|
&Munge_Public;
|
|
}
|
|
|
|
sub Munge_Public
|
|
{
|
|
my ($filename, $filepath, $fileext);
|
|
my ($mySymbol, $mySymbolPath, $myBinary, $myMungePath, $oldMungePath, $newMungePath);
|
|
my ($c_ext, @myCompOpt);
|
|
my ($optCL, $optML, $optLINK);
|
|
|
|
my @ppdirs = &Exists("$MungePath\\$FileScope");
|
|
|
|
@myCompOpt = @ENV{qw(_CL_ _ML_ _LINK_)} if (lc$ENV{'_BuildArch'} eq 'x86');
|
|
|
|
logmsg("Adding type info to some public pdb files for debugging...");
|
|
|
|
for (@ppdirs) {
|
|
next if (!-d);
|
|
($filename, $filepath, $fileext) = FileParse($_);
|
|
|
|
if (length($fileext) ne '3') {
|
|
errmsg("$_ name has the wrong format.");
|
|
return;
|
|
}
|
|
|
|
$mySymbol = &SymbolPath("$NTPostBld\\symbols", "retail", "$filename\.$fileext");
|
|
$mySymbolPath = &SymbolPath("$NTPostBld\\symbols", "retail");
|
|
$myBinary = "$NTPostBld\\$filename\.$fileext";
|
|
|
|
if (-f $mySymbol) {
|
|
$myMungePath = "$MungePath\\$filename\.$fileext";
|
|
($oldMungePath, $newMungePath) = ("$myMungePath\\original", "$myMungePath\\updated");
|
|
|
|
logmsg("Working on $filename\.$fileext");
|
|
|
|
## See if we need to do anything, or if the symbol file has already been updated
|
|
## If the symbol file passes symbol checking, with types present then don't update it.
|
|
if (!&IsSymchkFailed($myBinary, $mySymbolPath, "/o")) {
|
|
logmsg("Skipping $filename\.$fileext because it's public pdb already has type info in it.");
|
|
next;
|
|
}
|
|
|
|
mkpath([$oldMungePath, $newMungePath]);
|
|
|
|
## See if the pdb, if it exists, in original matches the exe in binaries
|
|
if (&IsSymchkFailed($myBinary, $oldMungePath, $SOPT{'PUB_SYM_FLAG'})) {
|
|
logmsg("Saving a copy of $filename\.pdb to $oldMungePath");
|
|
|
|
copy($mySymbol, $oldMungePath) or errmsg("copy $mySymbol to $oldMungePath failed.");
|
|
|
|
if (&IsSymchkFailed($myBinary, $oldMungePath, $SOPT{'PUB_SYM_FLAG'})) {
|
|
errmsg("cannot copy the correct pdb file to $oldMungePath\.");
|
|
next;
|
|
}
|
|
}
|
|
|
|
if (&Exists("$myMungePath\\*.*") > 0) {
|
|
|
|
if (!copy("$oldMungePath\\$filename\.pdb", $newMungePath)) {
|
|
errmsg("copy failed for $oldMungePath\\$filename\.pdb to $newMungePath\.");
|
|
next;
|
|
}
|
|
|
|
logmsg("Pushing type info into the stripped $filename\.pdb");
|
|
|
|
$c_ext = (-e "$myMungePath\\$filename\.c")? "c": "cpp";
|
|
|
|
if (&IsVC7PDB("$newMungePath\\$filename\.pdb")) {
|
|
logmsg("This is a vc7 pdb");
|
|
@ENV{qw(_CL_ _ML_ _LINK_)} = ();
|
|
} else {
|
|
logmsg("This is a vc6 pdb");
|
|
@ENV{qw(_CL_ _ML_ _LINK_)} = @myCompOpt;
|
|
}
|
|
|
|
logmsg("cl /nologo /Zi /Gz /c $myMungePath\\$filename\.$c_ext /Fd" . "$newMungePath\\$filename\.pdb /Fo" . "$newMungePath\\$filename\.obj");
|
|
|
|
if (system("cl /nologo /Zi /Gz /c $myMungePath\\$filename\.$c_ext /Fd" . "$newMungePath\\$filename\.pdb /Fo" . "$newMungePath\\$filename\.obj") > 0) {
|
|
errmsg("cl /Zi /Gz /c $myMungePath\\$filename\.$c_ext /Fd" . "$newMungePath\\$filename\.pdb had errors.");
|
|
next;
|
|
}
|
|
if (&IsSymchkFailed($myBinary, $newMungePath, "/o $SOPT{'PUB_SYM_FLAG'}")) {
|
|
errmsg("the munged $newMungePath\\$filename\.pdb doesn't match $myBinary.");
|
|
next;
|
|
}
|
|
|
|
logmsg("Copying $newMungePath\\$filename\.pdb to $mySymbolPath\\$fileext");
|
|
copy("$newMungePath\\$filename\.pdb", "$mySymbolPath\\$fileext");
|
|
|
|
if (&IsSymchkFailed($myBinary, $mySymbolPath, "/o $SOPT{'PUB_SYM_FLAG'}")) {
|
|
|
|
copy("$oldMungePath\\$filename\.pdb", "$mySymbolPath\\$fileext");
|
|
|
|
errmsg("the munged $newMungePath\\$filename\.pdb didn't get copied to $mySymbolPath\\$fileext\.");
|
|
|
|
logmsg("Copying the original pdb back to $mySymbolPath\\$fileext");
|
|
copy("$oldMungePath\\$filename\.$fileext", "$mySymbolPath\\$fileext") or do {
|
|
errmsg("cannot get $filename\.$fileext symbols copied to $mySymbolPath\\$fileext\.");
|
|
next;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
logmsg("Skipping $filename\.$fileext because $mySymbol does not exist.");
|
|
}
|
|
}
|
|
|
|
@ENV{qw(_CL_ _ML_ _LINK_)} = @myCompOpt if (lc$ENV{'_BuildArch'} eq 'x86');
|
|
|
|
return;
|
|
}
|
|
|
|
####################################################################################
|
|
|
|
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
#
|
|
# Initial variables
|
|
#
|
|
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
sub Initial_Variables
|
|
{
|
|
# Set Variables
|
|
$Lang = $ENV{'LANG'} if ("$Lang" eq "");
|
|
$ENV{'LANG'} = $Lang;
|
|
$BuildArch = $ENV{'_BuildArch'};
|
|
$BuildType = $ENV{'_BuildType'};
|
|
$NTPostBld = $ENV{'_NTPostBld'};
|
|
# $NTPostBld = "d:\\Ins_Sym\\$Project\\$Lang";
|
|
$MungePath = "$NTPostBld\\pp";
|
|
$SymbolCD = "$NTPostBld\\SymbolCD";
|
|
$RazzleToolPath = $ENV{'RazzleToolPath'};
|
|
$BuildLogs = "$NTPostBld\\build_logs";
|
|
$CabSize = 60000000;
|
|
$SymbolCDHandle = '';
|
|
# $Delegate = new Delegate 3, $ENV{'NUMBER_OF_PROCESSORS'} * 4;
|
|
# $ARCH = "\\\\arch\\archive\\ms\\windows\\windows_xp\\rtm\\2600\\$BuildType\\all\\$BuildArch\\pub";
|
|
|
|
$ARCH = "d:\\Ins_Sym\\Win2k\\$Lang\\symbols";
|
|
|
|
# $Symbol_Path_Creator = {
|
|
# 'FULL' => \&Full_Package_Path,
|
|
# 'UPDATE' => \&Update_Package_Path
|
|
# };
|
|
|
|
# SDIR: SYMBOL DIRECTORIES
|
|
%SDIR = (
|
|
'SYMBOLCD' => $SymbolCD,
|
|
'PUBSYM' => "$NTPostBld\\Symbols",
|
|
|
|
'FULL_CD' => "$NTPostBld\\SymbolCD\\CD",
|
|
# 'FULL_PKG' => &{$Symbol_Path_Creator->{'FULL'}}("$NTPostBld\\SymbolCD\\CD\\Symbols", $BuildArch, $BuildType),
|
|
# 'FULL_INF' => &{$Symbol_Path_Creator->{'FULL'}}("$NTPostBld\\SymbolCD\\CD\\Symbols", $BuildArch, $BuildType),
|
|
'FULL_CAB' => "$SymbolCD\\CABs\\FULL",
|
|
'FULL_DDF' => "$SymbolCD\\DDF\\FULL",
|
|
'FULL_CDF' => "$SymbolCD\\DDF\\FULL",
|
|
# 'FULL_CAT' => &{$Symbol_Path_Creator->{'FULL'}}("$NTPostBld\\SymbolCD\\CD\\Symbols", $BuildArch, $BuildType),
|
|
|
|
'UPDATE_CD' => "$NTPostBld\\SymbolCD\\UPD",
|
|
# 'UPDATE_PKG' => &{$Symbol_Path_Creator->{'UPDATE'}}("$NTPostBld\\SymbolCD\\UPD\\Symbols", $BuildArch, $BuildType),
|
|
# 'UPDATE_INF' => &{$Symbol_Path_Creator->{'UPDATE'}}("$NTPostBld\\SymbolCD\\UPD\\Symbols", $BuildArch, $BuildType),
|
|
'UPDATE_CAB' => "$SymbolCD\\CABs\\UPDATE",
|
|
'UPDATE_DDF' => "$SymbolCD\\DDF\\UPDATE",
|
|
'UPDATE_CDF' => "$SymbolCD\\DDF\\UPDATE",
|
|
# 'UPDATE_CAT' => &{$Symbol_Path_Creator->{'UPDATE'}}("$NTPostBld\\SymbolCD\\UPD\\Symbols", $BuildArch, $BuildType),
|
|
);
|
|
|
|
# SFS: SYMBOL FILESPECS
|
|
%SFS = (
|
|
'CD' => $SDIR{'SYMBOLCD'} . '\\SymbolCD.txt',
|
|
# 'BLDNUM' => &{$Symbol_Path_Creator->{'FULL'}}("$NTPostBld\\SymbolCD\\CD\\Symbols", $BuildArch, $BuildType) . "\\QFEnum.txt",
|
|
'LIST' => $SDIR{'SYMBOLCD'} . '\\SymList.txt',
|
|
'BAD' => $SDIR{'SYMBOLCD'} . '\\SymBad.txt',
|
|
'SYMUPD' => $SDIR{'SYMBOLCD'} . '\\SymUpd.txt',
|
|
'CAGENERR' => $SDIR{'SYMBOLCD'} . '\\cabgenerr.log',
|
|
'EXCLUDE' => $SDIR{'SYMBOLCD'} . '\\Exclude.txt',
|
|
'BINDIFF' => $BuildLogs . '\\bindiff.txt',
|
|
'WITHTYPES' => $SDIR{'SYMBOLCD'} . '\\SymbolsWithTypes.txt',
|
|
'DONTSHIP' => $SDIR{'SYMBOLCD'} . '\\SymDontShip.txt'
|
|
);
|
|
|
|
# SFN: SYMBOL FILENAMES
|
|
%SFN = (
|
|
'FULL_INF' => 'Symbols',
|
|
'FULL_CAB' => 'Symbols',
|
|
'FULL_DDF' => 'Symbols',
|
|
'FULL_CDF' => 'Symbols',
|
|
'FULL_CAT' => 'Symbols',
|
|
|
|
'UPDATE_INF' => 'Symbols',
|
|
'UPDATE_CAB' => 'Symbols',
|
|
'UPDATE_DDF' => 'Symbols',
|
|
'UPDATE_CDF' => 'Symbols',
|
|
'UPDATE_CAT' => 'Symbols',
|
|
);
|
|
|
|
# ST: SYMBOL TOOL
|
|
%ST = (
|
|
'MAKE' => "symmake.exe",
|
|
'PERL' => "perl.exe",
|
|
'CHECK' => "symchk.exe",
|
|
'BENCH' => "cabbench.exe",
|
|
'DUMP' => "pdbdump.exe",
|
|
'SIGN' => $RazzleToolPath . "\\ntsign.cmd",
|
|
'CAB' => $RazzleToolPath . "\\sp\\symcab.cmd"
|
|
);
|
|
|
|
# SOPT: SYMBOL OPTIONS
|
|
#
|
|
# the default option is doing all steps
|
|
#
|
|
%SOPT = (
|
|
'PUB_SYM_FLAG' => '/p',
|
|
'GOLD_BUILD' => 1,
|
|
'RUN_ALWAYS' => 1,
|
|
'NEED_MUNGE_PUBLIC' => 1,
|
|
'NEED_CREATE_SYMBOLCD_TXT' => undef,
|
|
'NEED_CREATE_MAKE_FILE' => 1,
|
|
'NEED_CREATE_SYMBOLCAT' => 1,
|
|
'NEED_CREATE_SYMBOLCAB' => 1,
|
|
'NEED_SIGN_FILES' => 1,
|
|
'NEED_FLAT_DIR' => 1,
|
|
'NEED_CLEAN_BUILD' => 1,
|
|
'FLAT_SYMBOL_PATH' => undef,
|
|
'USE_SYMLIST' => undef
|
|
);
|
|
|
|
if ((defined $COPT{'NEED_ALL'}) && (defined $COPT{'NEED_MUNGE_PUBLIC'})) {
|
|
errmsg("Error options! Please specify either -m or -t");
|
|
exit(1);
|
|
}
|
|
|
|
$FileScope = "*.*" if ("$FileScope" eq "");
|
|
|
|
# if neither is official build machine, nor assign -t in command line,
|
|
# or if is official build machine, but assign -m in command line,
|
|
#
|
|
# we will only munge public symbols
|
|
#
|
|
# if (((!exists $ENV{'OFFICIAL_BUILD_MACHINE'}) &&
|
|
# (!defined $COPT{'NEED_ALL'})) ||
|
|
# ((exists $ENV{'OFFICIAL_BUILD_MACHINE'}) &&
|
|
# (defined $COPT{'NEED_MUNGE_PUBLIC'}))) {
|
|
# @SOPT{qw(NEED_MUNGE_PUBLIC
|
|
# NEED_CREATE_SYMBOLCD_TXT
|
|
# NEED_CREATE_MAKE_FILE
|
|
# NEED_CREATE_SYMBOLCAT
|
|
# NEED_CREATE_SYMBOLCAB
|
|
# NEED_SIGN_FILES)} = (1, undef, undef, undef, undef, undef);
|
|
# }
|
|
|
|
# if ($SOPT{'NEED_CLEAN_BUILD'}) {
|
|
# rmtree([@SDIR{qw(FULL_DDF FULL_CD FULL_CAB UPDATE_DDF UPDATE_CD UPDATE_CAB)}]);
|
|
# }
|
|
}
|
|
|
|
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
#
|
|
# Small Subroutine
|
|
#
|
|
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
#
|
|
# IsSymchkFailed($binary, $symbol, $extraopt)
|
|
# - call symchk.exe to verify $binary matches with $symbol
|
|
#
|
|
sub IsSymchkFailed {
|
|
my ($binary, $symbol, $extraopt) = @_;
|
|
my ($fh, $record_error, $record_log, $result);
|
|
local $_;
|
|
|
|
if (defined $extraopt) {
|
|
if ($extraopt =~ /2\>/) {
|
|
$record_error = 1;
|
|
}
|
|
if ($extraopt =~ /[^2]\>/) {
|
|
$record_log = 1;
|
|
}
|
|
$extraopt =~ s/2?\>.*$//g;
|
|
}
|
|
$fh = new IO::File "$ST{'CHECK'} /t $binary /s $symbol $extraopt |";
|
|
|
|
while (<$fh>) {
|
|
chomp;
|
|
$result = $1 if /FAILED files = (\d+)/;
|
|
logmsg($_) if ($record_log);
|
|
logmsg($_) if (($record_error) && (/^ERROR/i));
|
|
}
|
|
|
|
undef $fh;
|
|
|
|
return $result;
|
|
}
|
|
|
|
#
|
|
# SymbolPath($root, $subdir, $filename)
|
|
# - return the symbol path for the binary
|
|
#
|
|
sub SymbolPath
|
|
{
|
|
my ($root, $subdir, $filename) = @_;
|
|
$root .= "\\$subdir" if (!$SOPT{'FLAT_SYMBOL_PATH'});
|
|
if (defined $filename) {
|
|
$filename =~ /\.([^\.]+)$/;
|
|
$root .= "\\$1\\$`";
|
|
return "$root\.pdb" if (-e "$root\.pdb");
|
|
return "$root\.dbg" if (-e "$root\.dbg");
|
|
$root .= ".pdb";
|
|
}
|
|
return $root;
|
|
}
|
|
|
|
#
|
|
# Full_Package_Path($root, $myarch, $mytype)
|
|
# - for compatible reason, we create a function to construct the path of the symbols.exe of the full package
|
|
#
|
|
sub Full_Package_Path
|
|
{
|
|
my ($root, $myarch, $mytype) = @_;
|
|
$mytype =~ s/fre/retail/ig;
|
|
$mytype =~ s/chk/debug/ig;
|
|
return "$root\\$myarch\\$mytype"; # temporary
|
|
}
|
|
|
|
#
|
|
# Update_Package_Path($root, $myarch, $mytype)
|
|
# - for compatible reason, we create a function to construct the path of the symbols.exe of the update package
|
|
#
|
|
sub Update_Package_Path
|
|
{
|
|
my ($root, $myarch, $mytype) = @_;
|
|
return $root; # \\$myarch\\$mytype"; # temporary
|
|
}
|
|
|
|
#
|
|
# IsVC7PDB($pdbspec)
|
|
# - because the MD5 hash value is 0000-0000-0000-000000000000 for the symbols built by VC6 or older
|
|
# - we can use it to determine the pdb is VC7 or not
|
|
#
|
|
sub IsVC7PDB {
|
|
my ($pdbspec) = shift;
|
|
my $fh = new IO::File "$ST{'DUMP'} $pdbspec hdr |";
|
|
local $_;
|
|
while (<$fh>) {
|
|
return 0 if /0000-0000-0000-000000000000/i;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
#
|
|
# Check_Exist_File($filename, $logfile)
|
|
# - this is a function generator, which generates a function for checking the $filename exist or not
|
|
# - it also check if the $logfile has 'ERROR:' in it
|
|
#
|
|
|
|
sub Check_Exist_File
|
|
{
|
|
my ($filename, $logfile) = @_;
|
|
return sub {
|
|
if (-e $filename) {
|
|
return 1;
|
|
} else {
|
|
my $fh = new IO::File $logfile;
|
|
for (<$fh>) {
|
|
chomp;
|
|
next if (!/.+ERROR\: /i);
|
|
errmsg("Error - $'");
|
|
}
|
|
$fh->close();
|
|
logmsg("$filename did not get created.");
|
|
return 0;
|
|
}
|
|
};
|
|
}
|
|
|
|
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
#
|
|
# Common Subroutine
|
|
#
|
|
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
sub FileParse
|
|
{
|
|
my ($name, $path, $ext) = fileparse(shift, '\.[^\.]+$');
|
|
$ext =~ s/^\.//;
|
|
return $name, $path, $ext;
|
|
}
|
|
|
|
sub IsUSA
|
|
{
|
|
# return (lc$ENV{'lang'} eq 'usa');
|
|
return 1;
|
|
}
|
|
|
|
sub Exists
|
|
{
|
|
my @list = glob(shift);
|
|
return (wantarray)?@list:$#list + 1;
|
|
}
|
|
|
|
1;
|
|
|
|
__END__
|