sbsv1/abld/bldmake/bldmake.pl
changeset 599 fa7a3cc6effd
equal deleted inserted replaced
596:9f25be3da657 599:fa7a3cc6effd
       
     1 # Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 # All rights reserved.
       
     3 # This component and the accompanying materials are made available
       
     4 # under the terms of "Eclipse Public License v1.0"
       
     5 # which accompanies this distribution, and is available
       
     6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 #
       
     8 # Initial Contributors:
       
     9 # Nokia Corporation - initial contribution.
       
    10 #
       
    11 # Contributors:
       
    12 #
       
    13 # Description:
       
    14 # all variables called *Path* are set up to end with a backslash
       
    15 # all variables called *Path or *File are stored as absolute (file)paths within makmake
       
    16 # all variables called UpPath* are stored as relative paths within makmake
       
    17 # 
       
    18 #
       
    19 
       
    20 
       
    21 use FindBin;		# for FindBin::Bin
       
    22 use Getopt::Long;
       
    23 
       
    24 my $PerlLibPath;    # fully qualified pathname of the directory containing our Perl modules
       
    25 
       
    26 BEGIN {
       
    27 # check user has a version of perl that will cope
       
    28 	require 5.005_03;
       
    29 # establish the path to the Perl libraries: currently the same directory as this script
       
    30 	$PerlLibPath = $FindBin::Bin;	# X:/epoc32/tools
       
    31 	$PerlLibPath =~ s/\//\\/g;	# X:\epoc32\tools
       
    32 	$PerlLibPath .= "\\";
       
    33 }
       
    34 sub ExportDirs ($);
       
    35 
       
    36 use lib $PerlLibPath;
       
    37 use E32env;
       
    38 use E32Plat;
       
    39 use Modload;
       
    40 use Output;
       
    41 use Pathutl;
       
    42 use E32Variant;
       
    43 use RVCT_plat2set;
       
    44 use BPABIutl;
       
    45 use wrappermakefile;
       
    46 use CheckSource;
       
    47 use File::Path; # for rmtree
       
    48 use featurevariantparser;
       
    49 
       
    50 my $BldInfName = 'BLD.INF';
       
    51 my %Options;
       
    52 my %KeepGoing;
       
    53 my @DefaultPlats=('WINSCW', 'GCCXML', 'EDG', 'X86GCC');
       
    54 my @BaseUserDefaultPlats=('ARM4', 'ARM4T', 'WINSCW', 'GCCXML', 'EDG', 'X86GCC');
       
    55 my @OptionalPlats=('VS6', 'VS2003');
       
    56 my @PlatsReq;
       
    57 
       
    58 my %CheckSourceEXPORTSMetaData;
       
    59 my %CheckSourceEXPORTSIncludes;
       
    60 my %CheckSourceMMPFILESMetaData;
       
    61 my %CheckSourceEXTENSIONSMetaData;
       
    62 my %CheckSourceBldInfIncludes;
       
    63 
       
    64 for ('ARMV4', 'ARMV5')
       
    65 {
       
    66 	push @BaseUserDefaultPlats, $_ if RVCT_plat2set::compiler_exists($_);
       
    67 }
       
    68 
       
    69 # Add ARMV5_ABIV1 platform if ENABLE_ABIV2_MODE is set in variant.cfg
       
    70 my $variantABIV2Keyword = &Variant_GetMacro();
       
    71 # Add ARMV5_ABIV1 platform only after determining the presence of RVCT compiler.
       
    72 if ($variantABIV2Keyword && RVCT_plat2set::compiler_exists('ARMV5_ABIV1') ) {
       
    73 	push @OptionalPlats, 'ARMV5_ABIV1';
       
    74 }
       
    75 
       
    76 # bldmake -k shouldn't die if Extension Makefile is missing
       
    77 our $IgnoreMissingExtensionMakefile = 0;
       
    78 
       
    79 # Add the BPABI Platforms to be added 
       
    80 my @BPABIPlats = &BPABIutl_Plat_List;
       
    81 foreach my $BPABIPlat (@BPABIPlats) 
       
    82 {
       
    83 	# BPABI platform related with ARMV5(eg.ARMV5_ABIV2) is added to the platform list after 
       
    84 	# determining the presence of RVCT compiler	
       
    85 	if(($BPABIPlat =~/^ARMV5/i))
       
    86 		{
       
    87 			if(!($BPABIPlat =~/^ARMV5$/i) && RVCT_plat2set::compiler_exists('ARMV5'))
       
    88 			{
       
    89 			push @OptionalPlats, $BPABIPlat;
       
    90 			}
       
    91 		}
       
    92 	# All other BPABI platforms(eg. gcce) are added to the platform list.
       
    93 	else
       
    94 		{
       
    95 			push @OptionalPlats, $BPABIPlat;
       
    96 		}
       
    97 }
       
    98 
       
    99 if ( RVCT_plat2set::compiler_exists('ARMV5') ) {
       
   100 	#determine the presence of ARVCT compiler
       
   101 	push @DefaultPlats, 'ARMV5';
       
   102 }
       
   103 	
       
   104 # Need to add WINS and X86 if MSDEV compiler is present
       
   105 # Use MSDevDir to determine the presence of the compiler
       
   106 push @BaseUserDefaultPlats, 'WINS', 'X86' if (exists($ENV{'MSDevDir'}));
       
   107 
       
   108 my @BaseDefaultPlats = @BaseUserDefaultPlats;
       
   109 push @BaseDefaultPlats, 'X86SMP' if (grep /^X86$/, @BaseUserDefaultPlats);
       
   110 push @BaseDefaultPlats, 'ARM4SMP' if (grep /^ARM4$/, @BaseUserDefaultPlats);
       
   111 push @BaseDefaultPlats, 'ARMV4SMP' if (grep /^ARMV4$/, @BaseUserDefaultPlats);
       
   112 push @BaseDefaultPlats, 'ARMV5SMP' if (grep /^ARMV5$/, @BaseUserDefaultPlats);
       
   113 push @BaseDefaultPlats, 'X86GMP' if (grep /^X86GCC$/, @BaseUserDefaultPlats);
       
   114 
       
   115 my $variantMacroHRHFile = Variant_GetMacroHRHFile();
       
   116 sub ExportDirs ($);
       
   117 
       
   118 # THE MAIN PROGRAM SECTION
       
   119 ##########################
       
   120 
       
   121 # Load default feature variant info - for the hrh file
       
   122 my %DefaultFeatureVariant = featurevariantparser->GetVariant('DEFAULT') if (featurevariantparser->DefaultExists());
       
   123 my @FeatureVariants = featurevariantparser->GetBuildableFeatureVariants();
       
   124 	
       
   125 {
       
   126 	Load_SetModulePath($PerlLibPath);
       
   127 	Plat_Init($PerlLibPath);
       
   128 
       
   129 	{
       
   130 		my @PlatList = &Plat_List();
       
   131 		
       
   132 		if (RVCT_plat2set::compiler_exists('ARMV6')){
       
   133 			foreach my $ARMV6Target ("ARMV6", "ARMV6_ABIV1", "ARMV6_ABIV2"){
       
   134 				if (grep /^$ARMV6Target$/, @PlatList) {
       
   135 					push @BaseUserDefaultPlats, "$ARMV6Target" if (!grep /^$ARMV6Target$/, @BaseUserDefaultPlats);
       
   136 					push @BaseDefaultPlats, "$ARMV6Target" if (!grep /^$ARMV6Target$/, @BaseDefaultPlats);
       
   137 				}
       
   138 			}
       
   139 		}
       
   140 	
       
   141 		if (RVCT_plat2set::compiler_exists('ARMV7')){
       
   142  			my $rvct_ver = RVCT_plat2set::get_version_string('ARMV7');
       
   143  			if ((defined $rvct_ver) and ($rvct_ver ge "3.1.674")) {
       
   144  				if (grep /^ARMV7$/, @PlatList ) {
       
   145 					push @DefaultPlats, 'ARMV7' if (!grep /^ARMV7$/, @DefaultPlats);
       
   146 					push @BaseUserDefaultPlats, "ARMV7" if (!grep /^ARMV7$/, @BaseUserDefaultPlats);
       
   147 					push @BaseDefaultPlats, "ARMV7" if (!grep /^ARMV7$/, @BaseDefaultPlats);
       
   148  				}
       
   149  			}
       
   150  		}
       
   151 	}
       
   152 	
       
   153 #	process the commmand-line
       
   154 	unless (GetOptions(\%Options, 'v', "k|keepgoing", "notest", "file|f=s")) {
       
   155 		exit 1;
       
   156 	}
       
   157 	unless (@ARGV>=1) {
       
   158 		&Usage();
       
   159 	}
       
   160 	my $Command=uc shift @ARGV;
       
   161 	unless ($Command=~/^(BLDFILES|CLEAN|INF|PLAT)$/o) {
       
   162 		&Usage();
       
   163 	}
       
   164 	my $CLPlat=uc shift @ARGV;
       
   165 
       
   166 	unless ($CLPlat) {
       
   167 		$CLPlat='ALL';
       
   168 	}
       
   169 
       
   170 	if ($Command eq 'INF') {
       
   171 		&ShowBldInfSyntax();
       
   172 		exit;
       
   173 	}
       
   174 
       
   175 	if ($Command eq 'PLAT') {
       
   176 		my @PlatList = ($CLPlat);
       
   177 		my $PlatName;
       
   178 		# Variable introduced to check if the bldmake plat command is called, To be
       
   179 		# passed as an argument in Plat_GetL function call.
       
   180 		my $platcommand=1;
       
   181 		if ($CLPlat eq "ALL") {
       
   182 			@PlatList = &Plat_List();
       
   183 			print(
       
   184 				"Supported Platforms:\n",
       
   185 				"  @PlatList\n\n"
       
   186 			);
       
   187 		}
       
   188 		print(
       
   189 			"Macros defined for BLD.INF preprocessing of MMPFILE sections:\n"
       
   190 		);
       
   191 		foreach $PlatName (@PlatList) {
       
   192 			my %Plat;
       
   193 			eval { &Plat_GetL($PlatName, \%Plat,{},$platcommand); };
       
   194 			die $@ if $@;
       
   195 			print(
       
   196 				"\nPlatform $PlatName:\n",
       
   197 				"  @{$Plat{MmpMacros}}\n"
       
   198 			);
       
   199 		}
       
   200 		exit;
       
   201 	}
       
   202 	if ($Options{file}) {
       
   203 		$BldInfName = $Options{file};
       
   204 	}
       
   205 
       
   206 #	check that the BLD.INF file exists
       
   207 #	maybe BLDMAKE should allow a path to be specified leading to the BLD.INF file
       
   208 	my $BldInfPath=&Path_WorkPath;
       
   209 	unless (-e "${BldInfPath}$BldInfName") {
       
   210 		&FatalError("Can't find \"${BldInfPath}$BldInfName\"");
       
   211 	}
       
   212 
       
   213 	if (!-d $E32env::Data{EPOCPath}){
       
   214 		&FatalError("Directory \"$E32env::Data{EPOCPath}\" does not exist");
       
   215 	}
       
   216 
       
   217 #	decide the output directory
       
   218 	my $OutDir=&Path_Chop($E32env::Data{BldPath}).$BldInfPath;
       
   219 
       
   220 #	Work out the path for the IBY files
       
   221 	my $RomDir=&Path_Chop($E32env::Data{RomPath}).$BldInfPath;
       
   222 
       
   223 #	Work out the name for the BLD.INF module
       
   224 	my @Dirs=&Path_Dirs($BldInfPath);
       
   225 	my $Module = pop @Dirs;
       
   226 	if (lc($Module) eq 'group') {
       
   227 		$Module = pop @Dirs;
       
   228 	}
       
   229 
       
   230 	if ($Command eq 'CLEAN') {
       
   231 		unlink "${BldInfPath}ABLD.BAT";
       
   232 		$OutDir=~m-(.*)\\-o;
       
   233 		if (-d $1) { # remove backslash for test because some old versions of perl can't cope
       
   234 			opendir DIR, $1;
       
   235 			my @Files=grep s/^([^\.].*)$/$OutDir$1/, readdir DIR;
       
   236 			closedir DIR;
       
   237 			unlink @Files;
       
   238 		}
       
   239 		rmtree <$OutDir\\wrappermakefiles>;
       
   240 # modified start: makefile improvement 
       
   241 		rmtree <$OutDir\\FeatureVariantInfo>;
       
   242 # modified end: makefile improvement 
       
   243 		exit;
       
   244 	}
       
   245 
       
   246 #	parse BLD.INF - to get the platforms and the export files
       
   247 	eval { &Load_ModuleL('PREPFILE'); };
       
   248 	&FatalError($@) if $@;
       
   249 
       
   250 	my @RealPlats=();
       
   251 	my @Exports=();
       
   252 	my @TestExports=();
       
   253 	if ($Options{v}) {
       
   254 		print "Reading \"${BldInfPath}$BldInfName\" for platforms and exports\n";
       
   255 	}
       
   256 	&ParseBldInf(\@RealPlats, \@Exports, \@TestExports, $BldInfPath, 
       
   257 		$E32env::Data{EPOCIncPath}, $E32env::Data{EPOCPath}, $E32env::Data{EPOCDataPath});
       
   258 
       
   259 #       Add Customizations
       
   260 	my @additions;
       
   261 	foreach my $plat (@RealPlats) {
       
   262 	        my @customizations = Plat_Customizations($plat);
       
   263 	        foreach my $custom (@customizations) {
       
   264 	                push @additions, $custom 
       
   265 			        unless grep /$custom/, @additions;
       
   266 		}
       
   267         }
       
   268 	unless ($CLPlat eq 'ALL') {
       
   269 		push @RealPlats, @additions;
       
   270 	}
       
   271 
       
   272  #	Force GCCXML support for anything that compiles as ARMV5
       
   273 	if ( (grep /^ARMV5$/, @RealPlats) and not (grep /^GCCXML$/,@RealPlats) ) 
       
   274 			{
       
   275 			push @RealPlats, 'GCCXML';
       
   276 			}
       
   277 
       
   278  #	Force EDG support for anything that compiles as ARMV5
       
   279 	if ( (grep /^ARMV5$/, @RealPlats) and not (grep /^EDG$/,@RealPlats) ) 
       
   280 			{
       
   281 			push @RealPlats, 'EDG';
       
   282 			}
       
   283 
       
   284 if (0) {
       
   285 #	Add ARMV5 to the platforms if ARM4 is defined
       
   286 	if (grep /^ARM4$/, @RealPlats) {
       
   287 		unless ( (grep /^ARMV4$/, @RealPlats) or (grep /^ARMV5$/, @RealPlats) ){
       
   288 		push @RealPlats, 'ARMV5';
       
   289 		push @RealPlats, 'ARMV4';
       
   290 		}
       
   291 	}
       
   292 }
       
   293 	
       
   294 #	get any IDE platforms required into a new platforms list, and
       
   295 #	Create a hash to contain the 'real' names of the platforms, i.e. WINS rather than VC6
       
   296 	my @Plats=@RealPlats;
       
   297 	my %Real;
       
   298 	foreach (@RealPlats) { # change to get VC6 batch files
       
   299 		$Real{$_}=$_;
       
   300 		my $AssocIDE;
       
   301 		my @AssocIDEs;
       
   302 
       
   303 #		Get the IDEs associated with a real platform. A real plat like,
       
   304 #		WINSCW may have multiple associated IDEs like VC6 .NET2003 or CW IDE.
       
   305 		&Plat_AssocIDE($_, \@AssocIDEs);
       
   306 		next unless @AssocIDEs;
       
   307 		
       
   308 		push @Plats, @AssocIDEs;
       
   309 		foreach $AssocIDE (@AssocIDEs)
       
   310 		{
       
   311 			$Real{$AssocIDE}=$Real{$_};
       
   312 		}
       
   313 		
       
   314 	}
       
   315 	if ($Options{v}) {
       
   316 		print "Platforms: \"@Plats\"\n";
       
   317 	}
       
   318 
       
   319 #	check that the platform specified on the command-line is acceptable
       
   320 #	and sort out a list of platforms to process
       
   321 	my @DoRealPlats=@RealPlats;
       
   322 	my @DoPlats=@Plats;
       
   323 
       
   324 	unless (@Plats) { 
       
   325 #	include the optional platform list if no platform is specified
       
   326 		my $OptionalPlat;
       
   327 		foreach $OptionalPlat (@OptionalPlats) {
       
   328 			unless (grep /^$OptionalPlat$/i, @DoPlats) {
       
   329 				push @DoPlats, $OptionalPlat;
       
   330 			}
       
   331 		}
       
   332 	}
       
   333 
       
   334 	unless ($CLPlat eq 'ALL') {
       
   335 		unless (grep /^$CLPlat$/, @Plats) {
       
   336 			&FatalError("Platform $CLPlat not supported by \"${BldInfPath}$BldInfName\"\n");
       
   337 		}
       
   338 		@DoPlats=($CLPlat);
       
   339 		@DoRealPlats=$Real{$CLPlat};
       
   340 	}
       
   341 			
       
   342 #	sort out the export directories we might need to make
       
   343 	my @ExportDirs=ExportDirs(\@Exports);
       
   344 	my @TestExportDirs=ExportDirs(\@TestExports);
       
   345 
       
   346 #	parse the BLD.INF file again for each platform supported by the project
       
   347 #	storing the information in a big data structure
       
   348 	my %AllPlatData;
       
   349 	my %AllPlatTestData;
       
   350 	my $Plat;
       
   351 	
       
   352 	if ($Options{v} and $CLPlat ne 'ALL'){
       
   353 		print "Reading \"${BldInfPath}$BldInfName\" for $CLPlat \n";
       
   354 	}
       
   355 
       
   356 	foreach $Plat (@RealPlats) {
       
   357 		if ($Options{v}) {
       
   358 			if ($CLPlat eq 'ALL') {
       
   359 				print "Reading \"${BldInfPath}$BldInfName\" for $Plat\n";
       
   360 			}
       
   361 		}
       
   362 		my (@PlatData, @PlatTestData);
       
   363 		if ($CLPlat eq 'ALL') {
       
   364 			&ParseBldInfPlat(\@PlatData, \@PlatTestData, $Plat, $BldInfPath, ($DefaultFeatureVariant{VALID} && &Plat_SupportsFeatureVariants($Plat) ? \%DefaultFeatureVariant : undef));
       
   365 		}
       
   366 		else {
       
   367 			&ParseBldInfPlat(\@PlatData, \@PlatTestData, $CLPlat, $BldInfPath, ($DefaultFeatureVariant{VALID} && &Plat_SupportsFeatureVariants($CLPlat) ? \%DefaultFeatureVariant : undef));
       
   368 		}
       
   369 		$AllPlatData{$Plat}=\@PlatData;
       
   370 		$AllPlatTestData{$Plat}=\@PlatTestData;
       
   371 	}
       
   372 	undef $Plat;
       
   373 
       
   374 	undef $CLPlat;
       
   375 	if ($Command eq 'BLDFILES') {
       
   376 
       
   377 #		create the perl file, PLATFORM.PM, listing the platforms
       
   378 		if ($Options{v}) {
       
   379 			print "Creating \"${OutDir}PLATFORM.PM\"\n";
       
   380 		}
       
   381 		&CreatePlatformPm($OutDir, \@Plats, \@RealPlats, \%Real, \%AllPlatData, \%AllPlatTestData);
       
   382 
       
   383 #		create the .BAT files required to call ABLD.PL
       
   384 		if ($Options{v}) {
       
   385 			print "Creating \"${BldInfPath}ABLD.BAT\"\n";
       
   386 		}
       
   387 		&CreatePerlBat($BldInfPath);
       
   388 
       
   389 #		create the makefile for exporting files
       
   390 		if ($Options{v}) {
       
   391 			print "Creating \"${OutDir}EXPORT.MAKE\"\n";
       
   392 		}
       
   393 		&CreateExportMak("${OutDir}EXPORT.MAKE", \@Exports, \@ExportDirs);
       
   394 
       
   395 #		create the makefile for exporting test files
       
   396 		if ($Options{v}) {
       
   397 			print "Creating \"${OutDir}EXPORTTEST.MAKE\"\n";
       
   398 		}
       
   399 		&CreateExportMak("${OutDir}EXPORTTEST.MAKE", \@TestExports, \@TestExportDirs);
       
   400 
       
   401 # modified start: makefile improvement 
       
   402 		#create the feature variant infor file
       
   403 		foreach my $copyofPlat (@DoPlats)
       
   404 		{
       
   405 			my $realplat = $Real{$copyofPlat};
       
   406 			if(&Plat_SupportsFeatureVariants($copyofPlat))
       
   407 			{
       
   408 				my $variant_info = &Path_Chop($E32env::Data{BldPath}).$BldInfPath."\\FeatureVariantInfo\\".$realplat."\\";	
       
   409 				eval { &Path_MakePathL($variant_info); };
       
   410 				die $@ if $@;
       
   411 				if ($Options{v}) {
       
   412 					print "Creating: \"$variant_info\"\n";
       
   413 				}
       
   414 				foreach my $featureVariant (@FeatureVariants)
       
   415 				{
       
   416 					my $variant_file = $variant_info."$realplat.$featureVariant.info";
       
   417 # modified by SV start: makefile improvement 
       
   418 					my $refdata = $AllPlatData{$realplat};
       
   419 					my $testrefdata = $AllPlatTestData{$realplat};
       
   420 					if ( @$refdata ) {
       
   421 						foreach my $RefPro (@$refdata)
       
   422 						{
       
   423 							$variant_file = $variant_info."$realplat.$featureVariant.$$RefPro{Base}.info";
       
   424 							my $ref_basedir = $variant_file;
       
   425 							$ref_basedir=~s/(.*[\\\/]).*/$1/;
       
   426 							if ( ! -d $ref_basedir ){
       
   427 								eval { &Path_MakePathL($ref_basedir); };
       
   428 								die $@ if $@;
       
   429 							}
       
   430 							open VARIANTINFOR,">$variant_file" or die "ERROR: Can't open or create file \"$variant_file\"\n";
       
   431 							print VARIANTINFOR "VARIANT_PLAT_NAME_$$RefPro{Base}:=default \n";
       
   432 							close VARIANTINFOR or die "ERROR: Can't close file \"$variant_file\"\n";
       
   433 						}
       
   434 					}
       
   435 					else {
       
   436 						open VARIANTINFOR,">$variant_file" or die "ERROR: Can't open or create file \"$variant_file\"\n";
       
   437 						print VARIANTINFOR "VARIANT_PLAT_NAME:=$featureVariant \n";
       
   438 						close VARIANTINFOR or die "ERROR: Can't close file \"$variant_file\"\n";
       
   439 						print "file \"$variant_file\"\n"
       
   440 					}
       
   441 					if ($testrefdata){
       
   442 						foreach my $RefPro (@$testrefdata)
       
   443 						{
       
   444 							$variant_file = $variant_info."$realplat.$featureVariant.$$RefPro{Base}.info";
       
   445 							my $ref_basedir = $variant_file;
       
   446 							$ref_basedir=~s/(.*[\\\/]).*/$1/;
       
   447 							if ( ! -d $ref_basedir ){
       
   448 								eval { &Path_MakePathL($ref_basedir); };
       
   449 								die $@ if $@;
       
   450 							}
       
   451 							open VARIANTINFOR,">$variant_file" or die "ERROR: Can't open or create file \"$variant_file\"\n";
       
   452 							print VARIANTINFOR "VARIANT_PLAT_NAME_$$RefPro{Base}:=default \n";
       
   453 							close VARIANTINFOR or die "ERROR: Can't close file \"$variant_file\"\n";
       
   454 						}
       
   455 						
       
   456 					}
       
   457 # modified by SV end: makefile improvement 
       
   458 					# Close and cleanup
       
   459 					if ($Options{v}) {
       
   460 						print "Variant info file has been successfully created\n";
       
   461 					}
       
   462 				}				
       
   463 			}
       
   464 		}
       
   465 # modified end: makefile improvement 
       
   466 #		create the platform meta-makefiles
       
   467 		foreach my $copyofPlat (@DoPlats) {  # Do not use $_ here !!
       
   468 			if ($Options{v}) {
       
   469 				print "Creating \"$OutDir$copyofPlat.MAKE\"\n";
       
   470 			}
       
   471 			my $realplat = $Real{$copyofPlat};
       
   472 			&CreatePlatMak($OutDir, $E32env::Data{BldPath}, $AllPlatData{$realplat}, $copyofPlat, $realplat, $RomDir, $Module, $BldInfPath, \@Exports, '');
       
   473 
       
   474 			if (&Plat_SupportsFeatureVariants($copyofPlat))
       
   475 				{
       
   476 				foreach my $featureVariant (@FeatureVariants)
       
   477 					{
       
   478 					print "Creating \"$OutDir$copyofPlat.$featureVariant.MAKE\"\n" if ($Options{v});
       
   479 					&CreatePlatMak($OutDir, $E32env::Data{BldPath}, $AllPlatData{$realplat}, $copyofPlat, $realplat, $RomDir, $Module, $BldInfPath, \@Exports, '', ".$featureVariant");
       
   480 					}
       
   481 				}
       
   482 		}
       
   483 		foreach (@DoPlats) {
       
   484 			if ($Options{v}) {
       
   485 				print "Creating \"$OutDir${_}TEST.MAKE\"\n";
       
   486 			}
       
   487 			&CreatePlatMak($OutDir, $E32env::Data{BldPath}, $AllPlatTestData{$Real{$_}}, $_, $Real{$_}, $RomDir, $Module, $BldInfPath, \@TestExports, 'TEST');
       
   488 
       
   489 			if (&Plat_SupportsFeatureVariants($_))
       
   490 				{
       
   491 				foreach my $featureVariant (@FeatureVariants)
       
   492 					{
       
   493 					print "Creating \"$OutDir${_}.".$featureVariant."TEST.MAKE\"\n" if ($Options{v});
       
   494 					&CreatePlatMak($OutDir, $E32env::Data{BldPath}, $AllPlatTestData{$Real{$_}}, $_, $Real{$_}, $RomDir, $Module, $BldInfPath, \@TestExports, 'TEST', ".$featureVariant");
       
   495 					}
       
   496 				}
       
   497 		}
       
   498 
       
   499 #		create the platform test batch files
       
   500 		foreach (@DoRealPlats) {
       
   501 			if ($Options{v}) {
       
   502 				print "Creating test batch files in \"$OutDir\" for $_\n";
       
   503 			}
       
   504 			&CreatePlatBatches($OutDir, $AllPlatTestData{$_}, $_);
       
   505 		}
       
   506 
       
   507 # modified by SV start: makefile improvement 
       
   508 # create all sub directories
       
   509 	foreach my $refplat (@DoRealPlats) {
       
   510 		my $tmp = $AllPlatData{$refplat};
       
   511 		foreach my $dref (@$tmp){
       
   512 			my $builddir = $OutDir . $$dref{Base} ."\\" . $refplat . "\\";
       
   513 				if (!-d $builddir){
       
   514 					if ($Options{v}) {
       
   515 						print "Creating directory \"$builddir\" \n";
       
   516 					}
       
   517 					eval { &Path_MakePathL($builddir); };
       
   518 					&FatalError($@) if $@;
       
   519 				}
       
   520 			}
       
   521 	}
       
   522 # modified by SV end: makefile improvement 
       
   523 
       
   524 #		report any near-fatal errors
       
   525 		if (scalar keys %KeepGoing) {
       
   526 		    print STDERR
       
   527 			    "\n${BldInfPath}$BldInfName WARNING(S):\n",
       
   528 			    sort keys %KeepGoing
       
   529 			    ;
       
   530 		}
       
   531 
       
   532 		exit;
       
   533 	}
       
   534 }
       
   535 
       
   536 
       
   537 ################ END OF MAIN PROGRAM SECTION #################
       
   538 #------------------------------------------------------------#
       
   539 ##############################################################
       
   540 
       
   541 
       
   542 # SUBROUTINE SECTION
       
   543 ####################
       
   544 
       
   545 sub Usage () {
       
   546 
       
   547 	eval { &Load_ModuleL('E32TPVER'); };
       
   548 	&FatalError($@) if $@;
       
   549 
       
   550 	print
       
   551 		"\n",
       
   552 		"BLDMAKE - Project building Utility (Build ",&E32tpver,")\n",
       
   553 		"\n",
       
   554 		"BLDMAKE {options} [<command>] [<platform>]\n",
       
   555 		"\n",
       
   556 		"<command>: (case insensitive)\n",
       
   557 		" BLDFILES - create build batch files\n",
       
   558 		" CLEAN    - remove all files bldmake creates\n",
       
   559 		" INF      - display basic BLD.INF syntax\n",
       
   560 		" PLAT     - display platform macros\n",
       
   561 		"\n",
       
   562 		"<platform>: (case insensitive)\n",
       
   563 		"  if not specified, defaults to \"ALL\"\n",
       
   564 		"\n",
       
   565 		"Options: (case insensitive)\n",
       
   566 		" -v   ->  verbose mode\n",
       
   567 		" -k   ->  keep going even if files are missing\n"
       
   568 	;
       
   569 	exit 1;
       
   570 }
       
   571 
       
   572 sub ShowBldInfSyntax () {
       
   573 
       
   574 	print <<ENDHERE1;
       
   575 
       
   576 BLD.INF - Syntax
       
   577 
       
   578 /* Use C++ comments if required */
       
   579 // (Curly braces denote optional arguments)
       
   580 
       
   581 PRJ_PLATFORMS
       
   582 {DEFAULT} {-<platform> ...} {<list of platforms>}
       
   583 // list platforms your project supports here if not default
       
   584 ENDHERE1
       
   585 
       
   586 	print "// default = ".join(" ",@DefaultPlats)."\n";
       
   587 
       
   588 	print <<ENDHERE;
       
   589 	
       
   590 PRJ_EXPORTS
       
   591 [<source path>\<source file>]	{<destination>}
       
   592 // list each file exported from source on a separate line
       
   593 // {<destination>} defaults to \\EPOC32\\Include\\<source file>
       
   594 
       
   595 PRJ_TESTEXPORTS
       
   596 [<source path>\<source file>]	{<destination>}
       
   597 // list each file exported from source on a separate line
       
   598 // {<destination>} defaults to BLD.INF dir
       
   599 
       
   600 PRJ_MMPFILES
       
   601 [<mmp path>\<mmp file>] {<qualifiers>}
       
   602 {MAKEFILE|NMAKEFILE} [<path>\<makefile>] {build_as_arm}
       
   603 // <qualifiers> are tidy, ignore, build_as_arm
       
   604 
       
   605 #if defined(<platform>)
       
   606 // .MMP statements restricted to <platform>
       
   607 #endif
       
   608 
       
   609 PRJ_TESTMMPFILES
       
   610 [<mmp path>\<mmp file>] {<qualifiers>}
       
   611 {MAKEFILE|NMAKEFILE} [<path>\<makefile>] {<qualifiers>}
       
   612 // <qualifiers> are {tidy} {ignore} {manual} {support} {build_as_arm}
       
   613 
       
   614 #if defined(<platform>)
       
   615 // .MMP statements restricted to <platform>
       
   616 #endif
       
   617 
       
   618 ENDHERE
       
   619 
       
   620 }
       
   621 
       
   622 sub WarnOrDie ($$) {
       
   623 	my ($dieref, $message) = @_;
       
   624 	if ($Options{k}) {
       
   625 		$KeepGoing{$message} = 1;
       
   626 	} else {
       
   627 		push @{$dieref}, $message;
       
   628 	}
       
   629 }
       
   630 
       
   631 sub ExtensionMakefileMissing($)
       
   632 {
       
   633 	$IgnoreMissingExtensionMakefile = @_;
       
   634 }
       
   635 
       
   636 sub ParseBldInf ($$$$$) {
       
   637 	my ($PlatsRef, $ExportsRef, $TestExportsRef, $BldInfPath, $EPOCIncPath, $EPOCPath, $EPOCDataPath)=@_;
       
   638 
       
   639 	my @Prj2D;
       
   640 	eval { &Prepfile_ProcessL(\@Prj2D, "${BldInfPath}$BldInfName",$variantMacroHRHFile); };
       
   641 	&FatalError($@) if $@;
       
   642 	
       
   643 	my @SupportedPlats=&Plat_List();
       
   644 
       
   645 	my @Plats;
       
   646 	my %RemovePlats;
       
   647 
       
   648 	my $DefaultPlatsUsed=0;
       
   649 	my %PlatformCheck;
       
   650 
       
   651 	my %ExportCheck;
       
   652 	my $Section=0;
       
   653 	our @PrjFileDie;
       
   654 	my $Line;
       
   655 	my $CurFile="${BldInfPath}$BldInfName";
       
   656 	LINE: foreach $Line (@Prj2D) {
       
   657 		my $LineNum=shift @$Line;
       
   658 		$_=shift @$Line;
       
   659 		if ($LineNum eq '#') {
       
   660 			$CurFile=$_;
       
   661 			next LINE;
       
   662 		}
       
   663 
       
   664 		$CurFile = &Path_Norm ($CurFile); 
       
   665 		
       
   666 		if (/^PRJ_(\w*)$/io) {
       
   667 			$Section=uc $1;
       
   668 			if ($Section=~/^(PLATFORMS|EXPORTS|TESTEXPORTS|MMPFILES|TESTMMPFILES|EXTENSIONS|TESTEXTENSIONS)$/o) {
       
   669 				if (@$Line) {
       
   670 					push @PrjFileDie, "$CurFile($LineNum) : Can't specify anything on the same line as a section header\n";
       
   671 				}
       
   672 				next LINE;
       
   673 			}
       
   674 			push @PrjFileDie, "$CurFile($LineNum) : Unknown section header - $_\n";
       
   675 			$Section=0;
       
   676 			next LINE;
       
   677 		}
       
   678 		if ($Section eq 'PLATFORMS') {
       
   679 #			platforms are gathered up into a big list that contains no duplicates.  "DEFAULT" is
       
   680 #			expanded to the list of default platforms.  Platforms specified with a "-" prefix
       
   681 #			are scheduled for removal from the list.  After processing platforms specified
       
   682 #			with the "-" prefix are removed from the list.
       
   683 
       
   684 			unshift @$Line, $_;
       
   685 			my $Candidate;
       
   686 			CANDLOOP: foreach $Candidate (@$Line) {
       
   687 				$Candidate=uc $Candidate;
       
   688 #				ignore old WINC target
       
   689 				if ($Candidate eq 'WINC') {
       
   690 					next CANDLOOP;
       
   691 				}
       
   692 #				expand DEFAULT
       
   693 				if ($Candidate eq 'DEFAULT') {
       
   694 					$DefaultPlatsUsed=1;
       
   695 					my $Default;
       
   696 					foreach $Default (@DefaultPlats) {
       
   697 						unless ($PlatformCheck{$Default}) {
       
   698 							push @Plats, $Default;
       
   699 							$PlatformCheck{$Default}="$CurFile: $LineNum";
       
   700 						}
       
   701 					}
       
   702 					next CANDLOOP;
       
   703 				}
       
   704 #				expand BASEDEFAULT
       
   705 				if ($Candidate eq 'BASEDEFAULT') {
       
   706 					$DefaultPlatsUsed=1;
       
   707 					my $Default;
       
   708 					foreach $Default (@BaseDefaultPlats) {
       
   709 						unless ($PlatformCheck{$Default}) {
       
   710 							push @Plats, $Default;
       
   711 							$PlatformCheck{$Default}="$CurFile: $LineNum";
       
   712 						}
       
   713 					}
       
   714 					next CANDLOOP;
       
   715 				}
       
   716 #				expand BASEUSERDEFAULT
       
   717 				if ($Candidate eq 'BASEUSERDEFAULT') {
       
   718 					$DefaultPlatsUsed=1;
       
   719 					my $Default;
       
   720 					foreach $Default (@BaseUserDefaultPlats) {
       
   721 						unless ($PlatformCheck{$Default}) {
       
   722 							push @Plats, $Default;
       
   723 							$PlatformCheck{$Default}="$CurFile: $LineNum";
       
   724 						}
       
   725 					}
       
   726 					next CANDLOOP;
       
   727 				}
       
   728 #				check for removals
       
   729 				if ($Candidate=~/^-(.*)$/o) {
       
   730 					$Candidate=$1;
       
   731 #					check default is specified
       
   732 					unless ($DefaultPlatsUsed) {
       
   733 						push @PrjFileDie, "$CurFile($LineNum) : \"DEFAULT\" must be specified before platform to be removed\n";
       
   734 						next CANDLOOP;
       
   735 					}
       
   736 					$RemovePlats{$Candidate}=1;
       
   737 					next CANDLOOP;
       
   738 				}
       
   739 # 				If tools platform is specified in bld.inf file then component is built for cwtools as well 
       
   740 				if ($Candidate =~ /^tools/i)
       
   741 						{
       
   742 						push @Plats, 'CWTOOLS';
       
   743 						}
       
   744 #				check platform is supported
       
   745 				unless (grep /^$Candidate$/, @SupportedPlats) {
       
   746 					WarnOrDie(\@PrjFileDie, "$CurFile($LineNum) : Unsupported platform $Candidate specified\n");
       
   747 					next CANDLOOP;
       
   748 				}
       
   749 #				check platform is not an IDE
       
   750 				if ($Candidate=~/^VC/o) {
       
   751 					push @PrjFileDie, "$CurFile($LineNum) : No need to specify platform $Candidate here\n";
       
   752 					next CANDLOOP;
       
   753 				}
       
   754 #				add the platform
       
   755 				unless ($PlatformCheck{$Candidate}) {
       
   756 					push @Plats, $Candidate;
       
   757 					my $SubPlat = sprintf("%sEDG", $Candidate);
       
   758 					push @Plats, $SubPlat 
       
   759 					    if (grep /^$SubPlat$/, @SupportedPlats);
       
   760 					$PlatformCheck{$Candidate}="$CurFile: $LineNum";
       
   761 				}
       
   762 			}
       
   763 			next LINE;
       
   764 		}
       
   765 
       
   766 		# Skip PRJ_TESTEXPORT section if -notest flag		
       
   767 		next LINE if ($Options{notest} && ($Section=~/^(TESTEXPORTS)$/o)); 
       
   768 		
       
   769 		if ($Section=~/^(EXPORTS|TESTEXPORTS)$/o) {
       
   770 
       
   771 #			make path absolute - assume relative to group directory
       
   772 			my $Type = 'file';
       
   773 			if (/^\:(\w+)/) {
       
   774 				# Export an archive
       
   775 				$Type = lc $1;
       
   776 				unless ($Type eq 'zip') {
       
   777 					push @PrjFileDie, "$CurFile($LineNum) : Unknown archive type - $Type\n";
       
   778 					next LINE;
       
   779 				}
       
   780 				$_ = shift @$Line;
       
   781 			}
       
   782 
       
   783 			my $loggedSourceExport = $_;
       
   784 			$_ = &Path_Norm ($_);
       
   785 			
       
   786 			my $Source=&Path_MakeAbs($CurFile, $_);
       
   787 			my $Releasable='';
       
   788 			my $emReleasable='';
       
   789 			my $unzip_option ='';
       
   790 			if (@$Line) {
       
   791 #				get the destination file if it's specified
       
   792 				$Releasable=shift @$Line;
       
   793 				CheckSource_MetaData(%CheckSourceEXPORTSMetaData, $CurFile, "PRJ_".$Section, $Releasable, $LineNum);
       
   794 				$Releasable = &Path_Norm ($Releasable);
       
   795 				$emReleasable=ucfirst $Releasable;
       
   796 				if ($emReleasable=~/^([A-Z]):(\\.*)$/)  {
       
   797 				  	$emReleasable=~s/://;
       
   798 					$Releasable=$EPOCDataPath.$emReleasable;
       
   799 				}
       
   800 			}
       
   801 
       
   802 			my $sourceExportTypeSuffix = "";
       
   803 			$sourceExportTypeSuffix .= " (NO DESTINATION)" if (!$Releasable && $Section =~ /^EXPORTS$/);		
       
   804 			CheckSource_MetaData(%CheckSourceEXPORTSMetaData, $CurFile, "PRJ_".$Section.$sourceExportTypeSuffix, $loggedSourceExport, $LineNum, $CheckSource_PhysicalCheck);
       
   805 			
       
   806 			if (@$Line) {
       
   807 				$unzip_option = shift @$Line;
       
   808 				unless ($unzip_option=~ /overwrite/i) {
       
   809 					push @PrjFileDie, "$CurFile($LineNum) : Too many arguments in exports section line\n";
       
   810 					next LINE;
       
   811 				}
       
   812 			}
       
   813 			unless ($Type eq 'zip' or &Path_Split('File', $Releasable)) {
       
   814 #				use the source filename if no filename is specified in the destination
       
   815 #				no filename for archives
       
   816 				$Releasable.=&Path_Split('File', $Source);
       
   817 			}
       
   818 			my $defpath;
       
   819 			if ($Type eq 'zip') {
       
   820 #				archives relative to EPOCROOT
       
   821 				$defpath = $ENV{EPOCROOT};
       
   822 			}
       
   823 			elsif (($Section =~ /EXPORTS$/) && ($Releasable =~ s/^\|[\/|\\]?//)) {
       
   824 #			'|' prefix forces "relative to bld.inf file" in PRJ_[TEST]EXPORTS destinations
       
   825 				$defpath = $CurFile;
       
   826 			}
       
   827 			elsif ($Section eq 'EXPORTS') {
       
   828 #				assume the destination is relative to $EPOCIncPath
       
   829 				$defpath = $EPOCIncPath;
       
   830 			}
       
   831 			else {
       
   832 				$defpath = $CurFile;
       
   833 			}
       
   834 			$Releasable=&Path_MakeEAbs($EPOCPath, $defpath, $Releasable);
       
   835 
       
   836 #			sanity checks!
       
   837 			if ($Type eq 'file' && $ExportCheck{uc $Releasable}) {
       
   838 				push @PrjFileDie, "$CurFile($LineNum) : Duplicate export $Releasable (from line $ExportCheck{uc $Releasable})\n";
       
   839 				next LINE;
       
   840 			}
       
   841 			$ExportCheck{uc $Releasable}="$CurFile: $LineNum";
       
   842 			if (! -e $Source) {
       
   843 				WarnOrDie(\@PrjFileDie, "$CurFile($LineNum) : Exported source file $Source not found\n");
       
   844 			}
       
   845 			elsif ($Type ne 'zip' && -d $Releasable) {
       
   846 				push @PrjFileDie, "$CurFile($LineNum) : Export target $Releasable must be a file.\n";
       
   847 			}
       
   848 			else {
       
   849 				if ($Section eq 'EXPORTS') {
       
   850 					push @$ExportsRef, {
       
   851 						'Source'=>$Source,
       
   852 						'Releasable'=>$Releasable,
       
   853 						'emReleasable'=>$emReleasable,
       
   854 						'Type'=>$Type,
       
   855 						'UnzipOption'=>$unzip_option
       
   856 					};
       
   857 				}
       
   858 				else {
       
   859 					push @$TestExportsRef, {
       
   860 						'Source'=>$Source,
       
   861 						'Releasable'=>$Releasable,
       
   862 						'emReleasable'=>$emReleasable,
       
   863 						'Type'=>$Type,
       
   864 						'UnzipOption'=>$unzip_option
       
   865 					};
       
   866 				}
       
   867 			}
       
   868 			next LINE;
       
   869 		}
       
   870 	}
       
   871 	if (@PrjFileDie) {
       
   872 		print STDERR
       
   873 			"\n${BldInfPath}$BldInfName FATAL ERROR(S):\n",
       
   874 			@PrjFileDie
       
   875 		;
       
   876 		exit 1;
       
   877 	}
       
   878 
       
   879 #	set the list of platforms to the default if there aren't any platforms specified,
       
   880 #	else add platforms to the global list unless they're scheduled for removal,
       
   881 	unless (@Plats) {
       
   882 		@$PlatsRef=@DefaultPlats;
       
   883 		# Include the list of BPABI Platforms in a default build.
       
   884 		my $OptionalPlat;
       
   885 		foreach $OptionalPlat (@OptionalPlats) {
       
   886 			#	VS6 and VS2003 are not real platforms and hence are not included in a default build
       
   887 			unless ( $OptionalPlat eq 'VS6' || $OptionalPlat eq 'VS2003') {
       
   888 				if (not grep /^$OptionalPlat$/i, @$PlatsRef) {
       
   889 					push @$PlatsRef, $OptionalPlat;
       
   890 				}
       
   891 			}
       
   892 		}		
       
   893 	}
       
   894 	else {
       
   895 		my $Plat;
       
   896 		foreach $Plat (@Plats) {
       
   897 			unless ($RemovePlats{$Plat}) {
       
   898 				push @$PlatsRef, $Plat;
       
   899 			}
       
   900 		}
       
   901 		push @PlatsReq , @$PlatsRef;
       
   902 	}
       
   903 }
       
   904 
       
   905 sub ExportDirs ($) {
       
   906 	my ($ExportsRef)=@_;
       
   907 
       
   908 	my %ExportDirHash;
       
   909 	foreach (@$ExportsRef) {
       
   910 		my $dir = ($$_{Type} eq 'zip') ? $$_{Releasable} : &Path_Split('Path',$$_{Releasable});
       
   911 		if ($dir) {
       
   912 			$dir=&Path_Chop($dir);
       
   913 			$ExportDirHash{uc $dir}=$dir;
       
   914 		}
       
   915 	}
       
   916 	my @ExportDirs;
       
   917 	foreach (keys %ExportDirHash) {
       
   918 		push @ExportDirs, $ExportDirHash{$_};
       
   919 	}
       
   920 	@ExportDirs;
       
   921 }
       
   922 
       
   923 
       
   924 sub ParseBldInfPlat ($$$$) {
       
   925 	my ($DataRef, $TestDataRef, $Plat, $BldInfPath, $FeatureVar)=@_;
       
   926 		
       
   927 #	get the platform .MMP macros
       
   928 	my %Plat;
       
   929 	eval { &Plat_GetL($Plat,\%Plat); };
       
   930 	&FatalError($@) if $@;
       
   931 
       
   932 #	get the raw data from the BLD.INF file
       
   933 	my @Prj2D;
       
   934 	eval { &Prepfile_ProcessL(\@Prj2D, "${BldInfPath}$BldInfName", ($FeatureVar ? $FeatureVar->{VARIANT_HRH} : $variantMacroHRHFile), @{$Plat{MmpMacros}}); };
       
   935 	&FatalError($@) if $@;
       
   936 
       
   937 	my %dummy;
       
   938 	my @userIncludes = ('.');
       
   939 	my @systemIncludes = ();
       
   940 	$CheckSourceBldInfIncludes{$Plat} = CheckSource_Includes("${BldInfPath}$BldInfName", %dummy, $variantMacroHRHFile, @{$Plat{MmpMacros}}, @userIncludes, @systemIncludes, $CheckSource_NoUserSystemDistinction);
       
   941 	
       
   942 #	process the raw data
       
   943 	my $IsExtensionBlock =0;
       
   944 	my (@ExtensionBlockData, $ErrorString);
       
   945 	my %Check;
       
   946 	my $Section=0;
       
   947 	my @PrjFileDie;
       
   948 	my $Line;
       
   949 	my $CurFile="${BldInfPath}$BldInfName";
       
   950 	LINE: foreach $Line (@Prj2D) {
       
   951 
       
   952 		my %Data;
       
   953 		my %Temp;
       
   954 
       
   955 		my $LineNum=shift @$Line;
       
   956 		if ($LineNum eq '#') {
       
   957 			$CurFile=shift @$Line;
       
   958 			next LINE;
       
   959 		}
       
   960 
       
   961 		$CurFile = &Path_Norm ($CurFile);
       
   962 		
       
   963 #		upper-case all the data here, but record original source case
       
   964 #		in a hash so that it can be recalled for CheckSource purposes
       
   965 
       
   966 		my %originalSourceCase;
       
   967    		foreach (@$Line) {
       
   968  			$originalSourceCase{uc $_} = $_;  # needed for extension template makefile MACROs 
       
   969    			$_=uc $_;
       
   970    		}
       
   971 
       
   972 		$_=shift @$Line;
       
   973 
       
   974 #		check for section headers - don't test for the right ones here
       
   975 #		because we do that in the first parse function
       
   976 
       
   977 		if (/^PRJ_(\w*)$/o) {
       
   978 			$Section=$1;
       
   979 			next LINE;
       
   980 		}
       
   981 
       
   982 #		Skip section if PRJ_TESTMMPFILES and -notest option
       
   983 		next LINE if ($Options{notest} && ($Section=~/^(TESTMMPFILES)$/o)); 
       
   984 
       
   985 #		check for EXTENSION sections
       
   986 		if ($Section=~/^(EXTENSIONS|TESTEXTENSIONS)$/o) {
       
   987 
       
   988 #			We have an extension block
       
   989 			if (/^start(\w*)$/io) {
       
   990 				if ($IsExtensionBlock) {
       
   991 					&FatalError("$CurFile($LineNum) : Cannot embed Extension Template 'start' sections\n");
       
   992 				}
       
   993 				$IsExtensionBlock =1;
       
   994 				$ErrorString = "$CurFile($LineNum)";
       
   995 				foreach (@$Line)
       
   996 				{
       
   997 				if (/^EXTENSION$/)
       
   998 					{
       
   999 					my $extensionTemplate = @$Line[scalar(@$Line)-1];
       
  1000 					CheckSource_MetaData(%CheckSourceEXTENSIONSMetaData, $CurFile, "PRJ_".$Section, $originalSourceCase{$extensionTemplate}.".mk", $LineNum, $CheckSource_PhysicalCheck) if ($extensionTemplate);
       
  1001 					}
       
  1002 				}
       
  1003 
       
  1004 				push @ExtensionBlockData, $Line; 			
       
  1005 				next LINE;
       
  1006 			}		
       
  1007 			
       
  1008 			if (($IsExtensionBlock) & (! (/^end(\w*)$/io))) {
       
  1009 				if (($_ ne "TOOL") & ($_ ne "OPTION") & ($_ ne "TARGET") & ($_ ne "SOURCES") & ($_ ne "DEPENDENCIES")) {
       
  1010 							&FatalError("$CurFile($LineNum) : Unrecognised keyword: $_.  Is there an 'end' corresponding to the 'start' for the Extension Template?\n"); 
       
  1011 				}
       
  1012 				if ($_ ne "OPTION") {
       
  1013 					unshift(@$Line, $_);					
       
  1014 				}
       
  1015 #				Need to revert MACROs back to their original case
       
  1016 				foreach (@$Line) {
       
  1017 					$_=$originalSourceCase{$_};
       
  1018 				}
       
  1019 				push @ExtensionBlockData, $Line; 
       
  1020 				next LINE;
       
  1021 			}
       
  1022 			
       
  1023 			if (/^end(\w*)$/io) {
       
  1024 				if (! $IsExtensionBlock) {
       
  1025 					&FatalError("$CurFile($LineNum) : No 'start' corresponding to this 'end' in Extension Template section\n"); 
       
  1026 				}
       
  1027 				$IsExtensionBlock =0;
       
  1028 				my $OutDir=Path_Chop($E32env::Data{BldPath}).$BldInfPath;
       
  1029 #				Generate wrapper makefile for this platform.
       
  1030 				eval { &Load_ModuleL('WrapperMakefile'); };
       
  1031 					&FatalError($@) if $@;
       
  1032 				$OutDir=~ s/\\/\//g;  # convert to unix slashes for wrappermakefile.pm
       
  1033 				%Data = GenerateWrapper($Plat, $OutDir, $ErrorString, \@PrjFileDie, @ExtensionBlockData);
       
  1034 				if (!$IgnoreMissingExtensionMakefile)
       
  1035 				{
       
  1036 					$Data{ExtensionRoot}=&Path_Split('Path', $CurFile);
       
  1037 					$Data{Path}=~ s/\//\\/g;  # convert unix slashes back to win32 
       
  1038 					$Data{Base}=~ s/\//\\/g;
       
  1039 				}
       
  1040 				@ExtensionBlockData = ();  # clear array
       
  1041 			}
       
  1042 		}
       
  1043 
       
  1044 #		check for MMP sections and get the .MMP file details
       
  1045 		if ($Section=~/^(MMPFILES|TESTMMPFILES)$/o) {
       
  1046 			$Data{Ext}='.MMP';
       
  1047 #			check for MAKEFILE statements for custom building
       
  1048 			my $SubSection = "MMP";
       
  1049 			if (/^MAKEFILE$/o) {
       
  1050 				$SubSection = $_;
       
  1051 				$Data{Makefile}=2;  # treat MAKEFILE=>NMAKEFILE   =1;
       
  1052 				$_=shift @$Line;
       
  1053 				$Data{Ext}=&Path_Split('Ext', $_);
       
  1054 			}
       
  1055 			if (/^NMAKEFILE$/o) {
       
  1056 				$SubSection = $_;
       
  1057 				$Data{Makefile}=2;
       
  1058 				$_=shift @$Line;
       
  1059 				$Data{Ext}=&Path_Split('Ext', $_);
       
  1060 			}
       
  1061 			if (/^GNUMAKEFILE$/o) {
       
  1062 				$SubSection = $_;
       
  1063 				$Data{Makefile}=1;
       
  1064 				$_=shift @$Line;
       
  1065 				$Data{Ext}=&Path_Split('Ext', $_);
       
  1066 			}
       
  1067 			CheckSource_MetaData(%CheckSourceMMPFILESMetaData, $CurFile, "PRJ_$Section $SubSection", $originalSourceCase{$_}, $LineNum, $CheckSource_PhysicalCheck);
       
  1068 			$_ = &Path_Norm ($_);
       
  1069 			
       
  1070 #			path considered relative to the current file
       
  1071 			$Data{Path}=&Path_Split('Path', &Path_MakeAbs($CurFile, $_));
       
  1072 
       
  1073 #			this function doesn't care whether the .MMPs are listed with their extensions or not
       
  1074 			$Data{Base}=&Path_Split('Base', $_);
       
  1075 			my $MmpFile= $Data{Path}.$Data{Base};
       
  1076    
       
  1077 #			check the file isn't already specified
       
  1078   			if ($Check{$MmpFile}) {
       
  1079   				push @PrjFileDie, "$CurFile($LineNum) : duplicate $Data{Base} (from line $Check{$MmpFile})\n";
       
  1080    				next;
       
  1081    			}
       
  1082   			$Check{$MmpFile}="$CurFile: $LineNum";
       
  1083 
       
  1084 #			check the file exists
       
  1085 			unless (-e "$Data{Path}$Data{Base}$Data{Ext}") {
       
  1086 				WarnOrDie(\@PrjFileDie, "$CurFile($LineNum) : $Data{Path}$Data{Base}$Data{Ext} does not exist\n");
       
  1087 				next LINE;
       
  1088 			}
       
  1089 			
       
  1090 
       
  1091 #			process the file's attributes
       
  1092 			if ($Section eq 'MMPFILES') {
       
  1093 				foreach (@$Line) {
       
  1094 					if (/^TIDY$/o) {
       
  1095 						$Data{Tidy}=1;
       
  1096 						next;
       
  1097 					}
       
  1098 					if (/^IGNORE$/o) {
       
  1099 						next LINE;
       
  1100 					}
       
  1101 					if (/^BUILD_AS_ARM$/o) {
       
  1102 					  $Data{BuildAsARM}="-arm";
       
  1103 					  next;
       
  1104 					}
       
  1105 
       
  1106 					push @PrjFileDie, "$CurFile($LineNum) : Don't understand .MMP file argument \"$_\"\n";
       
  1107 				}
       
  1108 			}
       
  1109 
       
  1110 #			process the test .MMP file's attributes
       
  1111 			elsif ($Section eq 'TESTMMPFILES') {
       
  1112 				foreach (@$Line) {
       
  1113 					if (/^TIDY$/o) {
       
  1114 						$Data{Tidy}=1;
       
  1115 						next;
       
  1116 					}
       
  1117 					if (/^IGNORE$/o) {
       
  1118 						next LINE;
       
  1119 					}
       
  1120 					if (/^BUILD_AS_ARM$/o) {
       
  1121 					  $Data{BuildAsARM}="-arm";
       
  1122 					  next;
       
  1123 					}
       
  1124 					if (/^MANUAL$/o) {
       
  1125 						$Data{Manual}=1;
       
  1126 						next;
       
  1127 					}
       
  1128 					if (/^SUPPORT$/o) {
       
  1129 						$Data{Support}=1;
       
  1130 						next;
       
  1131 					}
       
  1132 					push @PrjFileDie, "$CurFile($LineNum) : Don't understand test .MMP file argument \"$_\"\n";
       
  1133 				}
       
  1134 			}
       
  1135 		}		
       
  1136 
       
  1137 #		store the data
       
  1138 		if (($Section eq 'MMPFILES') or ($Section eq 'EXTENSIONS')) {
       
  1139 			if ($IgnoreMissingExtensionMakefile and $Section eq 'EXTENSIONS')
       
  1140 			{
       
  1141 				# More than more ext makefile can be missing so reset indicator
       
  1142 				$IgnoreMissingExtensionMakefile = 0;
       
  1143 			}
       
  1144 			else
       
  1145 			{
       
  1146 				push @$DataRef, \%Data;
       
  1147 			}
       
  1148 			next LINE;
       
  1149 		}
       
  1150 		if (($Section eq 'TESTMMPFILES') or ($Section eq 'TESTEXTENSIONS')) {
       
  1151 			if ($IgnoreMissingExtensionMakefile and $Section eq 'TESTEXTENSIONS')
       
  1152 			{
       
  1153 				# More than more ext makefile can be missing so reset indicator
       
  1154 				$IgnoreMissingExtensionMakefile = 0;
       
  1155 			}
       
  1156 			else
       
  1157 			{
       
  1158 				push @$TestDataRef, \%Data;
       
  1159 			}
       
  1160 			next LINE;
       
  1161 		}
       
  1162 		
       
  1163 	}
       
  1164 #	line loop end
       
  1165 
       
  1166 #	exit if there are errors
       
  1167 	if (@PrjFileDie) {
       
  1168 		print STDERR
       
  1169 			"\n\"${BldInfPath}$BldInfName\" FATAL ERROR(S):\n",
       
  1170 			@PrjFileDie
       
  1171 		;
       
  1172 		exit 1;
       
  1173 	}
       
  1174 }
       
  1175 
       
  1176 
       
  1177 sub FatalError (@) {
       
  1178 
       
  1179 	print STDERR "BLDMAKE ERROR: @_\n";
       
  1180 	exit 1;
       
  1181 }
       
  1182 
       
  1183 sub CreatePlatformPm ($$$$$$) {
       
  1184 	my ($BatchPath, $PlatsRef, $RealPlatsRef, $RealHRef, $AllPlatDataHRef, $AllPlatTestDataHRef)=@_;
       
  1185 
       
  1186 
       
  1187 # 	exclude GCCXML, EDG and CWTOOLS  from list of RealPlats
       
  1188 	my @RealPlats;
       
  1189 	foreach my $Plat (@$RealPlatsRef){
       
  1190 	unless (($Plat =~ /^gccxml/i)  or  ($Plat =~ /^edg/i) or  ($Plat =~ /^cwtools/i) or ($Plat =~ /^x86gcc/i) or ($Plat =~ /^x86gmp/i)) {
       
  1191 # 	exclude BPABI targets from list of RealPlats provided they are not specified in the platform list
       
  1192 				if (grep /^$Plat$/i, @OptionalPlats) {
       
  1193 					if (grep /^$Plat$/, @PlatsReq) {
       
  1194 						push @RealPlats, $Plat;
       
  1195 					}
       
  1196 					next;
       
  1197 				}
       
  1198 				push @RealPlats, $Plat;
       
  1199 			}
       
  1200 	}
       
  1201 
       
  1202 
       
  1203 	&Output(
       
  1204 		"# Bldmake-generated perl file - PLATFORM.PM\n",
       
  1205 		"\n",
       
  1206 		"# use a perl integrity checker\n",
       
  1207 		"use strict;\n",
       
  1208 		"\n",
       
  1209 		"package Platform;\n",
       
  1210 		"\n",
       
  1211 		"use vars qw(\@Plats \@RealPlats %Programs %TestPrograms %FeatureVariantSupportingPlats);\n",
       
  1212 		"\n",
       
  1213 		"\@Plats=(\'",join('\',\'',@$PlatsRef),"\');\n",
       
  1214 		"\n",
       
  1215 		"\@RealPlats=(\'", join('\',\'',@RealPlats),"\');\n",
       
  1216 		"\n",
       
  1217 		"%Programs=(\n"
       
  1218 	);
       
  1219 	my %All; # all programs for all platforms
       
  1220 	my $TmpStr;
       
  1221 	my $Plat;
       
  1222 	foreach $Plat (@$PlatsRef) {
       
  1223 		$TmpStr="	\'$Plat\'=>[";
       
  1224 		if (@{${$AllPlatDataHRef}{$$RealHRef{$Plat}}}) {
       
  1225 			my $ProgRef;
       
  1226 			foreach $ProgRef (@{${$AllPlatDataHRef}{$$RealHRef{$Plat}}}) {
       
  1227 				$TmpStr.="'$$ProgRef{Base}',";
       
  1228 				$All{$$ProgRef{Base}}=1;
       
  1229 			}
       
  1230 			chop $TmpStr;
       
  1231 			}
       
  1232 		&Output(
       
  1233 			"$TmpStr],\n"
       
  1234 		);
       
  1235 		}
       
  1236 	$TmpStr="	ALL=>[";
       
  1237 	if (keys %All) {
       
  1238 		my $Prog;
       
  1239 		foreach $Prog (keys %All) {
       
  1240 			$TmpStr.="'$Prog',";
       
  1241 		}
       
  1242 		chop $TmpStr;
       
  1243 	}
       
  1244 	&Output(
       
  1245 		"$TmpStr]\n",
       
  1246 		");\n",
       
  1247 		"\n",
       
  1248 		"%TestPrograms=(\n"
       
  1249 	);
       
  1250 	%All=();
       
  1251 	foreach $Plat (@$PlatsRef) {
       
  1252 		$TmpStr="	\'$Plat\'=>[";
       
  1253 		if (@{${$AllPlatTestDataHRef}{$$RealHRef{$Plat}}}) {
       
  1254 			my $ProgRef;
       
  1255 			foreach $ProgRef (@{${$AllPlatTestDataHRef}{$$RealHRef{$Plat}}}) {
       
  1256 				$TmpStr.="'$$ProgRef{Base}',";
       
  1257 				$All{$$ProgRef{Base}}=1;
       
  1258 			}
       
  1259 			chop $TmpStr;
       
  1260 		}
       
  1261 		&Output("$TmpStr],\n");
       
  1262 	}
       
  1263 	$TmpStr="	ALL=>[";
       
  1264 	if (keys %All) {
       
  1265 		my $Prog;
       
  1266 		foreach $Prog (keys %All) {
       
  1267 			$TmpStr.="'$Prog',";
       
  1268 		}
       
  1269 		chop $TmpStr;
       
  1270 	}
       
  1271 	&Output(
       
  1272 		"$TmpStr]\n",
       
  1273 		");\n",
       
  1274 		"\n"
       
  1275 	);
       
  1276 
       
  1277 	&Output(
       
  1278 		"\n",
       
  1279 		"%FeatureVariantSupportingPlats=("
       
  1280 	);
       
  1281 
       
  1282 	$TmpStr = "";
       
  1283 	foreach $Plat (@$PlatsRef)
       
  1284 		{
       
  1285 		$TmpStr .= "\n\t$Plat=>1," if (&Plat_SupportsFeatureVariants($Plat));
       
  1286 		}
       
  1287 
       
  1288 	chop $TmpStr;
       
  1289 
       
  1290 	&Output(
       
  1291 		"$TmpStr\n",
       
  1292 		");\n",
       
  1293 		"\n",
       
  1294 		"1;\n"
       
  1295 	);
       
  1296 
       
  1297 #	write the PLATFORM.PM file
       
  1298 	&WriteOutFileL($BatchPath."PLATFORM.PM");
       
  1299 }
       
  1300 
       
  1301 sub CreatePerlBat ($) {
       
  1302 	my ($BldInfPath)=@_;
       
  1303 
       
  1304 #	create ABLD.BAT, which will call ABLD.PL
       
  1305 #   NB. must quote $BldInfPath because it may contain spaces, but we know it definitely
       
  1306 #       ends with \ so we need to generate "\foo\bar\\" to avoid quoting the close double quote
       
  1307 	&Output(
       
  1308 		"\@ECHO OFF\n",
       
  1309 		"\n", 
       
  1310 		"REM Bldmake-generated batch file - ABLD.BAT\n",
       
  1311 		"REM ** DO NOT EDIT **", 
       
  1312 		"\n",
       
  1313 		"\n",
       
  1314 		"perl -S ABLD.PL \"${BldInfPath}\\\" %1 %2 %3 %4 %5 %6 %7 %8 %9\n",
       
  1315 		"if errorlevel==1 goto CheckPerl\n",
       
  1316 		"goto End\n",
       
  1317 		"\n",
       
  1318 		":CheckPerl\n",
       
  1319 		"perl -v >NUL\n",
       
  1320 		"if errorlevel==1 echo Is Perl, version 5.003_07 or later, installed?\n",
       
  1321 		"goto End\n",
       
  1322 		"\n",
       
  1323 		":End\n"
       
  1324 	);
       
  1325 
       
  1326 #	check that the .BAT file does not already exist and is read-only
       
  1327 	if ((-e "${BldInfPath}ABLD.BAT")  && !(-w "${BldInfPath}ABLD.BAT")) {
       
  1328 		warn "BLDMAKE WARNING: read-only ABLD.BAT will be overwritten\n";
       
  1329 		chmod 0222, "${BldInfPath}ABLD.BAT";
       
  1330 	}
       
  1331 
       
  1332 #	create the .BAT file in the group directory
       
  1333 	&WriteOutFileL($BldInfPath."ABLD.BAT",1);
       
  1334 
       
  1335 }
       
  1336 
       
  1337 sub GetArchiveExportList($) {
       
  1338 	my ($ExportRef) = @_;
       
  1339 	my $Type = $ExportRef->{Type};
       
  1340 	my $Src = $ExportRef->{Source};
       
  1341 	my $Dest = $ExportRef->{Releasable};
       
  1342 	$Dest = '' if (!defined($Dest));
       
  1343 	my @list = ();
       
  1344 	if ($Type eq 'zip') {
       
  1345 		unless (open PIPE, "unzip -l $Src | ") {
       
  1346 			warn "Can't unzip $Src\n";
       
  1347 		}
       
  1348 		while (<PIPE>) {
       
  1349 			if (/^\s*\d+\s+\S+\s+\S+\s+(.*?)\s*$/) {
       
  1350 #				ignore empty lines and anything that finishes with / 
       
  1351 				unless(($1=~/\/\s*$/) || ($1=~/^$/)) {
       
  1352 
       
  1353 					my $member = $1;
       
  1354 					$member =~ s/\$/\$\$/g;
       
  1355 					if (!$Dest){
       
  1356 						push @list, "$ENV{EPOCROOT}$member";
       
  1357 					}
       
  1358 					else{
       
  1359 						push @list, "$Dest\\$member";
       
  1360 					}
       
  1361 				}
       
  1362 			}
       
  1363 		}
       
  1364 		close PIPE;
       
  1365 	}
       
  1366 	return @list;
       
  1367 }
       
  1368 
       
  1369 sub CreateExportMak ($$$) {
       
  1370 	my ($Makefile, $ExportsRef, $ExpDirsRef)=@_;
       
  1371 
       
  1372 #	create EXPORT.MAKE
       
  1373 
       
  1374 	my $erasedefn = "\@erase";
       
  1375 	$erasedefn = "\@erase 2>>nul" if ($ENV{OS} eq "Windows_NT");
       
  1376 	&Output(
       
  1377 		"ERASE = $erasedefn\n",
       
  1378 		"\n",
       
  1379 		"\n",
       
  1380 		"EXPORT : EXPORTDIRS"
       
  1381 	);
       
  1382 	my $ref;
       
  1383 	if (@$ExportsRef) {
       
  1384 		foreach $ref (@$ExportsRef) {
       
  1385 			if ($$ref{Type} eq 'zip') {
       
  1386 				my @list = &GetArchiveExportList($ref);
       
  1387 				foreach (@list) {
       
  1388 					my $dst=$_;
       
  1389 					&Output(
       
  1390 						" \\\n",
       
  1391 						"\t$dst"
       
  1392 					);
       
  1393 				}
       
  1394 			} else {
       
  1395 				my $name=&Path_Quote($$ref{Releasable});
       
  1396 				&Output(
       
  1397 					" \\\n",
       
  1398 					"\t$name"
       
  1399 				);
       
  1400 			}
       
  1401 		}
       
  1402 	}
       
  1403 	else {
       
  1404 		&Output(
       
  1405 			" \n",
       
  1406 			"\t\@echo Nothing to do\n"
       
  1407 		);
       
  1408 	}
       
  1409 	&Output(
       
  1410 		"\n",
       
  1411 		"\n",
       
  1412 		"\n",
       
  1413 		"EXPORTDIRS :"
       
  1414 	);
       
  1415 	my $dir;
       
  1416 	foreach $dir (@$ExpDirsRef) {
       
  1417 		$dir=&Path_Quote($dir);
       
  1418 		&Output(
       
  1419 			" $dir"
       
  1420 		);
       
  1421 	}
       
  1422 	&Output(
       
  1423 		"\n",
       
  1424 		"\n"
       
  1425 	);
       
  1426 	foreach $dir (@$ExpDirsRef) {
       
  1427 		&Output(
       
  1428 			"$dir :\n",
       
  1429 			    "\t\@perl -S emkdir.pl \"\$\@\"\n",
       
  1430 			"\n"
       
  1431 		);
       
  1432 	}
       
  1433 	&Output(
       
  1434 		"\n",
       
  1435 		"\n"
       
  1436 	);
       
  1437 	foreach $ref (@$ExportsRef) {
       
  1438 		my $unzipoption = $$ref{UnzipOption};
       
  1439 		CheckSource_ExportedIncludes($$ref{Source}, $$ref{Releasable}, %CheckSourceEXPORTSIncludes);
       
  1440 		
       
  1441 		if ($$ref{Type} eq 'zip') {
       
  1442 			my $src = &Path_Quote($$ref{Source});
       
  1443 			my $destdir = &Path_Quote($$ref{Releasable});
       
  1444 			$destdir=$ENV{EPOCROOT} if (!defined($destdir) or ($destdir eq ''));
       
  1445 			my @list = &GetArchiveExportList($ref);
       
  1446   			foreach (@list) {  				
       
  1447   				my $dst=$_;
       
  1448   				&Output(
       
  1449  					"$dst : $src\n",
       
  1450   				);
       
  1451   			}
       
  1452 			if ($unzipoption =~ /overwrite/i){
       
  1453 				&Output(
       
  1454 				"\t- unzip -o $src -d \"$destdir\"\n",
       
  1455 				);
       
  1456 			}
       
  1457 			else{	
       
  1458 				&Output(
       
  1459 				"\t- unzip -u  -o $src -d \"$destdir\"\n",
       
  1460 				);
       
  1461 			}
       
  1462 		} else {
       
  1463 			my $dst=&Path_Quote($$ref{Releasable});
       
  1464 			my $src=&Path_Quote($$ref{Source});
       
  1465 			&Output(
       
  1466 				"$dst : $src\n",
       
  1467 					"\tcopy \"\$?\" \"\$\@\"\n",
       
  1468 				"\n"
       
  1469 			);
       
  1470 		}
       
  1471 	}
       
  1472 	&Output(
       
  1473 		"\n",
       
  1474 		"\n"
       
  1475 	);
       
  1476 	if (@$ExportsRef) {
       
  1477 		&Output(
       
  1478 			"CLEANEXPORT :\n"
       
  1479 		);
       
  1480 		foreach $ref (@$ExportsRef) {
       
  1481 			if ($$ref{Type} eq 'zip') {
       
  1482 				my @list = &GetArchiveExportList($ref);
       
  1483 				foreach (@list) {
       
  1484 					my $dst=$_;
       
  1485 					$dst =~ s/\//\\/go;
       
  1486 					&Output(
       
  1487 						"\t-\$(ERASE) \"$dst\"\n"
       
  1488 					);
       
  1489 				}
       
  1490 			} else {
       
  1491 				my $dst = $$ref{Releasable};
       
  1492 				$dst =~ s/\//\\/go;
       
  1493 				&Output(
       
  1494 					"\t-\$(ERASE) \"$dst\"\n"
       
  1495 				);
       
  1496 			}
       
  1497 		}
       
  1498 		&Output(
       
  1499 			"\n",
       
  1500 			"WHAT :\n"
       
  1501 		);
       
  1502 		foreach $ref (@$ExportsRef) {
       
  1503 			if ($$ref{Type} eq 'zip') {
       
  1504 				my @list = &GetArchiveExportList($ref);
       
  1505 				foreach (@list) {
       
  1506 					my $dst=$_;
       
  1507 					$dst =~ s/\//\\/go;
       
  1508 					&Output(
       
  1509 						"\t\@echo \"$dst\"\n"
       
  1510 					);
       
  1511 				}
       
  1512 			} else {
       
  1513 				my $dst = $$ref{Releasable};
       
  1514 				$dst =~ s/\//\\/go;
       
  1515 				&Output(
       
  1516 					"\t\@echo \"$dst\"\n"
       
  1517 				);
       
  1518 			}
       
  1519 		}
       
  1520 	}
       
  1521 	else {
       
  1522 		&Output(
       
  1523 			"CLEANEXPORT :\n",
       
  1524 			"\t\@echo Nothing to do\n",
       
  1525 			"WHAT :\n",
       
  1526 			"\t\@rem do nothing\n"
       
  1527 		);
       
  1528 	}
       
  1529 
       
  1530 	&Output(
       
  1531 		"\nCHECKSOURCE :\n"
       
  1532 	);
       
  1533 	
       
  1534 	&Output (CheckSource_MakefileOutput(%CheckSourceEXPORTSMetaData));
       
  1535 	&Output (CheckSource_MakefileOutput(%CheckSourceEXPORTSIncludes));
       
  1536 
       
  1537 	&Output("\n");
       
  1538 	
       
  1539 #	write EXPORT.MAKE
       
  1540 	&WriteOutFileL($Makefile);
       
  1541 }
       
  1542 
       
  1543 sub CreatePlatExports ($$) {
       
  1544 	my ($RealPlat,$Exports)=@_;
       
  1545 	my $Ref;
       
  1546 	&Output(
       
  1547  	"\n# Rules which handle the case when \$(CFG) is not defined\n\n" ,
       
  1548  	"EXPORT:		\tEXPORTUREL EXPORTUDEB\n", 
       
  1549  	"EXPORTCLEAN:	\tEXPORTCLEANUREL EXPORTCLEANUDEB\n",
       
  1550  	"EXPORTWHAT:	\tEXPORTWHATUREL EXPORTWHATUDEB\n",
       
  1551   
       
  1552  	"\n# definitions \n",
       
  1553  	"DATAx = $ENV{EPOCROOT}epoc32\\data\n",
       
  1554  	"EMULx = $ENV{EPOCROOT}epoc32\\$RealPlat\n",
       
  1555  	"URELx = $ENV{EPOCROOT}epoc32\\release\\$RealPlat\\urel\n",
       
  1556  	"UDEBx = $ENV{EPOCROOT}epoc32\\release\\$RealPlat\\udeb\n",
       
  1557  	"\n"
       
  1558 	);
       
  1559 	
       
  1560 	&Output( 
       
  1561 	"# Exports to emulated drive A: to Y \n\n",
       
  1562 	"EXPORTGENERIC : EXPORTDIRSGENERIC",
       
  1563 	);
       
  1564 	 
       
  1565 	my @dirs;
       
  1566 	my @expgen;
       
  1567 	my %dirsg;
       
  1568 	foreach $Ref (@$Exports) {
       
  1569 	 	if ($$Ref{emReleasable}=~/^([A-Y])(\\.*)$/){
       
  1570 		   my $exp="\\$$Ref{emReleasable}";
       
  1571 	 	   if ($$Ref{Type} eq 'zip') {	
       
  1572 			 my @list = &GetArchiveExportList($Ref);	
       
  1573 			  foreach (@list) {
       
  1574 				my $dst=&Path_Quote($_);
       
  1575 				if ($dst=~/([^\\]*)$/o){
       
  1576 					$dst=$1;
       
  1577 				}
       
  1578 				my $zipdest=$dst;
       
  1579 				$zipdest =~ s/\//\\/g;
       
  1580 			    push  @expgen, "$exp\\$zipdest";
       
  1581 			    my $zippath= &Path_Chop(&Path_Split('Path', $zipdest));
       
  1582 				if(!$zippath){
       
  1583 					$dirsg{$exp}=$exp;
       
  1584 				}
       
  1585 				else{
       
  1586 					 $dirsg{"$exp\\$zippath"}="$exp\\$zippath";
       
  1587 				}
       
  1588 				&Output(" \\\n","\t\$(EMULx)$exp\\$zipdest");
       
  1589 			 }      
       
  1590 		 }
       
  1591 		 else { 
       
  1592 		     my $dir =  &Path_Chop(&Path_Split('Path', $exp));  
       
  1593 			 push @expgen,  $exp;	
       
  1594 			 $dirsg{$dir}=$dir;
       
  1595 			 &Output(" \\\n", "\t\$(EMULx)$exp "); 
       
  1596 		 }
       
  1597 	   }
       
  1598 	}
       
  1599 	&Output("\n\nEXPORTDIRSGENERIC : ");
       
  1600 	foreach (keys %dirsg){
       
  1601 			 push @dirs, "\$(EMULx)$dirsg{$_}";
       
  1602 			 &Output(" \\\n", "\t\$(EMULx)$_"); 
       
  1603 	} 
       
  1604 	&Output("\n\n");
       
  1605 	foreach (@expgen){	 
       
  1606 			&Output( 
       
  1607 			"\$(EMULx)$_ : \t\$(DATAx)$_ \n",
       
  1608 			"\tcopy \"\$?\" \"\$@\" \n"
       
  1609 			);
       
  1610 	}	
       
  1611 	&Output("\nEXPORTCLEANGENERIC :\n");		
       
  1612 	foreach (@expgen){	 
       
  1613 			&Output("\t-@\$(ERASE) \$(EMULx)$_ \n");
       
  1614 	} 			
       
  1615 	&Output("\nEXPORTWHATGENERIC :\n");			
       
  1616 	foreach (@expgen){	   
       
  1617 			&Output("\t\@echo \$(EMULx)$_ \n");
       
  1618 	}
       
  1619 		
       
  1620 	&Output( 
       
  1621 	 		"\n\n# Exports to emulated drive Z: - UREL version \n\n",
       
  1622 	 		"EXPORTUREL : EXPORTDIRSUREL",
       
  1623 	 	   );
       
  1624 	
       
  1625 	my @expurel; 
       
  1626 	my %dirsurel;
       
  1627 	foreach $Ref (@$Exports) {
       
  1628 		if ($$Ref{emReleasable}=~/^(Z)(\\.*)$/){
       
  1629 			my $exp="\\$$Ref{emReleasable}";
       
  1630 	 	    if ($$Ref{Type} eq 'zip') {
       
  1631 			  my @list = &GetArchiveExportList($Ref);
       
  1632 			  foreach (@list) {
       
  1633 				my $dst=&Path_Quote($_);
       
  1634 				if ($dst=~/([^\\]*)$/o){
       
  1635 					$dst=$1;
       
  1636 				}
       
  1637 				my $zipdest=$dst;
       
  1638 				$zipdest=~ s/\//\\/g;
       
  1639 				push  @expurel, "$exp\\$zipdest"; 
       
  1640 				my $zippath= &Path_Chop(&Path_Split('Path', $zipdest)); 
       
  1641 				if(!$zippath){
       
  1642 				   $dirsurel{$exp}=$exp;
       
  1643 				}
       
  1644 				else{
       
  1645 					$dirsurel{"$exp\\$zippath"}="$exp\\$zippath";
       
  1646 				}
       
  1647 				&Output(" \\\n","\t\$(URELx)$exp\\$zipdest");
       
  1648 			}  
       
  1649 		}
       
  1650 		else {
       
  1651 			  my $dir =  &Path_Chop(&Path_Split('Path', $exp));  
       
  1652 			  push @expurel,  $exp; 
       
  1653 			  $dirsurel{$dir}=$dir;
       
  1654 			  &Output(" \\\n", "\t\$(URELx)$exp "); 
       
  1655 		}
       
  1656 	  }
       
  1657 	} 
       
  1658 	&Output("\n\nEXPORTDIRSUREL : ");
       
  1659 	foreach (keys %dirsurel){
       
  1660 			push @dirs, "\$(URELx)$dirsurel{$_}";
       
  1661    			&Output(" \\\n", "\t\$(URELx)$_ "); 
       
  1662 	}
       
  1663 	&Output("\n\n");	
       
  1664 	foreach (@expurel){
       
  1665 			 &Output( 
       
  1666 					"\$(URELx)$_ : \t\$(DATAx)$_ \n",
       
  1667 					"\tcopy \"\$?\" \"\$@\" \n"
       
  1668 			 );
       
  1669 	}		
       
  1670 	&Output("\nEXPORTCLEANUREL :\n"); 		
       
  1671 	foreach (@expurel){	
       
  1672 			 &Output("\t-@\$(ERASE) \$(URELx)$_ \n"); 
       
  1673 	}  
       
  1674 	&Output("\nEXPORTWHATUREL :\n");	
       
  1675 	foreach (@expurel){	
       
  1676 			 &Output( "\t\@echo \$(URELx)$_ \n"); 	
       
  1677 	}
       
  1678 	   
       
  1679 	&Output( 
       
  1680 	 		"\n\n# Exports to emulated drive Z: - UDEB version \n\n",
       
  1681 	 		"EXPORTUDEB : EXPORTDIRSUDEB",
       
  1682 	);  
       
  1683 	 	   
       
  1684 	my %dirsudeb=%dirsurel;          
       
  1685 	my @expudeb=@expurel;
       
  1686 	foreach (@expudeb){
       
  1687 	         &Output(" \\\n", "\t\$(UDEBx)$_ ");		  
       
  1688 	}
       
  1689 	&Output("\n\nEXPORTDIRSUDEB : ");
       
  1690 	foreach(keys %dirsudeb){
       
  1691 	  		push @dirs, "\$(UDEBx)$dirsudeb{$_}";
       
  1692 	  		&Output(" \\\n", "\t\$(UDEBx)$_ "); 
       
  1693 	  	
       
  1694 	}
       
  1695 	&Output("\n\n");
       
  1696 	foreach (@expudeb){
       
  1697 	 		 &Output( 
       
  1698 					"\$(UDEBx)$_ : \t\$(DATAx)$_ \n",
       
  1699 					"\tcopy \"\$?\" \"\$@\" \n"
       
  1700 			 );
       
  1701 	}			
       
  1702 	&Output("\nEXPORTCLEANUDEB :\n");
       
  1703 	foreach (@expudeb){	
       
  1704 			 &Output("\t-@\$(ERASE) \$(UDEBx)$_ \n"); 
       
  1705 	}  
       
  1706 	&Output("\nEXPORTWHATUDEB :\n");	
       
  1707 	foreach (@expudeb){	
       
  1708 			 &Output("\t\@echo \$(UDEBx)$_ \n"); 	
       
  1709 	}
       
  1710 	
       
  1711     &Output("\n# Directories \n\n");  
       
  1712 	&Output(join (" \\\n", @dirs)." :")       
       
  1713 	&Output("\n\t\@perl -S emkdir.pl \$@\n\n");			
       
  1714 		   		
       
  1715 }
       
  1716 
       
  1717 sub CreatePlatMak ($$$$$$$$$;$) {
       
  1718 	my ($BatchPath, $E32MakePath, $DataRef, $Plat, $RealPlat, $RomDir, $Module, $BldInfPath, $Exports, $Test, $FeatureVariant)=@_;
       
  1719 	$FeatureVariant = "" if (!$FeatureVariant);
       
  1720 
       
  1721 	unless ($Test) {
       
  1722 		$Test='';
       
  1723 	}
       
  1724 	else {
       
  1725 		$Test='TEST';
       
  1726 	}
       
  1727 
       
  1728 	my $Ref;
       
  1729 	my $eDrive=0;
       
  1730 	if ($RealPlat =~ /^WINS/) {
       
  1731 	    foreach $Ref (@$Exports) {
       
  1732 			if ($$Ref{emReleasable}=~/^([A-Z])(\\.*)$/) {
       
  1733 				$eDrive=1;
       
  1734 				last;
       
  1735 			}
       
  1736 		}
       
  1737 	} 
       
  1738 
       
  1739 
       
  1740 	my $OutRomFile="$RomDir$RealPlat$Test.IBY";
       
  1741 	my $GCCDir="gcc\$(PBUILDPID)\\bin";
       
  1742 	
       
  1743 	my $erasedefn = "\@erase";
       
  1744 	$erasedefn = "\@erase 2>>nul" if ($ENV{OS} eq "Windows_NT");
       
  1745 
       
  1746 # Get the root platform name to support hierarchy of customizations	
       
  1747 	my $root = Plat_Root($Plat);
       
  1748 
       
  1749 	my $config_file = "";
       
  1750 
       
  1751 	if (grep /^$root$/i, @BPABIPlats) {
       
  1752 		$config_file = BPABIutl_Config_Path($root);
       
  1753 	}
       
  1754 
       
  1755 	my $rvct_path = "";
       
  1756 
       
  1757 	if ( $config_file ) {
       
  1758 
       
  1759 		if ($root =~ /^ARMV\d/) {
       
  1760 
       
  1761 			unless ( RVCT_plat2set::compiler_exists($Plat) )
       
  1762 			{
       
  1763 				FatalError("Can't find any RVCT installation.");
       
  1764 			}
       
  1765 
       
  1766 			my $rvct_ver = RVCT_plat2set::get_version_string($Plat);
       
  1767 
       
  1768 			if ($Plat =~ "^ARMV5" && $rvct_ver lt "2.2.559")
       
  1769 			{
       
  1770 				warn "BLDMAKE WARNING: ARMV5 requires at least RVCT 2.2.559.";
       
  1771 				OutText();
       
  1772 				return;
       
  1773 			}
       
  1774 
       
  1775 			if ($Plat =~ "^ARMV6" && $rvct_ver lt "2.2.559")
       
  1776 			{
       
  1777 				warn "BLDMAKE WARNING: ARMV6 requires at least RVCT 2.2.559.";
       
  1778 				OutText();
       
  1779 				return;
       
  1780 			}
       
  1781 
       
  1782 			if ($Plat =~ "^ARMV7" && $rvct_ver lt "3.1.674")
       
  1783 			{
       
  1784 				warn "BLDMAKE WARNING: ARMV7 requires at least RVCT 3.1.674.";
       
  1785 				OutText();
       
  1786 				return;
       
  1787 			}
       
  1788 
       
  1789 			my $rvct_bin_name = RVCT_plat2set::get_bin_name($Plat);
       
  1790 			my $rvct_bin_path = RVCT_plat2set::get_bin_path($Plat);
       
  1791 			my $rvct_inc_name = RVCT_plat2set::get_inc_name($Plat);
       
  1792 			my $rvct_inc_path = RVCT_plat2set::get_inc_path($Plat);
       
  1793 			my $rvct_lib_name = RVCT_plat2set::get_lib_name($Plat);
       
  1794 			my $rvct_lib_path = RVCT_plat2set::get_lib_path($Plat);
       
  1795 
       
  1796 			main::Output("export $rvct_bin_name:=$rvct_bin_path\n");
       
  1797 			main::Output("export $rvct_inc_name:=$rvct_inc_path\n");
       
  1798 			main::Output("export $rvct_lib_name:=$rvct_lib_path\n");
       
  1799 
       
  1800 			my ($rvct_M, $rvct_m, $rvct_b) = RVCT_plat2set::get_version_list($Plat);
       
  1801 
       
  1802 			Output( "\n" );
       
  1803 			Output( "export RVCT_VER_MAJOR:=$rvct_M\n" );
       
  1804 			Output( "export RVCT_VER_MINOR:=$rvct_m\n" );
       
  1805 			Output( "export RVCT_VER_BUILD:=$rvct_b\n" );
       
  1806 
       
  1807 			$rvct_path = "\$($rvct_bin_name);"; # Example: '$(RVCT22BIN);'.
       
  1808 		}
       
  1809 
       
  1810 		&Output(
       
  1811 			"\n",
       
  1812 			"export PLAT:=${Plat}\n\n",
       
  1813 			"include $config_file\n\n"
       
  1814 		);
       
  1815 	}
       
  1816 # modified start: makefile improvement 
       
  1817 	unless($FeatureVariant eq "")
       
  1818 	{
       
  1819 # modified by SV start: makefile improvement 
       
  1820 		foreach $Ref (@$DataRef) {
       
  1821 			&Output(
       
  1822 			"include $BatchPath"."FeatureVariantInfo\\".uc($Plat)."\\"."$Plat$FeatureVariant.$$Ref{Base}.info\n\n",
       
  1823 			);
       
  1824 		}
       
  1825 # modified by SV end: makefile improvement 
       
  1826 	}
       
  1827 # modified end: makefile improvement 
       
  1828 	# Don't hardcode the rvct path if rvct auto switch feature is not enabled.
       
  1829 	if ($ENV{ABLD_PLAT_INI}) 
       
  1830 	{
       
  1831 		&Output(
       
  1832 		'export Path:=',&main::Path_Drive,$E32env::Data{EPOCPath},$GCCDir,";", $rvct_path,"\$(Path)\n",
       
  1833 		"export PATH:=\$(Path)\n"
       
  1834 		);
       
  1835 	}
       
  1836 	else
       
  1837 	{
       
  1838 		&Output(
       
  1839 		'export Path:=',&main::Path_Drive,$E32env::Data{EPOCPath},$GCCDir,";", "\$(Path)\n",
       
  1840 		"export PATH:=\$(Path)\n"
       
  1841 		);
       
  1842 	}
       
  1843 
       
  1844 	&Output(		
       
  1845 		"\n",
       
  1846 		"# prevent MAKEFLAGS variable from upsetting calls to NMAKE\n",
       
  1847 		"unexport MAKEFLAGS\n",
       
  1848 		"\n",
       
  1849 		"ERASE = $erasedefn\n",
       
  1850 		"\n",
       
  1851 		"\n",
       
  1852 		"ifdef EFREEZE_ALLOW_REMOVE\n",
       
  1853 		"REMOVEMACRO := EFREEZE_ALLOW_REMOVE=-remove\n",
       
  1854 		"endif\n",
       
  1855 		"\n",
       
  1856 		"\n"
       
  1857 	);
       
  1858 
       
  1859 	if ($eDrive) {
       
  1860 		# Generate exports into emulated drives
       
  1861 		&CreatePlatExports($RealPlat,$Exports);
       
  1862 	}
       
  1863 	my $Command;
       
  1864 	foreach $Command (qw(CLEAN CLEANMAKEFILE CLEANALL FINAL FREEZE LIBRARY MAKEFILE RESOURCE SAVESPACE TARGET LISTING WHATMAKEFILE)) {
       
  1865 		&Output(
       
  1866 			"$Command :"
       
  1867 		);
       
  1868 
       
  1869 			 if ($eDrive and $Command eq 'CLEAN'){
       
  1870 				 &Output(" EXPORTCLEANGENERIC EXPORTCLEAN\$(CFG) ");
       
  1871 				 foreach $Ref (@$DataRef) {
       
  1872 					 &Output(" $Command$$Ref{Base}");
       
  1873 				 }
       
  1874 			 }	    	 
       
  1875 			 elsif ($eDrive and $Command eq 'RESOURCE'){
       
  1876 				 &Output(" EXPORTGENERIC EXPORT\$(CFG) ");
       
  1877 			   	 foreach $Ref (@$DataRef) {
       
  1878 					 &Output(" $Command$$Ref{Base}");
       
  1879 				 }
       
  1880 				 
       
  1881 				 foreach $Ref (@$DataRef) {
       
  1882 					 &Output("\n\nRESOURCE$$Ref{Base} : EXPORTGENERIC EXPORT\$(CFG)");
       
  1883 				 }
       
  1884 			  }
       
  1885 			  else {
       
  1886 			        if(@$DataRef){
       
  1887 			        	foreach $Ref (@$DataRef) {
       
  1888 			        		&Output(" $Command$$Ref{Base}");
       
  1889 			           }
       
  1890 			          } 		
       
  1891 			         else {
       
  1892 			         	&Output("\n","\t\@echo Nothing to do\n");
       
  1893 			         }
       
  1894 			  }  
       
  1895 		&Output("\n","\n");
       
  1896 	}
       
  1897 	
       
  1898 	&Output(
       
  1899 		"WHAT :"
       
  1900 	);
       
  1901 	if($eDrive){
       
  1902 	  &Output(" EXPORTWHATGENERIC EXPORTWHAT\$(CFG) ");
       
  1903 	}
       
  1904 	my $whatcount=0;
       
  1905 	foreach $Ref (@$DataRef) {
       
  1906 		unless ($$Ref{Tidy}) {
       
  1907 			$whatcount++;
       
  1908 			&Output(
       
  1909 				" WHAT$$Ref{Base}"
       
  1910 			);
       
  1911 		}
       
  1912 	}
       
  1913 	if ($whatcount==0 and !$eDrive) {
       
  1914 		&Output(
       
  1915 			"\n",
       
  1916 			"\t\@rem do nothing\n" 
       
  1917 		);
       
  1918 	}
       
  1919 
       
  1920 	&Output(
       
  1921 		"\n",
       
  1922 		"\n",
       
  1923 		"CHECKSOURCE :"
       
  1924 	);
       
  1925 	my $CheckSource=' CHECKSOURCE_GENERIC';
       
  1926 	foreach $Ref (@$DataRef) {
       
  1927 		$CheckSource.=" CHECKSOURCE$$Ref{Base}" if ($$Ref{Ext} eq ".MMP");
       
  1928 	}
       
  1929 	&Output(
       
  1930 		"$CheckSource\n"
       
  1931 	);
       
  1932 
       
  1933 	&Output(
       
  1934 		"\n",
       
  1935 		"CHECKSOURCE_GENERIC :\n"
       
  1936 	);
       
  1937 
       
  1938 	if ($CheckSourceBldInfIncludes{$Plat})
       
  1939 		{
       
  1940 		my %dummy;
       
  1941 		$dummy{$CheckSourceBldInfIncludes{$Plat}} = 1;
       
  1942 		&Output (CheckSource_MakefileOutput(%dummy));		
       
  1943 		}
       
  1944 
       
  1945 	&Output (CheckSource_MakefileOutput(%CheckSourceMMPFILESMetaData));
       
  1946 	&Output (CheckSource_MakefileOutput(%CheckSourceEXTENSIONSMetaData));
       
  1947 	
       
  1948 	&Output(
       
  1949 		"\n",
       
  1950 		"\n",
       
  1951 		"TIDY :"
       
  1952 	);
       
  1953 	my $Tidy='';
       
  1954 	foreach $Ref (@$DataRef) {
       
  1955 		if ($$Ref{Tidy}) {
       
  1956 			$Tidy.=" TIDY$$Ref{Base}";
       
  1957 		}
       
  1958 	}
       
  1959 	if ($Tidy) {
       
  1960 		&Output(
       
  1961 			"$Tidy\n"
       
  1962 		);
       
  1963 	}
       
  1964 	else {
       
  1965 		&Output(
       
  1966 			"\n",
       
  1967 			"\t\@echo Nothing to do\n"
       
  1968 		);
       
  1969 	}
       
  1970 	&Output(
       
  1971 		"\n",
       
  1972 		"\n"
       
  1973 	);
       
  1974 #	change for non-EPOC platforms
       
  1975 	if ($RealPlat=~/^(WINS|WINSCW|WINC|TOOLS|TOOLS2)$/o) {
       
  1976 		&Output(
       
  1977 			"ROMFILE :\n"
       
  1978 		);
       
  1979 	}
       
  1980 	else {
       
  1981 		&Output(
       
  1982 			'ROMFILE : STARTROMFILE'
       
  1983 		);
       
  1984 		foreach $Ref (@$DataRef) {
       
  1985 			&Output(
       
  1986 				" ROMFILE$$Ref{Base}"
       
  1987 			);
       
  1988 		}
       
  1989 		&Output(
       
  1990 			"\n",
       
  1991 			"\n",
       
  1992 			"STARTROMFILE :\n",
       
  1993 			    "\t\@perl -S emkdir.pl \"", &Path_Chop($RomDir), "\"\n",
       
  1994 			    "\t\@echo // $OutRomFile > $OutRomFile\n",
       
  1995 			    "\t\@echo // >> $OutRomFile\n"
       
  1996 		);
       
  1997 		if ($Test) {
       
  1998 			my ($Auto, $Manual);
       
  1999 			foreach $Ref (@$DataRef) {
       
  2000 				++$Auto unless ($$Ref{Manual} or $$Ref{Support});
       
  2001 				++$Manual if ($$Ref{Manual});
       
  2002 			}
       
  2003 			if ($Auto) {
       
  2004 				my $IbyTextFrom="data=$BatchPath$Plat.AUTO.BAT";
       
  2005 				my $IbyTextTo="Test\\$Module.AUTO.BAT";
       
  2006 				my $Spaces= 60>length($IbyTextFrom) ? 60-length($IbyTextFrom) : 1; 
       
  2007 				&Output("\t\@echo ", $IbyTextFrom, ' 'x$Spaces, $IbyTextTo, ">> $OutRomFile\n");
       
  2008 			}
       
  2009 			if ($Manual) {
       
  2010 				my $IbyTextFrom="data=$BatchPath$Plat.MANUAL.BAT";
       
  2011 				my $IbyTextTo="Test\\$Module.MANUAL.BAT";
       
  2012 				my $Spaces= 60>length($IbyTextFrom) ? 60-length($IbyTextFrom) : 1; 
       
  2013 				&Output("\t\@echo ", $IbyTextFrom, ' 'x$Spaces, $IbyTextTo, ">> $OutRomFile\n");
       
  2014 			}
       
  2015 		}
       
  2016 	}
       
  2017 	&Output(
       
  2018 		"\n",
       
  2019 		"\n"
       
  2020 	);
       
  2021 	my $CallNmake='nmake -nologo -x - $(VERBOSE) $(KEEPGOING)';
       
  2022 	my $CallGNUmake='$(MAKE) $(VERBOSE) $(KEEPGOING)';
       
  2023 
       
  2024 	my %PlatHash;
       
  2025 	&Plat_GetL($RealPlat, \%PlatHash);
       
  2026 	my $CallMake=$CallNmake;
       
  2027 	if ($PlatHash{MakeCmd} eq "make") {
       
  2028 		$CallMake="$CallGNUmake -r";
       
  2029 	}
       
  2030 	&Plat_GetL($Plat, \%PlatHash);
       
  2031 	
       
  2032 	foreach $Ref (@$DataRef) {
       
  2033 
       
  2034 #		standard commands
       
  2035 		unless ($$Ref{Makefile}) {
       
  2036 			my $MakefilePath=join('', &Path_Chop($E32MakePath), $BldInfPath, $$Ref{Base}, "\\", $RealPlat, "\\");
       
  2037 # modified start: makefile improvement 
       
  2038 			my $RealMakefile;
       
  2039 			if($FeatureVariant eq "")
       
  2040 			{
       
  2041 				$RealMakefile="-f \"$MakefilePath$$Ref{Base}.$RealPlat$FeatureVariant\"";
       
  2042 			}
       
  2043 			else{
       
  2044 				$RealMakefile="-f \"$MakefilePath$$Ref{Base}.$RealPlat.\$(VARIANT_PLAT_NAME_$$Ref{Base})\"";
       
  2045 			}
       
  2046 # modified end: makefile improvement 
       
  2047 			my $MakefileBase="$MakefilePath$$Ref{Base}";		
       
  2048 
       
  2049 			if($Plat eq 'VS6' || $Plat eq 'VS2003')
       
  2050 			{
       
  2051 				$CallMake .= "-f ";
       
  2052 				$RealMakefile = "$MakefileBase$PlatHash{Ext}";
       
  2053 			}
       
  2054 			&Output(
       
  2055 				"MAKEFILE$$Ref{Base}_FILES= \\\n",
       
  2056 					"\t\"$MakefileBase$PlatHash{Ext}$FeatureVariant\"",
       
  2057 			);
       
  2058 #			changes for WINS/WINSCW/WINC and VC6
       
  2059 			if ($Plat =~ /^VC6/) {
       
  2060 				&Output(
       
  2061 					" \\\n\t\"$MakefileBase.DSW\"",
       
  2062 					" \\\n\t\"$MakefileBase.SUP.MAKE\""
       
  2063 				);
       
  2064 			}
       
  2065 			if ($Plat eq 'CW_IDE') {
       
  2066 				&Output(
       
  2067 					" \\\n\t\"$MakefileBase.pref\""		# Defect: actually uses $BaseTrg, not mmp file name
       
  2068 				);
       
  2069 			}
       
  2070 			if ($RealPlat=~/^(WINS|WINSCW|WINC)$/o) {
       
  2071 				&Output(
       
  2072 					" \\\n\t\"$MakefileBase.UID.CPP\""	# Defect: actually uses $BaseTrg, not mmp file name
       
  2073 				);
       
  2074 			}
       
  2075 			
       
  2076   			my $bld_flags="";
       
  2077 			$bld_flags="\$(ABLD_FLAGS)" if (($Plat =~ /^ARMV5(_ABIV1)?$/ || grep /$Plat/i, @BPABIPlats) || (Plat_Root($Plat) =~ /^ARMV5(_ABIV1)?$/ || grep /$Plat/i, @BPABIPlats));
       
  2078 			
       
  2079 			
       
  2080 			my $build_as_arm_arg="";
       
  2081 			$build_as_arm_arg = $$Ref{BuildAsARM} if ($$Ref{BuildAsARM});
       
  2082 
       
  2083 			# Compiler Wrapper option Support  
       
  2084 			# Generate the flag to keep the Compiler Wrapper option information
       
  2085 			my $cmp_wrap_flag="";
       
  2086 			if (($Plat =~ /^ARMV5(_ABIV1)?$/ || grep /$Plat/i, @BPABIPlats) || ($Plat=~/^WINSCW$/) || (Plat_Root($Plat) =~ /^ARMV5(_ABIV1)?$/ || grep /$Plat/i, @BPABIPlats))
       
  2087 			{
       
  2088 				# for armv5 , armv5_abiv1, winscw and all bpabi plaforms
       
  2089 				$cmp_wrap_flag="\$(ABLD_COMPWRAP_FLAG)" ;
       
  2090 			}
       
  2091 
       
  2092 			&Output(
       
  2093 				"\n",
       
  2094 				"\n",
       
  2095 				"MAKEFILE$$Ref{Base} :\n",
       
  2096 				    "\tperl -S makmake.pl \$(NO_DEPENDENCIES) -D $$Ref{Path}$$Ref{Base} $Plat$FeatureVariant $build_as_arm_arg $bld_flags $cmp_wrap_flag\n",
       
  2097 
       
  2098 				"\n",
       
  2099 				"CLEANMAKEFILE$$Ref{Base} :\n",
       
  2100 				    "\t-\$(ERASE) \$(MAKEFILE$$Ref{Base}_FILES)\n",
       
  2101 				"\n",
       
  2102 				"WHATMAKEFILE$$Ref{Base} :\n",
       
  2103 				    "\t\@echo \$(MAKEFILE$$Ref{Base}_FILES)\n",
       
  2104 				"\n",
       
  2105 				"TARGET$$Ref{Base} :\n",
       
  2106 				    "\t$CallMake $RealMakefile \$(CFG)\n",
       
  2107 				"\n",
       
  2108 				"SAVESPACE$$Ref{Base} :\n",
       
  2109 				    "\t$CallMake $RealMakefile \$(CFG) CLEANBUILD\$(CFG)\n",
       
  2110 				"\n",
       
  2111 				"LISTING$$Ref{Base} :\n",
       
  2112 				    "\t$CallMake $RealMakefile MAKEWORK\$(CFG) LISTING\$(CFG)\$(SOURCE)\n",
       
  2113 				"\n",
       
  2114 				"FINAL$$Ref{Base} :\n",
       
  2115 				    "\t\@rem do nothing\n",
       
  2116 				"\n",
       
  2117 			);
       
  2118 			foreach $Command (qw(CLEANALL)) {
       
  2119 				&Output(
       
  2120 					"CLEANALL$$Ref{Base} :\n",
       
  2121 					"\tperl -S ermdir.pl $MakefilePath\n",
       
  2122 					"\n",
       
  2123 				);
       
  2124 			}
       
  2125 			foreach $Command (qw(CLEAN RESOURCE)) {
       
  2126 				&Output(
       
  2127 					"$Command$$Ref{Base} :\n",
       
  2128 					    "\t$CallMake $RealMakefile $Command\$(CFG)\n",
       
  2129 					"\n"
       
  2130 				);
       
  2131 			}
       
  2132 			foreach $Command (qw(LIBRARY)) {
       
  2133 				&Output(
       
  2134 					"$Command$$Ref{Base} :\n",
       
  2135 					    "\t$CallMake $RealMakefile $Command\n",
       
  2136 					"\n"
       
  2137 				);
       
  2138 			}
       
  2139 			foreach $Command (qw(FREEZE)) {
       
  2140 				&Output(
       
  2141 					"$Command$$Ref{Base} :\n",
       
  2142 					    "\t$CallMake $RealMakefile $Command \$(REMOVEMACRO)\n",
       
  2143 					"\n"
       
  2144 				);
       
  2145 			}
       
  2146 			unless ($$Ref{Tidy}) {
       
  2147 				&Output(
       
  2148 					"WHAT$$Ref{Base} :\n",
       
  2149 					    "\t\@$CallMake -s $RealMakefile WHAT\$(CFG)\n",
       
  2150 					"\n"
       
  2151 				);
       
  2152 			}
       
  2153 			else {
       
  2154 				&Output(
       
  2155 					"TIDY$$Ref{Base} :\n",
       
  2156 					    "\t$CallMake $RealMakefile CLEANRELEASE CLEANLIBRARY\n",
       
  2157 					"\n"
       
  2158 				);
       
  2159 			}
       
  2160 			
       
  2161 			&Output(
       
  2162 				"CHECKSOURCE$$Ref{Base} :\n",
       
  2163 					"\t\@$CallMake -s $RealMakefile CHECKSOURCE\n",
       
  2164 					"\t\@$CallMake -s $RealMakefile CHECKSOURCE\$(CFG)\n",
       
  2165 				"\n"
       
  2166 				);
       
  2167 			&Output(
       
  2168 				"ROMFILE$$Ref{Base} :\n",
       
  2169 				    "\t\@$CallMake $RealMakefile ROMFILE >> $OutRomFile\n",
       
  2170 				"\n",
       
  2171 				"\n"
       
  2172 			);
       
  2173 		}
       
  2174 
       
  2175 #		calls to custom makefiles
       
  2176 		else {
       
  2177 			my $ChopRefPath=&Path_Chop($$Ref{Path});
       
  2178 			my $ChopBldInfPath=&Path_Chop($BldInfPath);
       
  2179 			my $MakefileCall;
       
  2180 			if ($$Ref{Makefile}==2) {
       
  2181 				$MakefileCall="cd $ChopRefPath;$CallNmake";
       
  2182 			} else {
       
  2183 				$MakefileCall="$CallGNUmake -C $ChopRefPath";
       
  2184 			}
       
  2185 			$MakefileCall.=" -f \"$$Ref{Base}$$Ref{Ext}\" TO_ROOT=";
       
  2186 			$MakefileCall.=&Path_Chop(&Path_UpToRoot($$Ref{Path}));
       
  2187 			$MakefileCall.=" EPOCBLD=";
       
  2188 			$MakefileCall.=join('', &Path_Chop(&Path_UpToRoot($$Ref{Path})), &Path_Chop($E32MakePath), $BldInfPath, $$Ref{Base}, "\\", $RealPlat);
       
  2189 			$MakefileCall.=" TO_BLDINF=";
       
  2190 			$MakefileCall.=join('', &Path_Chop(&Path_UpToRoot($$Ref{Path})), $ChopBldInfPath);
       
  2191 			if ($$Ref{ExtensionRoot}) {
       
  2192 				$MakefileCall.=" EXTENSION_ROOT=".&Path_Chop($$Ref{ExtensionRoot});
       
  2193 			}
       
  2194 			if ($$Ref{BuildAsARM}) {
       
  2195 			  $MakefileCall.=" BUILD_AS_ARM=1";
       
  2196 			}			  
       
  2197 			&Output(
       
  2198 # should change to MAKEFILE
       
  2199 				"MAKEFILE$$Ref{Base} :\n",
       
  2200 				    "\t$MakefileCall PLATFORM=$Plat MAKMAKE\n",
       
  2201 				"\n",
       
  2202 # should call in custom makefiles maybe
       
  2203 				"CLEANMAKEFILE$$Ref{Base} :\n",
       
  2204 				"#	$MakefileCall PLATFORM=$Plat CLEANMAKEFILE\n",
       
  2205 				"\n",
       
  2206 				"WHATMAKEFILE$$Ref{Base} :\n",
       
  2207 				"#	\@$MakefileCall -s PLATFORM=$Plat WHATMAKEFILE\n",
       
  2208 				"\n",
       
  2209 # should change to TARGET
       
  2210 				"TARGET$$Ref{Base} :\n",
       
  2211 				    "\t$MakefileCall PLATFORM=$RealPlat CFG=\$(CFG) BLD\n",
       
  2212 				"\n",
       
  2213 # should ignore this target and just call the TARGET target instead?
       
  2214 				"SAVESPACE$$Ref{Base} :\n",
       
  2215 				    "\t$MakefileCall PLATFORM=$RealPlat CFG=\$(CFG) SAVESPACE\n",
       
  2216 				"\n",
       
  2217 				"LISTING$$Ref{Base} :\n",
       
  2218 				"\n",
       
  2219 				"\n",
       
  2220 # should change to LIBRARY
       
  2221 				"LIBRARY$$Ref{Base} :\n",
       
  2222 				    "\t$MakefileCall PLATFORM=$RealPlat LIB\n",
       
  2223 				"\n",
       
  2224 				"FREEZE$$Ref{Base} :\n",
       
  2225 					"\t$MakefileCall PLATFORM=$RealPlat FREEZE \$(REMOVEMACRO)\n",
       
  2226 				"\n",
       
  2227 			);
       
  2228 
       
  2229 			foreach $Command (qw(CLEANALL)) {
       
  2230 				&Output(
       
  2231 					"$Command$$Ref{Base} :\n",
       
  2232 					"\t$MakefileCall PLATFORM=$RealPlat CFG=\$(CFG) CLEAN\n",
       
  2233 					"\n"
       
  2234 				);
       
  2235 			}
       
  2236 
       
  2237 			foreach $Command (qw(CLEAN RESOURCE FINAL)) {
       
  2238 				&Output(
       
  2239 					"$Command$$Ref{Base} :\n",
       
  2240 					    "\t$MakefileCall PLATFORM=$RealPlat CFG=\$(CFG) $Command\n",
       
  2241 					"\n"
       
  2242 				);
       
  2243 			}
       
  2244 			unless ($$Ref{Tidy}) {
       
  2245 # should change to WHAT
       
  2246 				&Output(
       
  2247 					"WHAT$$Ref{Base} :\n",
       
  2248 					    "\t\@$MakefileCall -s PLATFORM=$RealPlat CFG=\$(CFG) RELEASABLES\n",
       
  2249 					"\n"
       
  2250 				);
       
  2251 			}
       
  2252 			else {
       
  2253 				&Output(
       
  2254 					"TIDY$$Ref{Base} :\n",
       
  2255 					    "\t$MakefileCall PLATFORM=$RealPlat TIDY\n",
       
  2256 # should change to CLEANLIBRARY
       
  2257 					    "\t$MakefileCall CLEANLIB\n",
       
  2258 					"\n"
       
  2259 				);
       
  2260 			}
       
  2261 			&Output(
       
  2262 				"ROMFILE$$Ref{Base} :\n",
       
  2263 				    "\t\@$MakefileCall PLATFORM=$RealPlat ROMFILE >> $OutRomFile\n",
       
  2264 				"\n",
       
  2265 				"\n"
       
  2266 			);
       
  2267 		}
       
  2268 
       
  2269 	}
       
  2270 	
       
  2271 	&WriteOutFileL("$BatchPath$Plat$FeatureVariant$Test.MAKE");
       
  2272 }
       
  2273 
       
  2274 sub CreatePlatBatches ($$$) {
       
  2275 	my ($OutDir, $DataRef, $Plat)=@_;
       
  2276 
       
  2277 #	create the test batch files
       
  2278 #	this function won't work properly if the target basename is different from the .MMP basename
       
  2279 #	so perhaps it should call makmake on the .mmp file to check
       
  2280 
       
  2281 	my $AutoText;
       
  2282 	my $ManualText;
       
  2283 
       
  2284 	my $Ref;
       
  2285 	foreach $Ref (@$DataRef) {
       
  2286 		if ($$Ref{Manual}) {
       
  2287 			$ManualText.="$$Ref{Base}\n";
       
  2288 			next;
       
  2289 		}
       
  2290 		if ($$Ref{Ext} eq ".MK") {
       
  2291 			next;
       
  2292 		}
       
  2293 		if ($$Ref{Support}) {
       
  2294 			next;
       
  2295 		}
       
  2296 		else {
       
  2297 			$AutoText.="$$Ref{Base}\n";
       
  2298 		}
       
  2299 	}
       
  2300 
       
  2301 	if ($AutoText) {
       
  2302 		&Output($AutoText);
       
  2303 		&WriteOutFileL("$OutDir$Plat.AUTO.BAT");
       
  2304 	}
       
  2305 
       
  2306 	if ($ManualText) {
       
  2307 		&Output($ManualText);
       
  2308 		&WriteOutFileL("$OutDir$Plat.MANUAL.BAT");
       
  2309 	}
       
  2310 }
       
  2311 
       
  2312 sub WriteOutFileL ($$) { # takes batch file and boolean read-only flag
       
  2313 	my ($BATFILE, $ReadOnly)=@_;
       
  2314 
       
  2315 	$BATFILE=~ s/\//\\/g;  # convert unix slashes from wrappermakefile.pm
       
  2316 
       
  2317 	eval { &Path_MakePathL($BATFILE); };
       
  2318 	&FatalError($@) if $@;
       
  2319 
       
  2320 	open BATFILE,">$BATFILE" or &FatalError("Can't open or create Batch File \"$BATFILE\"");
       
  2321 	print BATFILE &OutText or &FatalError("Can't write output to Batch File \"$BATFILE\"");
       
  2322 	close BATFILE or &FatalError("Can't close Batch File \"$BATFILE\"");
       
  2323 }
       
  2324 
       
  2325