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