use Data::Dumper;\r
use Archive::Zip;\r
use Logger;\r
-require "commandandcontrol.pl";\r
require "copyfiles.pl";\r
require "prunefiles.pl";\r
-require "repository1.pl";\r
require "signfiles.pl";\r
require "zipXML.pl";\r
\r
my $BAIL;\r
-$0 = fileparse($0);\r
-my $MAKE = 'NMAKE';\r
+$0 = fileparse($0);\r
+my $OPT = {foo => 'bar'};\r
+my $MAKE = 'NMAKE';\r
our $config;\r
-local $bOutputCleaned = 0;\r
\r
sub get_info {\r
my $cmd = shift || die;\r
return { cmd => $cmd, full => $full};\r
}\r
\r
+sub usage {\r
+ print <<USAGE;\r
+Usage: $0 [options] NMAKE-options\r
+\r
+ Options are case insensitive.\r
+\r
+ Options:\r
+ /help /? usage information (what you now see).\r
+ /config /f path Path to config file. Default is bkwconfig.xml.\r
+ /srcdir /r dir Source directory to use. Should contain \r
+ pismere/athena. If cvstag or svntag is null, \r
+ the directory should be prepopulated.\r
+ /outdir /o dir Directory to be created where build results will go\r
+ /repository checkout | co \\ What repository action to take.\r
+ update | up ) Options are to checkout, update or \r
+ skip / take no action [skip].\r
+ /username /u name username used to access svn if checking out.\r
+ /cvstag /c tag use -r <tag> in cvs command\r
+ /svnbranch /b tag use /branches/<tag> instead of /trunk.\r
+ /svntag /s tag use /tags/<tag> instead of /trunk.\r
+ /debug /d Do debug make instead of release make.\r
+ /[no]make Control the make step.\r
+ /clean Build clean target.\r
+ /[no]package Control the packaging step.\r
+ /[no]sign Control signing of executable files.\r
+ /verbose /v Debug mode - verbose output.\r
+ /logfile /l path Where to write output. Default is bkw.pl.log.\r
+ /nolog Don't save output.\r
+ Other:\r
+ NMAKE-options any options you want to pass to NMAKE, which can be:\r
+ (note: /nologo is always used)\r
+\r
+USAGE\r
+ system("$MAKE /?");\r
+ }\r
+\r
sub handler {\r
my $sig = shift;\r
my $bailmsg = "Bailing out due to SIG$sig!\n";\r
local $cmdline = "bkw.pl";\r
foreach $arg (@ARGV) {$cmdline .= " $arg";}\r
\r
- local @savedARGV = @ARGV;\r
+ Getopt::Long::Configure('no_bundling', 'no_auto_abbrev',\r
+ 'no_getopt_compat', 'require_order',\r
+ 'ignore_case', 'pass_through',\r
+ 'prefix_pattern=(--|-|\+|\/)',\r
+ );\r
+ GetOptions($OPT,\r
+ 'help|h|?',\r
+ 'cvstag|c:s',\r
+ 'svntag|s:s',\r
+ 'svnbranch|b:s',\r
+ 'src|r:s',\r
+ 'out|o:s',\r
+ 'debug|d',\r
+ 'nodebug',\r
+ 'config|f=s',\r
+ 'logfile|l:s',\r
+ 'nolog',\r
+ 'repository:s',\r
+ 'username|u:s',\r
+ 'verbose|v',\r
+ 'vverbose',\r
+ 'make!',\r
+ 'clean',\r
+ 'package!',\r
+ 'sign!',\r
+ );\r
+\r
+ if ( $OPT->{help} ) {\r
+ usage();\r
+ exit(0);\r
+ }\r
+ \r
+ delete $OPT->{foo}; \r
\r
##++ Validate required conditions:\r
\r
+ local $argvsize = @ARGV;\r
+ if ($argvsize > 0) {\r
+ print "Error -- invalid argument: $ARGV[0]\n";\r
+ usage();\r
+ die;\r
+ }\r
+ \r
+ if (! exists $OPT->{config}) {$OPT->{config} = "bkwconfig.xml";}\r
+\r
# List of programs which must be in PATH:\r
my @required_list = ('sed', 'awk', 'which', 'cat', 'rm', 'cvs', 'svn', 'doxygen', \r
'hhc', 'candle', 'light', 'makensis', 'nmake', 'plink', 'filever');\r
\r
##++ Assemble configuration from config file and command line:\r
\r
- local $config = commandandcontrol("bkwconfig.xml", 0);\r
+ my $configfile = $OPT->{config};\r
+ my $bOutputCleaned = 0;\r
+\r
+ print "Info -- Reading configuration from $configfile.\n";\r
+\r
+ # Get configuration file:\r
+ my $xml = new XML::Simple();\r
+ $config = $xml->XMLin($configfile);\r
+ # Set up convenience variables:\r
+ local $odr = $config->{Config}; ## Options, directories, repository, environment.\r
+\r
+#while ($v = each %$OPT) {print "$v: $OPT->{$v}\n";}\r
+\r
+ # Scan the configuration for switch definitions:\r
+ while (($sw, $val) = each %$odr) {\r
+ next if (! exists $val->{def}); ## ?? Should always exist.\r
+\r
+ # Set/clear environment variables:\r
+ if ($val->{env}) {\r
+ if ($val->{def}) {$ENV{$sw} = (exists $val->{value}) ? $val->{value} : 1; }\r
+ else {delete $ENV{$sw}; }\r
+ }\r
+\r
+ # If the switch is in the command line, override the stored value:\r
+ if (exists $OPT->{$sw}) {\r
+ if (exists $val->{value}) {\r
+ $val->{value} = $OPT->{$sw}; \r
+ $val->{def} = 1;\r
+ }\r
+ else {\r
+ $val->{def} = $OPT->{$sw}; ## If no<switch>, value will be zero.\r
+ }\r
+ }\r
+ # If the switch can be negated, test that, too:\r
+ if ( ! ($val->{def} =~ /A/)) {\r
+ local $nosw = "no".$sw;\r
+ if (exists $OPT->{$nosw}) {\r
+ $val->{def} = 0;\r
+ }\r
+ }\r
+ \r
+ # For any switch definition with fixed values ("options"), validate:\r
+ if (exists $val->{options}) {\r
+ local $bValid = 0;\r
+ # options can be like value1|syn1 value2|syn2|syn3\r
+ foreach $option (split(/ /, $val->{options})) {\r
+ local $bFirst = 1;\r
+ local $sFirst;\r
+ foreach $opt (split(/\|/, $option)) {\r
+ # opt will be like value2, syn2, syn3\r
+ if ($bFirst) {\r
+ $sFirst = $opt; ## Remember the full name of the option.\r
+ $bFirst = 0;\r
+ }\r
+ if ($val->{value} =~ /$opt/i) {\r
+ $val->{value} = $sFirst; ## Save the full name.\r
+ $bValid = 1;\r
+ }\r
+ }\r
+ }\r
+ if (! $bValid) {\r
+ print "Fatal -- invalid $sw value $val->{value}. Possible values are $val->{options}.\n";\r
+ usage();\r
+ die;\r
+ }\r
+ }\r
+ }\r
\r
# Set up convenience variables:\r
- local $odr = $config->{Config}; ## Options, directories, repository, environment.\r
our $verbose = $odr->{verbose}->{def};\r
our $vverbose = $odr->{vverbose}->{def};\r
+ our $clean = $clean->{clean}->{def};\r
local $src = $odr->{src}->{value};\r
- local $wd = $src."\\pismere";\r
+ local $out = $odr->{out}->{value};\r
+\r
+ if ($clean && $odr->{package}->{def}) {\r
+ print "Info -- /clean forces /nopackage.\n";\r
+ $odr->{package}->{def} = 0;\r
+ }\r
+\r
+ if ($vverbose) {print "Debug -- Config: ".Dumper($config);}\r
+ \r
+ # Test the unix find command:\r
+ if (! exists $odr->{unixfind}->{value}) {\r
+ $odr->{unixfind}->{value} = "C:\\tools\\cygwin\\bin";\r
+ }\r
+ local $unixfind = $odr->{unixfind}->{value};\r
+\r
+ local $savedPATH = $ENV{PATH};\r
+ $ENV{PATH} = $unixfind.";".$savedPATH;\r
+ print "Info -- chdir to ".`cd`."\n" if ($verbose);\r
+ if (-e "a.tmp") {!system("rm a.tmp") or die "Fatal -- Couldn't clean temporary file a.tmp.";}\r
+ !system("find . -name a.tmp > b.tmp 2>&1") or die "Fatal -- find test failed.";\r
+ local $filesize = -s "b.tmp";\r
+ $ENV{PATH} = $savedPATH;\r
+ if ($filesize > 0) {\r
+ die "Fatal -- $unixfind does not appear to be a path to a UNIX find command.";\r
+ }\r
+ \r
+ # Don't allow /svntag and /svnbranch simultaneously:\r
+ if ( (length $odr->{svntag}->{value} > 0) && \r
+ (length $odr->{svnbranch}->{value} > 0) ) {\r
+ die "Fatal -- Can't specify both /SVNTAG and /SVNBRANCH.";\r
+ }\r
\r
##-- Assemble configuration from config file and command line.\r
\r
- local $rverb = $odr->{repository}->{value};\r
+ local $rverb = $odr->{repository}->{value};\r
+ if ( ($rverb =~ /checkout/) && $clean) {\r
+ print "Warning -- Because sources afe being checked out, make clean will not be run.\n";\r
+ $clean = $odr->{clean}->{def} = 0;\r
+ }\r
+\r
+ my $wd = $src."\\pismere";\r
\r
if (! ($rverb =~ /skip/)) {\r
local $len = 0;\r
!system("rmdir $wd") or die "Fatal -- Couldn't remove $wd.";\r
}\r
\r
-##++ Begin repository action:\r
- repository1($config);\r
-\r
- @ARGV = @savedARGV;\r
- # Now use the configuration file in the repository sources, forcing use of that config file:\r
- $config = commandandcontrol("$src/pismere/athena/auth/krb5/src/windows/build/bkwconfig.xml", 1);\r
- \r
-##-- End repository action.\r
-\r
- # Set up convenience variables:\r
- $odr = $config->{Config}; ## Options, directories, repository, environment.\r
- $verbose = $odr->{verbose}->{def};\r
- $vverbose = $odr->{vverbose}->{def};\r
- our $clean = $odr->{clean}->{def};\r
- $src = $odr->{src}->{value};\r
- $out = $odr->{out}->{value};\r
- $wd = "$src\\pismere";\r
- \r
# Begin logging:\r
my $l;\r
if ($odr->{logfile}->{def}) {\r
$l->no_die_handler; ## Needed so XML::Simple won't throw exceptions.\r
}\r
\r
- print "Info -- Executing $cmdline\n";\r
- print "Info -- Option settings:\n";\r
- foreach $sw (sort keys %$odr) {\r
- local $val = $odr->{$sw};\r
- if ($val->{def}) {\r
- if (exists $val->{value}) {print " $sw $val->{value}\n";}\r
- else {print " $sw\n";}\r
+ print "Executing $cmdline\n";\r
+ \r
+##++ Begin repository action:\r
+ if ($rverb =~ /skip/) {print "Info -- *** Skipping repository access.\n" if ($verbose);}\r
+ else {\r
+ if ($verbose) {print "Info -- *** Begin fetching sources.\n";}\r
+ local $cvspath = "$src";\r
+ if (! -d $cvspath) { ## xcopy will create the entire path for us.\r
+ !system("echo foo > a.tmp") or die "Fatal -- Couldn't create temporary file in ".`cd`;\r
+ !system("echo F | xcopy a.tmp $cvspath\\a.tmp") or die "Fatal -- Couldn't xcopy to $cvspath.";\r
+ !system("rm a.tmp") or die "Fatal -- Couldn't remove temporary file.";\r
+ !system("rm $cvspath\\a.tmp") or die "Fatal -- Couldn't remove temporary file.";\r
}\r
- else {print " no$sw\n";}\r
- }\r
+ \r
+ # Set up cvs environment variables:\r
+ $ENV{CVSROOT} = $odr->{CVSROOT}->{value};\r
+ local $krb5dir = "$wd\\athena\\auth\\krb5";\r
\r
- if ($vverbose) {print "Debug -- Config: ".Dumper($config);}\r
- \r
- if ( ($rverb =~ /checkout/) && $clean) {\r
- print "Warning -- Because sources afe being checked out, make clean will not be run.\n";\r
- $clean = $odr->{clean}->{def} = 0;\r
- }\r
+ local $cvscmdroot = "cvs $rverb";\r
+ if (length $odr->{cvstag}->{value} > 0) {\r
+ $cvscmdroot .= " -r $odr->{cvstag}->{value}";\r
+ }\r
\r
- if ($clean && $odr->{package}->{def}) {\r
- print "Info -- /clean forces /nopackage.\n";\r
- $odr->{package}->{def} = 0;\r
- }\r
+ if ($rverb =~ /checkout/) { \r
+ chdir($src) or die "Fatal -- couldn't chdir to $src\n";\r
+ print "Info -- chdir to ".`cd`."\n" if ($verbose);\r
+ my @cvsmodules = ( \r
+ 'krb', \r
+ 'pismere/athena/util/lib/delaydlls', \r
+ 'pismere/athena/util/lib/getopt', \r
+ 'pismere/athena/util/guiwrap'\r
+ );\r
+\r
+ foreach my $module (@cvsmodules) {\r
+ local $cvscmd = $cvscmdroot." ".$module;\r
+ if ($verbose) {print "Info -- cvs command: $cvscmd\n";}\r
+ !system($cvscmd) or die "Fatal -- command \"$cvscmd\" failed; return code $?\n";\r
+ }\r
+ }\r
+ else { ## Update.\r
+ chdir($wd) or die "Fatal -- couldn't chdir to $wd\n";\r
+ print "Info -- chdir to ".`cd`."\n" if ($verbose);\r
+ if ($verbose) {print "Info -- cvs command: $cvscmdroot\n";}\r
+ !system($cvscmdroot) or die "Fatal -- command \"$cvscmdroot\" failed; return code $?\n";\r
+ }\r
\r
- # Test the unix find command:\r
- if (! exists $odr->{unixfind}->{value}) {\r
- $odr->{unixfind}->{value} = "C:\\tools\\cygwin\\bin";\r
- }\r
- local $unixfind = $odr->{unixfind}->{value};\r
+ # Set up svn environment variable:\r
+ $ENV{SVN_SSH} = "plink.exe";\r
+ # If the directory structure doesn't exist, many cd commands will fail.\r
+ if (! -d $krb5dir) { ## xcopy will create the entire path for us.\r
+ !system("echo foo > a.tmp") or die "Fatal -- Couldn't create temporary file in ".`cd`;\r
+ !system("echo F | xcopy a.tmp $krb5dir\\a.tmp") or die "Fatal -- Couldn't xcopy to $krb5dir.";\r
+ !system("rm a.tmp") or die "Fatal -- Couldn't remove temporary file.";\r
+ !system("rm $krb5dir\\a.tmp") or die "Fatal -- Couldn't remove temporary file.";\r
+ }\r
\r
- local $savedPATH = $ENV{PATH};\r
- $ENV{PATH} = $unixfind.";".$savedPATH;\r
- print "Info -- chdir to ".`cd`."\n" if ($verbose);\r
- if (-e "a.tmp") {!system("rm a.tmp") or die "Fatal -- Couldn't clean temporary file a.tmp.";}\r
- !system("find . -name a.tmp > b.tmp 2>&1") or die "Fatal -- find test failed.";\r
- local $filesize = -s "b.tmp";\r
- $ENV{PATH} = $savedPATH;\r
- if ($filesize > 0) {\r
- die "Fatal -- $unixfind does not appear to be a path to a UNIX find command.";\r
+ chdir($krb5dir) or die "Fatal -- Couldn't chdir to $krb5dir";\r
+ print "Info -- chdir to ".`cd`."\n" if ($verbose);\r
+ my $svncmd = "svn $rverb ";\r
+ if ($rverb =~ /checkout/) { # Append the rest of the checkout command:\r
+ chdir("..");\r
+ $svncmd .= "svn+ssh://".$odr->{username}->{value}."@".$odr->{SVNURL}->{value}."/krb5/";\r
+ if (length $odr->{svntag}->{value} > 0) {\r
+ $svncmd .= "tags/$odr->{svntag}->{value}";\r
+ }\r
+ elsif (length $odr->{svnbranch}->{value} > 0) {\r
+ $svncmd .= "branches/$odr->{svnbranch}->{value}";\r
+ }\r
+ else {\r
+ $svncmd .= "trunk";\r
+ }\r
+\r
+ $svncmd .= " krb5";\r
+\r
+ }\r
+ if ($verbose) {print "Info -- svn command: $svncmd\n";}\r
+ !system($svncmd) or die "Fatal -- command \"$svncmd\" failed; return code $?\n";\r
+ if ($verbose) {print "Info -- *** End fetching sources.\n";}\r
}\r
+##-- End repository action.\r
\r
##++ Read in the version information to be able to update the \r
# site-local files in the install build areas.\r