sbsv1_os/e32toolp/test/cw_ide_test.pl
changeset 0 83f4b4db085c
child 1 d4b442d23379
equal deleted inserted replaced
-1:000000000000 0:83f4b4db085c
       
     1 #!perl
       
     2 # Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description:
       
    15 # Script to build specified MMP files with both command line and IDE, then
       
    16 # use EVALID to compare the results.
       
    17 # Inspired by "buildall.pl", written by Cuong Phan
       
    18 # 
       
    19 #
       
    20 
       
    21 use strict;
       
    22 use File::Basename;		# for fileparse()
       
    23 use File::Path;			# for mkpath
       
    24 use Cwd;				# for cwd
       
    25 use OLE;
       
    26 use Getopt::Long;
       
    27 
       
    28 sub Usage ($) 
       
    29 	{
       
    30 	my ($message) = @_;
       
    31 	print <<ENDHERESTRING;
       
    32 $message
       
    33 
       
    34 Usage : perl cw_ide_test.pl [-v] -f mmplist platform1 [platform2 ...]
       
    35 
       
    36 Builds specified MMP files with both the command line and the CodeWarrior IDE,
       
    37 storing the build products in zip files and comparing them with EVALID.
       
    38 The output can be summarised using scanlog.pl.
       
    39 
       
    40 All of the specified MMP files are build for all of the specified platforms.
       
    41 If -v is specified, the detailed build commands are included in the output.
       
    42 
       
    43 ENDHERESTRING
       
    44 
       
    45 	exit 1;
       
    46 	}
       
    47 
       
    48 my %Options=();
       
    49 GetOptions(\%Options, "v", "f=s");
       
    50 
       
    51 &Usage("No platforms specified") if (@ARGV < 1);
       
    52 &Usage("Must specify list of mmp files using -f") if (!defined($Options{"f"}));
       
    53 
       
    54 my @mmplist=();
       
    55 my $specifiedCWD;
       
    56 open FILELIST, "<$Options{f}" or &Usage("Cannot open $Options{f}");
       
    57 while (<FILELIST>)
       
    58 	{
       
    59 	$specifiedCWD = "";
       
    60 		
       
    61 	if (/#.*cwd:/i)
       
    62 		{
       
    63 		$specifiedCWD = $_;
       
    64 		$specifiedCWD =~ s/^.*cwd:/cwd:/i;
       
    65 		$specifiedCWD =~ s/\).*$//;
       
    66 		$specifiedCWD =~ s/\s*//g;
       
    67 		$specifiedCWD =~ s/\//\\/g;
       
    68 		$specifiedCWD .="?";
       
    69 		}
       
    70 		
       
    71 	s/#.*$//;		# remove comments
       
    72 	s/\s*$//;		# remove trailing ws
       
    73 	s/^\s*//;		# remove leading ws
       
    74 	s/\//\\/g;		# convert / to \
       
    75 	next if ($_ eq "");
       
    76 	push @mmplist, $specifiedCWD.$_;
       
    77 	}
       
    78 close FILELIST;
       
    79 
       
    80 &Usage("No MMP files?") if (@mmplist == 0);
       
    81 
       
    82 # create an instance of CodeWarrior
       
    83 my $CW = CreateObject OLE  "CodeWarrior.CodeWarriorApp";
       
    84 if (!defined($CW))
       
    85 	{
       
    86 	print "Failed to start CodeWarrior\n";
       
    87 	exit(1);
       
    88 	}
       
    89 
       
    90 # turn on autoflush, to get stdout in the right place...
       
    91 # These runes come from perlfaq5
       
    92 
       
    93 my $old_fh = select(STDOUT);
       
    94 $| = 1;
       
    95 select($old_fh);
       
    96 
       
    97 foreach my $mmpfile (@mmplist)
       
    98 	{
       
    99 	$specifiedCWD = "";
       
   100 
       
   101 	if ($mmpfile =~ /^cwd:/)
       
   102 		{
       
   103 		$specifiedCWD = $mmpfile;
       
   104 		$specifiedCWD =~ s/^cwd://;
       
   105 		$specifiedCWD =~ s/\?.*$//;
       
   106 		$mmpfile =~ s/^cwd:.*\?//;
       
   107 		}
       
   108 
       
   109 	if (!-f $mmpfile)
       
   110 		{
       
   111 		print "MISSING: $mmpfile\n";
       
   112 		next;
       
   113 		}
       
   114 	
       
   115 	foreach my $platform (@ARGV)
       
   116 		{
       
   117 		$platform = uc $platform;
       
   118 		my ($mmpname, $mmpdir, $mmpext) = fileparse($mmpfile,'\..*');
       
   119 		my $phasename = $mmpname."_".$platform;
       
   120 		
       
   121 		my $origdir = cwd;
       
   122 
       
   123 		if ($specifiedCWD)
       
   124 			{
       
   125 			print ("chdir $specifiedCWD\n");			
       
   126 			chdir ($specifiedCWD);
       
   127 
       
   128 			# Workaround for Base components, where GENEXEC.MKE needs to be executed to export the required headers for a build
       
   129 			do_system ("bldmake bldfiles");
       
   130 			do_system ("abld makefile $platform");
       
   131 			}
       
   132 		else
       
   133 			{
       
   134 			print ("chdir $mmpdir\n");
       
   135 			chdir ($mmpdir);
       
   136 			}
       
   137 
       
   138 		my $time = localtime;
       
   139 		print "===-------------------------------------------------\n";
       
   140 		print "=== $phasename\n";
       
   141 		print "===-------------------------------------------------\n";
       
   142 		print "=== $phasename started $time\n";
       
   143 
       
   144 		if ($specifiedCWD)
       
   145 			{
       
   146 			$mmpdir = "\\".$mmpdir;
       
   147 			}
       
   148 		else
       
   149 			{
       
   150 			$mmpdir = "";
       
   151 			}
       
   152 
       
   153 		&do_one_mmp_file($phasename, $mmpname, $platform, $mmpdir);
       
   154 
       
   155 		$time = localtime;
       
   156 		print "=== $phasename finished $time\n";
       
   157 
       
   158 		chdir($origdir);
       
   159 		print ("chdir $origdir\n");
       
   160 		}
       
   161 	}
       
   162 
       
   163 $CW->Quit(0);
       
   164 exit(0);
       
   165 
       
   166 sub do_system($)
       
   167 	{
       
   168 	my ($cmd) = @_;
       
   169 	print "    $cmd\n";
       
   170 	return system($cmd);
       
   171 	}
       
   172 
       
   173 sub zip_and_check($$$)
       
   174 	{
       
   175 	my ($zipname, $releaseref, $complain) = @_;
       
   176 	
       
   177 	unlink($zipname) if (-f $zipname);
       
   178 	
       
   179 	my @ziplist;
       
   180 	foreach (sort keys %$releaseref)
       
   181 		{
       
   182 		if (-f $_)
       
   183 			{
       
   184 			push @ziplist,$_;	# add to zip archive
       
   185 			}
       
   186 		else
       
   187 			{
       
   188 			print "MISSING: $_\n" if ($complain);
       
   189 			}
       
   190 		}
       
   191 	
       
   192 	if (scalar @ziplist ==0 && $complain)
       
   193 		{
       
   194 		print "Can't create empty archive $zipname\n";
       
   195 		return;
       
   196 		}
       
   197 	
       
   198 	# Make the non-empty archive
       
   199 	
       
   200 	open ZIP, "| zip -q $zipname -@";
       
   201 	print ZIP
       
   202 	 join("\n",@ziplist,"");
       
   203 	close ZIP;
       
   204 	print "Created $zipname\n";
       
   205 	}
       
   206 	
       
   207 sub do_one_mmp_file($$$)
       
   208 	{
       
   209 	my ($phasename, $mmpname, $platform, $mmpdir) = @_;
       
   210 
       
   211 	print "=== $phasename == $mmpname.mmp\n";
       
   212 
       
   213 	# use MAKMAKE to generate the makefile
       
   214 	# make CLEAN to remove any existing build results
       
   215 	# make ALL to build everything
       
   216 	# make WHAT to get the releaseables, as per abld.pl
       
   217 	# check the releaseables and zip up the ones which do exist
       
   218 	# make CLEAN again to get ready for the IDE build...
       
   219 		
       
   220 	my $makefile = "$mmpname.$platform";
       
   221 	my %allreleaseables=();		# complete list, for putting back afterwards
       
   222 	my %releaseables=();		# just things we expect the IDE to build
       
   223 	my %uncheckedreleaseables=();
       
   224 	my $makecmd = "make -s";
       
   225 	$makecmd = "make" if ($Options{"v"});
       
   226 	
       
   227 	unlink $makefile if (-f $makefile);
       
   228 	&do_system("perl -S makmake.pl $mmpdir$mmpname $platform");
       
   229 	return if (!-f $makefile);
       
   230 	
       
   231 	open PIPE,"make -s -r -f $makefile WHAT |";
       
   232 	while (<PIPE>) 
       
   233 		{
       
   234 		next if (/Nothing to be done for \S+\.$/o);
       
   235 #		releasables split on whitespace - quotes possible -stripped out
       
   236 		while (/("([^"\t\n\r\f]+)"|([^ "\t\n\r\f]+))/go) 
       
   237 			{
       
   238 			my $file = ($2 ? $2 : $3);
       
   239 			$allreleaseables{$file}=1;
       
   240 			next if ($file =~ /epoc32\\localisation\\/i);
       
   241 			next if ($file =~ /epoc32\\data/i && $platform =~ /winscw/i);
       
   242 			$releaseables{$file}=1;
       
   243 			}
       
   244 		}
       
   245 	close PIPE;
       
   246 	&zip_and_check("$mmpname.orig.$platform.zip", \%allreleaseables, 0);
       
   247 	
       
   248 	&do_system("$makecmd -r -f $makefile CLEAN");
       
   249 	&do_system("$makecmd -r -f $makefile ALL");
       
   250 	&zip_and_check("$mmpname.cmd.$platform.zip", \%releaseables, 1);
       
   251 
       
   252 	&do_system("$makecmd -r -f $makefile CLEAN");
       
   253 	
       
   254 	print "=== $phasename == $mmpname.mcp\n";
       
   255 
       
   256 	# Remove the remnants of previous projects
       
   257 	# use MAKMAKE to generate the importable .xml
       
   258 	# import the xml to create the .mcp
       
   259 	# build the relevant targets
       
   260 	# extract the contents of the "Errors & Warnings" window
       
   261 	# check against the commandline list of releasables, zip up the ones which exist
       
   262 	
       
   263 	my $currentdir = cwd;
       
   264 	$currentdir =~ s/\//\\/g;
       
   265 	my $xmlfile = "$currentdir\\$mmpname.xml";
       
   266 	my $mcpfile = "$currentdir\\$mmpname.mcp";
       
   267 	my $mcpdata = "$currentdir\\${mmpname}_Data";
       
   268 	
       
   269 	&do_system("rmdir /s/q $mcpdata") if (-d $mcpdata);
       
   270 	unlink $mcpfile if (-f $mcpfile);
       
   271 	unlink $xmlfile if (-f $xmlfile);
       
   272 
       
   273 	&do_system("perl -S makmake.pl $mmpdir$mmpname CW_IDE:$platform");
       
   274 	if (-f $xmlfile)
       
   275 		{
       
   276 		&fixup_XML($xmlfile) if ($Options{"v"});
       
   277 		my $project = $CW->ImportProject($xmlfile, $mcpfile, 'true');
       
   278 		if (defined($project))
       
   279 			{
       
   280 			my $success = &BuildTargets($project->Targets,$platform);
       
   281 			$project->Close();
       
   282 			return if (!$success);
       
   283 			&zip_and_check("$mmpname.ide.$platform.zip", \%releaseables, 1);
       
   284 			}
       
   285 		else
       
   286 			{
       
   287 			print "ERROR: failed to import $xmlfile\n";
       
   288 			return;
       
   289 			}
       
   290 		}
       
   291 	else
       
   292 		{
       
   293 		print "ERROR: failed to create $xmlfile\n";
       
   294 		return;
       
   295 		}
       
   296 
       
   297 	print "=== $phasename == $mmpname.evalid\n";
       
   298 
       
   299 	# remove & recreate a clean temporary directory for unzipping
       
   300 	# unzip the saved results of the cmd and ide builds
       
   301 	# use EVALID to compare the releaseables
       
   302 		
       
   303 	my $evaliddir = "c:\\temp\\evalid";
       
   304 	&do_system("rmdir /s/q $evaliddir") if (-d $evaliddir);
       
   305 	mkpath([$evaliddir]);
       
   306 	
       
   307 	if (   &do_system("unzip -q $mmpname.cmd.$platform.zip -d $evaliddir\\cmd")==0
       
   308 		&& &do_system("unzip -q $mmpname.ide.$platform.zip -d $evaliddir\\ide")==0)
       
   309 		{
       
   310 		open EVALID,"perl -S evalid.pl $evaliddir\\ide $evaliddir\\cmd -c |";
       
   311 		while (<EVALID>)
       
   312 			{
       
   313 			print $_ if (/^(PROBLEM|Failed)/);
       
   314 			print $_ if (/^OK/ && $Options{"v"});
       
   315 			if (/^FAILED/)
       
   316 				{
       
   317 				if (/\.map\t/i)
       
   318 					{
       
   319 					print "WARNING(S): $_";
       
   320 					}
       
   321 				else
       
   322 					{
       
   323 					print "FATAL ERROR(S): $_";
       
   324 					}
       
   325 				}
       
   326 			}
       
   327 		close EVALID;
       
   328 		}
       
   329 	else
       
   330 		{
       
   331 		print "FATAL ERROR(S): problems unpacking zip files\n";
       
   332 		}
       
   333 	&do_system("rmdir /s/q $evaliddir") if (-d $evaliddir);
       
   334 	
       
   335 	# Restore original files, if any
       
   336 	if (-e "$mmpname.orig.$platform.zip")
       
   337 		{
       
   338 		&do_system("unzip -q -o $mmpname.orig.$platform.zip -d \\");
       
   339 		}
       
   340 	}
       
   341 
       
   342 sub fixup_XML($)
       
   343 	{
       
   344 	my ($xmlfile) = @_;
       
   345 	open XML,"<$xmlfile" or return;
       
   346 	my @lines = <XML>;
       
   347 	close XML;
       
   348 	
       
   349 	foreach (@lines)
       
   350 		{
       
   351 		# Insist that build commands are logged to the output window, irrespective of CW version
       
   352 		s-<SETTING><NAME>LogMessages</NAME><VALUE>false</VALUE></SETTING>-<SETTING><NAME>LogMessages</NAME><VALUE>true</VALUE></SETTING>-;
       
   353 		s-<SETTING><NAME>ShowCommandLine</NAME><VALUE>false</VALUE></SETTING>-<SETTING><NAME>ShowCommandLine</NAME><VALUE>true</VALUE></SETTING>-;
       
   354 
       
   355 		# Remove generation of Browse info by Language Parser (temporary workaround for crashes in automated IDE builds)
       
   356 		s-<SETTING><NAME>BrowserGenerator</NAME><VALUE>2</VALUE></SETTING>-<SETTING><NAME>BrowserGenerator</NAME><VALUE>0</VALUE></SETTING>-;		
       
   357 		}
       
   358 		
       
   359 	open XML,">$xmlfile" or return;
       
   360 	print XML @lines;
       
   361 	close XML;
       
   362 	}
       
   363 	
       
   364 sub BuildTargets($$)
       
   365 	{
       
   366 	my ($targets,$platform) = @_;
       
   367 
       
   368 	for (my $item=0; $item<$targets->Count; $item++ ) 
       
   369 		{
       
   370 		my $target = $targets->Item($item);
       
   371 	    my $targetName = $target->name;
       
   372 	    # Skip platforms we aren't interested in...
       
   373 	    next if ($targetName !~ /$platform /i);
       
   374 
       
   375 		print "Building $targetName...\n";
       
   376 		     
       
   377 	    $target->RemoveObjectCode( 'true' );
       
   378 
       
   379 		my $buildMessages = $target->BuildAndWaitToComplete();
       
   380 		if (!defined($buildMessages))
       
   381 			{
       
   382 			printf "FATAL ERROR(S): build aborted? (%s)\n", $target->LastError();
       
   383 			return 0;
       
   384 			}
       
   385 			
       
   386 		my $messageList = $buildMessages->Informations;
       
   387 		&printMessages("",$messageList) if defined($messageList);
       
   388 		
       
   389 		my $warningCount = $buildMessages->WarningCount;
       
   390 		my $errorCount = $buildMessages->ErrorCount;    
       
   391 		print "Completed $targetName with $errorCount errors and $warningCount warnings\n";
       
   392 
       
   393 		if ($errorCount > 0)
       
   394 			{
       
   395 			$messageList = $buildMessages->Errors;
       
   396 			&printMessages("FATAL ERROR(S): ", $messageList);
       
   397 			}
       
   398 		if ($warningCount > 0)
       
   399 			{
       
   400 			$messageList = $buildMessages->Warnings;
       
   401 			&printMessages("WARNING: ", $messageList);
       
   402 			}
       
   403 		} 
       
   404 	return 1;
       
   405 	}
       
   406 
       
   407 sub	printMessages ($$)
       
   408 	{
       
   409     my ($prefix,$messageList) = @_;
       
   410 
       
   411 	# traverse through the list of messages
       
   412 	for (my $item = 0; $item < ($messageList->Count); $item++)
       
   413 		{
       
   414         my $message = $messageList->Item($item);
       
   415 		print $prefix,$message->MessageText,"\n";
       
   416 		}
       
   417 	}
       
   418