sbsv1_os/e32toolp/makmake/makmake.pl
changeset 0 83f4b4db085c
child 1 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 
       
    21 use FindBin;		# for FindBin::Bin
       
    22 use Getopt::Long;
       
    23 use Cwd;
       
    24 use strict;
       
    25 # modified start: makefile improvement 
       
    26 use File::stat;
       
    27 use Time::localtime;
       
    28 # modified end: makefile improvement 
       
    29 
       
    30 my $PerlLibPath;    # fully qualified pathname of the directory containing our Perl modules
       
    31 
       
    32 # Prototype to remove warning.
       
    33 sub AddStringTables();
       
    34 
       
    35 BEGIN {
       
    36 # check user has a version of perl that will cope
       
    37 	require 5.005_03;
       
    38 # establish the path to the Perl libraries: currently the same directory as this script
       
    39 	$PerlLibPath = $FindBin::Bin;	# X:/epoc32/tools
       
    40 	$PerlLibPath =~ s/\//\\/g;	# X:\epoc32\tools
       
    41 	$PerlLibPath .= "\\";
       
    42 }
       
    43 
       
    44 use lib $PerlLibPath;
       
    45 use E32env;
       
    46 use E32Plat;
       
    47 use E32Variant;
       
    48 use Genutl;
       
    49 use Modload;
       
    50 use Pathutl;
       
    51 use Trgtype;
       
    52 use CheckSource;
       
    53 use featurevariantparser;
       
    54 use featurevariantmap;
       
    55 
       
    56 # THE MAIN PROGRAM SECTION
       
    57 ##########################
       
    58 
       
    59 {
       
    60 	Load_SetModulePath($PerlLibPath);
       
    61 	Plat_Init($PerlLibPath);
       
    62 }
       
    63 
       
    64 my $MAKEFILE;
       
    65 my $MMPFILE;
       
    66 my %Options;
       
    67 my %Plat;
       
    68 my %TruePlat;
       
    69 my %BldMacros;
       
    70 my $PlatArg;
       
    71 my @PlatOverrideList=();
       
    72 my $EABIDef;
       
    73 my $DebugSwitch=undef;
       
    74 
       
    75 my $IsCompilerWrapperOption = 0;
       
    76 my $IsProxyWrapperOption = 0;
       
    77 my $FeatureVariantArg;
       
    78 my %FeatureVariantInfo;
       
    79 
       
    80 {
       
    81 	# process the command line
       
    82 	unless (GetOptions(\%Options, 'd', 'mmp', 'plat=s', 'v', 'arm', 'nd' , 'ithumb' , 'iarm' , 'debug', 'no_debug', 'logfc','wrap:s')) {
       
    83 		exit 1;
       
    84 	}
       
    85 	#Update the variable to set the information of -wrap option
       
    86 	if(exists($Options{wrap})) {
       
    87 		if ($Options{wrap} eq "") {
       
    88 			# Set the Compiler wrapper option information i.e. '1'
       
    89 			$IsCompilerWrapperOption = 1;
       
    90 		} elsif ($Options{wrap} eq "proxy") {
       
    91 			$IsProxyWrapperOption = 1;
       
    92 		} else {
       
    93 			print "WARNING: Invalid value for option -wrap: $Options{wrap}\n";
       
    94 		}
       
    95 	}
       
    96 	
       
    97 	$Options{makemakefile}='1' unless ($Options{mmp} || $Options{plat});
       
    98 
       
    99 	if ($Options{mmp} or $Options{plat}) {
       
   100 		eval { &Load_ModuleL('MAKHELP'); };
       
   101 		die $@ if $@;
       
   102 	}
       
   103 
       
   104 	if ($Options{mmp}) {
       
   105 		&Help_Mmp;
       
   106 		exit;
       
   107 	}
       
   108 
       
   109 	if ($Options{plat}) {
       
   110 		eval { &Plat_GetL($Options{plat},\%Plat,\%BldMacros); };
       
   111 		die $@ if $@;
       
   112 		eval { &Load_ModuleL($Plat{MakeMod}); };
       
   113 		die $@ if $@;
       
   114 		&Help_Plat($Plat{Real},$Plat{CPU}, $Plat{DefFile}, \@{$Plat{MmpMacros}},\@{$Plat{Macros}});
       
   115 		exit;
       
   116 	}
       
   117 
       
   118 #	show help & exit if necessary
       
   119 	if (@ARGV != 2) {
       
   120 		&Usage();
       
   121 	}
       
   122 	if ($Options{v}) {
       
   123 		print "perl -S makmake.pl @ARGV\n";
       
   124 		&Load_SetVerbose;
       
   125 		&Path_SetVerbose;
       
   126 		&Plat_SetVerbose;
       
   127 	}
       
   128 
       
   129 	$PlatArg=uc pop @ARGV;
       
   130 
       
   131 	# Process build platform arguments where they differ from the "norm"
       
   132 	if ($PlatArg=~/^(\S+)\.(\S+)$/)
       
   133 		{
       
   134 		# Explicit feature variant platforms take the form <base platform>.<variant name>
       
   135 		# e.g. armv5.variant1
       
   136 		$PlatArg=$1;
       
   137 		$FeatureVariantArg=$2;
       
   138 		}
       
   139 	elsif ($PlatArg=~/^(\S+):(\S+)$/)
       
   140 		{
       
   141 		# IDE platforms can take the form cw_ide:<platform-1>+<platform-2>+<platform-n>
       
   142 		# e.g. cw_ide:plat1+plat2+plat3
       
   143 		# 			
       
   144 		$PlatArg=$1;
       
   145 		@PlatOverrideList=split(/\+/,$2);
       
   146 		}
       
   147 
       
   148 	eval { &Plat_GetL($PlatArg,\%TruePlat,\%BldMacros); };
       
   149 	die $@ if $@;
       
   150 	if (scalar @PlatOverrideList) {
       
   151 		$PlatArg=$PlatOverrideList[0];
       
   152 	}
       
   153 
       
   154 	
       
   155 	$MMPFILE=pop @ARGV;
       
   156 	die "ERROR: Can't specify MMP file on a different drive\n" if $MMPFILE=~/^\w:\\/o;
       
   157 	if ($MMPFILE!~/.MMP$/io) {
       
   158 		$MMPFILE.='.MMP';
       
   159 	}
       
   160 	$MMPFILE=&Path_AbsToWork($MMPFILE);
       
   161 
       
   162 	eval { &Load_ModuleL('Mmp'); };
       
   163 	die $@ if $@;
       
   164 	if ($Options{v}) {
       
   165 		&Mmp_SetVerbose;
       
   166 	}
       
   167 	if ($Options{d}) {
       
   168 		die "ERROR: $E32env::Data{EPOCPath} does not exist\n" if (!-d $E32env::Data{EPOCPath});
       
   169 	}
       
   170 	
       
   171 	if ($Options{debug}) {
       
   172 		$DebugSwitch = 1;
       
   173 	}
       
   174 	elsif($Options{no_debug}){
       
   175 		$DebugSwitch = 0;
       
   176 	}
       
   177 }
       
   178 
       
   179 my %LinkerOptions;
       
   180 my %WarningLevel;
       
   181 my $ABI;
       
   182 my @AifStruct;
       
   183 my $AllowDllData;
       
   184 my $CompressTarget;
       
   185 my $CompressTargetMode;   #NONE
       
   186 my $ASSPExports;
       
   187 my @ASSPLibList;
       
   188 my @BitMapStruct;
       
   189 my $BuildAsARM=$Options{arm};
       
   190 my $CallDllEntryPoints;
       
   191 my $Capability;
       
   192 my @CapabilityFlags;
       
   193 my $DataLinkAddress;
       
   194 my @DebugLibList;
       
   195 my %Def;
       
   196 my %DocHash;
       
   197 my $ExportUnfrozen;
       
   198 my $FirstLib;
       
   199 my $FixedProcess;
       
   200 my %HeapSize;
       
   201 my @LibList;
       
   202 my $LinkAs;
       
   203 my $LinkAsBase;
       
   204 my $ExportLibrary;
       
   205 my $NoExportLibrary;
       
   206 my %MmpFlag;
       
   207 my @PlatTxt2D;
       
   208 my $ProcessPriority;
       
   209 my @RamTargets;
       
   210 my @ResourceStruct;
       
   211 my @RomTargets;
       
   212 my $SmpSafe;
       
   213 my @SourceStruct;
       
   214 my $StackSize;
       
   215 my @StatLibList;    
       
   216 my $StdCpp;
       
   217 my $NoStdCpp;
       
   218 my $NewLib;
       
   219 my @SysIncPaths;
       
   220 my @ResourceSysIncPaths;
       
   221 my $ResourceVariantMacroHRHFile;
       
   222 my $Trg;
       
   223 my %TrgType;
       
   224 my @UidList;
       
   225 my @UserIncPaths;
       
   226 my $SrcDbg;
       
   227 my %Path;
       
   228 my %Version;
       
   229 my $SecureId;
       
   230 my $VendorId;
       
   231 my $variantMacroHRHFile = Variant_GetMacroHRHFile();  # HRH file containing macros specific to a variant
       
   232 my %ReplaceOptions;
       
   233 my $ARMFPU;
       
   234 my @StringTable;
       
   235 my @StringTableUserIncPaths;
       
   236 my $CodePagingTargetMode;	# 0-N/A, 1-UNPAGED, 2-PAGED
       
   237 my $DataPagingTargetMode;	# 0-N/A, 1-UNPAGED, 2-PAGED
       
   238 my %CheckSourceUDEBIncludes;
       
   239 my %CheckSourceURELIncludes;
       
   240 my %CheckSourceMMPMetaData;
       
   241 my %CheckSourceMMPIncludes;
       
   242 my $IsWideCharMain=0;
       
   243 my $IsDebuggable; # 0-NONDEBUGGABLE, 1-DEBUGGABLE, 2-DEBUGGABLE_UDEBONLY
       
   244 
       
   245 
       
   246 use constant NOTPAGED => 0;
       
   247 use constant UNPAGED => 1;
       
   248 use constant PAGED => 2;
       
   249 
       
   250 use constant INFLATECOMPRESSIONMETHOD => 1;
       
   251 use constant BYTEPAIRCOMPRESSIONMETHOD => 2;
       
   252 
       
   253 use constant NOTDEBUGGABLE => 0;
       
   254 use constant DEBUGGABLE =>  1;
       
   255 use constant DEBUGGABLE_UDEBONLY => 2;
       
   256 
       
   257 # If the platform does support feature variants but none are specified, then we assume the use of "DEFAULT" if it exists
       
   258 # If default doesn't exist feature variantion is basically disabled?
       
   259 $FeatureVariantArg = 'default' if (!$FeatureVariantArg && defined &PMSupportsFeatureVariants && featurevariantparser->DefaultExists());
       
   260 
       
   261 # Preload the details of the variant requested if any - we need the HRH file for MMP file processing
       
   262 if ($FeatureVariantArg)
       
   263 	{
       
   264 	# First check the feature variant is valid
       
   265 	my @buildableFeatureVariants = featurevariantparser->GetBuildableFeatureVariants();
       
   266 	die "ERROR: \"$PlatArg.$FeatureVariantArg\" feature variant is either invalid or virtual.\n" if !(grep /^$FeatureVariantArg$/i, @buildableFeatureVariants);
       
   267 
       
   268 	# Now load the variant
       
   269 	%FeatureVariantInfo = featurevariantparser->GetVariant($FeatureVariantArg);
       
   270 	
       
   271 	# Change the HRH file to use
       
   272 	$variantMacroHRHFile = $FeatureVariantInfo{VARIANT_HRH} if $FeatureVariantInfo{VARIANT_HRH};
       
   273 	}
       
   274 	
       
   275 &SetVarsFromMmp($PlatArg);
       
   276 die $@ if $@;
       
   277 
       
   278 {
       
   279 	# set up the makefile filepath - need to do this before loading the platform module
       
   280 	# because UID source file will be added and set up in the makefile path under WINS
       
   281 	if ($Options{d}) {
       
   282 		$MAKEFILE=join ('', $Path{Bld}, &Path_Split('Base',$MMPFILE), $TruePlat{Ext});
       
   283 	}
       
   284 	else {
       
   285 		$MAKEFILE=join "", &Path_WorkPath, &Path_Split('Base',$MMPFILE), $TruePlat{Ext};
       
   286 	}
       
   287 }
       
   288 
       
   289 {
       
   290 	# Generate an X86GCC def file from eabi def file in build dir if needed
       
   291 	if (($PlatArg eq "X86GCC" || $PlatArg eq "X86GMP") && $Def{Base} && not -e &DefFile)
       
   292 	{
       
   293 		# Find the equivalent eabi def file
       
   294 		my $eabiDefFile = File::Spec->canonpath("$Def{Path}../eabi/$Def{Base}$Def{Ext}");
       
   295 		if (-e $eabiDefFile)
       
   296 		{
       
   297 			# Need to create MAKEFILE directory early in this case
       
   298 			eval { &Path_MakePathL($MAKEFILE); };
       
   299 			die $@ if $@;
       
   300 			# Change def file path to build path 
       
   301 			$Def{Path} = $Path{Bld};
       
   302 			&generateX86GCCDefFile($eabiDefFile, &DefFile);
       
   303 		}
       
   304 		else
       
   305 		{
       
   306 			print "WARNING: Unable to find EABI def file at $eabiDefFile to generate X86GCC def file with\n";
       
   307 		}
       
   308 	}
       
   309 }
       
   310 
       
   311 {
       
   312 
       
   313 
       
   314 #	load the platform module
       
   315 	eval { &Load_ModuleL($TruePlat{MakeMod}); };
       
   316 	die $@ if $@;
       
   317 
       
   318 	unless (defined &PMHelp_Mmp) {
       
   319 #		check this function is defined - all modules must have it - if not perhaps the
       
   320 #		platform module has not loaded is compiler module successfully via "use"
       
   321 		die "ERROR: Module \"$Plat{MakeMod}\" not loaded successfully\n";
       
   322 	}
       
   323 }
       
   324 
       
   325 	# Allow the platform to bow out if feature variants have been specified but it doesn't support them
       
   326 	if ($FeatureVariantArg && !defined &PMSupportsFeatureVariants)
       
   327 		{
       
   328 		die "ERROR: The \"$PlatArg\" platform does not support feature variants.\n";
       
   329 		}
       
   330 
       
   331 {
       
   332 	# allow the platform to bow out if it can't support some .MMP file specifications
       
   333 	if (defined &PMCheckPlatformL) {
       
   334 		eval { &PMCheckPlatformL(); };
       
   335 		die $@ if $@;
       
   336 	}
       
   337 }
       
   338 
       
   339 my @StdIncPaths=();
       
   340 
       
   341 {
       
   342 	# get the platform module to do it's mmpfile processing - WINS modules may set up an extra source file
       
   343 	# for UIDs here depending upon the targettype
       
   344 	&PMPlatProcessMmp(@PlatTxt2D) if defined &PMPlatProcessMmp;
       
   345 }
       
   346 
       
   347 %CheckSourceMMPMetaData = &Mmp_CheckSourceMMPMetaData();
       
   348 %CheckSourceMMPIncludes = &Mmp_CheckSourceMMPIncludes();
       
   349 
       
   350 # merge checksource processing from platform specific .mmp sections, if applicable
       
   351 %CheckSourceMMPMetaData = (%CheckSourceMMPMetaData, &PMPlatCheckSource()) if defined &PMPlatCheckSource;
       
   352 
       
   353 @ResourceSysIncPaths = @SysIncPaths;
       
   354 $ResourceVariantMacroHRHFile = $variantMacroHRHFile;
       
   355 
       
   356 AddStringTables();
       
   357 
       
   358 # Process feature variants if applicable
       
   359 
       
   360 if ($FeatureVariantArg)
       
   361 	{
       
   362 	if ($Options{v})
       
   363 		{
       
   364 		$featurevariantmap::verbose = 1;
       
   365 		$featurevariantparser::verbose = 1;
       
   366 		}
       
   367 
       
   368 	# Get the default variant details
       
   369 	my %DefaultFeatureVariantInfo = $FeatureVariantInfo{NAME} =~ /^default$/i ? %FeatureVariantInfo : featurevariantparser->GetVariant("DEFAULT");	
       
   370 	die "ERROR: Feature variant \"$PlatArg.default\" is invalid.\n" if !$DefaultFeatureVariantInfo{VALID};
       
   371 
       
   372 	# The following IF statement decides whether to use the default variant and not use the hash in the filename 
       
   373 	# This prevents the generation of dll's/exe's for which variants are not needed (i.e they are invariant)
       
   374 	# It also avoids the time-consuming and redundant hash generation
       
   375 	# A component is considered invariant if it's not a DLL or EXE or FEATUREVARIANT isn't present in the .mmp file
       
   376 	
       
   377 # modified start: makefile improvement 
       
   378 	if ($TrgType{Basic} =~ /^(EXEDLL|EXE|DLL|LIB)$/ && &Mmp_IsFeatureVariant)
       
   379 # modified end: makefile improvement 
       
   380 		{
       
   381 		# Load the requested variant if it hasn't already been preloaded		
       
   382 		%FeatureVariantInfo = featurevariantparser->GetVariant($FeatureVariantArg) if !$FeatureVariantInfo{NAME} || $FeatureVariantInfo{NAME} ne $FeatureVariantArg;
       
   383 		}
       
   384 	else
       
   385 		{
       
   386 		# Use the default variant
       
   387 		%FeatureVariantInfo = %DefaultFeatureVariantInfo;
       
   388 		$FeatureVariantInfo{INVARIANT} = 1;
       
   389 		$FeatureVariantInfo{NAME} = uc $FeatureVariantArg;
       
   390 		}
       
   391 
       
   392 	die "ERROR: Feature variant \"$PlatArg.$FeatureVariantInfo{NAME}\" is invalid.\n" if !$FeatureVariantInfo{VALID};
       
   393 	
       
   394 	my @featureVariantSysIncPaths = (@{$FeatureVariantInfo{BUILD_INCLUDES}},@SysIncPaths);
       
   395 	
       
   396 	# Further process paths and filenames so that they include a drive letter.
       
   397 	# We store this in a hash specifically for passing on to featurevariantmap->Hash
       
   398 	
       
   399 	my @processedIncludes = &Path_PrefixWithDrive(&Path_Chop(@UserIncPaths), &Path_Chop(@featureVariantSysIncPaths));
       
   400 	push @processedIncludes, &Path_Chop(&PMToolChainIncDir) if defined &PMToolChainIncDir && &PMToolChainIncDir;
       
   401 	
       
   402 	my $processedPreInclude = "";
       
   403 	if (defined &PMPrefixFile)
       
   404 		{
       
   405 		$processedPreInclude = &PMPrefixFile;
       
   406 		$processedPreInclude =~ s/\"//g;
       
   407 		$processedPreInclude = &Path_PrefixWithDrive($processedPreInclude);		
       
   408 		}
       
   409 
       
   410 	my %processedFeatureVariantInfo;
       
   411 	$processedFeatureVariantInfo{PREINCLUDE} = $processedPreInclude if $processedPreInclude;
       
   412 	$processedFeatureVariantInfo{BUILD_INCLUDES} = \@processedIncludes if @processedIncludes;
       
   413 	$processedFeatureVariantInfo{VALID} = 1;
       
   414 	
       
   415 	# Pass in the details of the macros tested in the MMP
       
   416 	$processedFeatureVariantInfo{MMPTESTED} = &Mmp_TestedMacros();
       
   417 
       
   418 	my @pathedSrcList = ();
       
   419 	push @pathedSrcList, Path_PrefixWithDrive($$_{SrcPath}.$$_{CurFile}) foreach (@SourceStruct);
       
   420 
       
   421 	foreach my $bld (@{$Plat{Blds}})
       
   422 		{
       
   423 # modified start: makefile improvement 
       
   424 		my @reusedHash;
       
   425 # modified end: makefile improvement 
       
   426 		if ($FeatureVariantInfo{INVARIANT})															# Invariant override
       
   427 			{
       
   428 			$FeatureVariantInfo{$bld."_LABEL"} = "INVARIANT";
       
   429 			}
       
   430 		else
       
   431 			{
       
   432 # modified by SV start: makefile improvement 
       
   433 			my $vmap = "$E32env::Data{RelPath}".lc($Plat{Real})."\\".lc($bld)."\\".Trg()."." . $FeatureVariantInfo{NAME}.".vmap";
       
   434 # modified by SV end: makefile improvement 
       
   435 			$vmap = Path_PrefixWithDrive($vmap);
       
   436 			if(-e $vmap){
       
   437 				my @variantlist = featurevariantmap->GetVariantListFromVmap($vmap);
       
   438 				my @calls;
       
   439 				foreach(@variantlist)
       
   440 				{
       
   441 					my $target = "CHECKVMAP".uc($bld);
       
   442 					my $makefile = $MAKEFILE.".".$_;
       
   443 					if(-e $makefile){
       
   444 						push @calls, "make -r -f \"$makefile\"  $target";
       
   445 					}
       
   446 				}
       
   447 				foreach my $call (@calls)
       
   448 				{
       
   449 					print "call: $call" if $Options{v};
       
   450 					open PIPE, "$call |";
       
   451 					while(<PIPE>) {
       
   452 						print $_;
       
   453 					}
       
   454 					close PIPE;
       
   455 				}
       
   456 				if(-e $vmap){
       
   457 					@reusedHash = featurevariantmap->CheckOldVmapFile($vmap, \%FeatureVariantInfo);
       
   458 				}
       
   459 			}
       
   460 			if(defined(@reusedHash))
       
   461 			{
       
   462 				$FeatureVariantInfo{$bld."_LABEL"} = $reusedHash[0];
       
   463 				$FeatureVariantInfo{$bld."_FEATURES"} = $reusedHash[1];
       
   464 				next;
       
   465 			}
       
   466 # modified end: makefile improvement 
       
   467 			my @macros = (@{$Plat{Macros}}, @{$BldMacros{$bld}}, "__SUPPORT_CPP_EXCEPTIONS__");
       
   468 			push @macros, "__PRODUCT_INCLUDE__=\"".&Path_PrefixWithDrive($FeatureVariantInfo{VARIANT_HRH})."\"" if $FeatureVariantInfo{VARIANT_HRH};
       
   469 			$processedFeatureVariantInfo{MACROS} = \@macros;
       
   470 
       
   471 			print ("Feature variant hash processing: \"$FeatureVariantInfo{NAME} $bld\"\n") if $Options{v};
       
   472 			
       
   473 			my @result = featurevariantmap->HashAndFeatures(\@pathedSrcList, \%processedFeatureVariantInfo);
       
   474 			$FeatureVariantInfo{$bld."_LABEL"} = $result[0];
       
   475 			$FeatureVariantInfo{$bld."_FEATURES"} = $result[1];
       
   476 			
       
   477 			die "ERROR: Can't obtain hash for \"$PlatArg.$FeatureVariantInfo{NAME}\" feature variant.\n" if !$FeatureVariantInfo{$bld."_LABEL"};
       
   478 			}
       
   479 		}
       
   480 
       
   481 	# Customise standard content based on feature variant updates
       
   482 	@SysIncPaths = @featureVariantSysIncPaths;
       
   483 	$variantMacroHRHFile = $FeatureVariantInfo{VARIANT_HRH};
       
   484 	$MAKEFILE .= ".$FeatureVariantInfo{NAME}";
       
   485 
       
   486 	# Resources are always processed in the context of the default variant's system include and variant files when
       
   487 	# feature variants are in use
       
   488 	@ResourceSysIncPaths = (@{$DefaultFeatureVariantInfo{BUILD_INCLUDES}},@ResourceSysIncPaths);
       
   489 	$ResourceVariantMacroHRHFile = $DefaultFeatureVariantInfo{VARIANT_HRH};
       
   490 	}
       
   491 
       
   492 
       
   493 {
       
   494 	# if verbose mode set, output some info
       
   495 	#--------------------------------------
       
   496 	if ($Options{v}) {
       
   497 		print  
       
   498 			"Target: \"$Trg\"\n",
       
   499 			"TargetType: \"$TrgType{Name}\"\n",
       
   500 			"Libraries: \"@LibList\"\n",
       
   501 			"Debug Libraries: \"@DebugLibList\"\n",
       
   502 			"Static Libraries: \"@StatLibList\"\n",
       
   503 			"Uids: \"@UidList\"\n",
       
   504 			"BuildVariants: \"@{$Plat{Blds}}\"\n",
       
   505 			"TargetMakeFile: \"$MAKEFILE\"\n",
       
   506 			"UserIncludes: \"<Source Dir> @UserIncPaths\"\n",
       
   507 			"SystemIncludes: \"@SysIncPaths\"\n"
       
   508 		;
       
   509 
       
   510 	if (%FeatureVariantInfo)
       
   511 		{
       
   512 		print 
       
   513 			"Feature Variant Name: \"$FeatureVariantInfo{NAME}\"\n",
       
   514 			"Feature Variant SystemIncludes: \"@{$FeatureVariantInfo{BUILD_INCLUDES}}\"\n",
       
   515 			"Feature Variant HRH file: \"$FeatureVariantInfo{VARIANT_HRH}\"\n";
       
   516 
       
   517 		foreach my $bld (@{$Plat{Blds}})
       
   518 			{
       
   519 			print "Feature Variant $bld Label: \"".$FeatureVariantInfo{$bld."_LABEL"}."\"\n";			
       
   520 			}
       
   521 		
       
   522 		}
       
   523 	}
       
   524 }
       
   525 
       
   526 # Special handling for non-default invariant makefiles without FEATUREVARIANT in the MMP file
       
   527 # In this situation the default variant makefle is just included into the variant makefile
       
   528 # modified start: makefile improvement 
       
   529 if ($TrgType{Basic} =~ /^(EXEDLL|EXE|DLL|LIB)$/ && %FeatureVariantInfo && $FeatureVariantInfo{INVARIANT})
       
   530 	{
       
   531 	$MAKEFILE =~ s/([^.]*$)/DEFAULT/;
       
   532 # modified by SV start: makefile improvement 
       
   533 		if( $FeatureVariantInfo{NAME} !~ /^default$/i)
       
   534 			{
       
   535 				print "not creating makefile for  : $FeatureVariantInfo{NAME}\n" if ($Options{v});
       
   536 			}
       
   537 # modified by SV end: makefile improvement 
       
   538 	if(-e $MAKEFILE )
       
   539 		{
       
   540 		my $mmp_time = -M $MMPFILE;
       
   541 		my $makefile_time = -M $MAKEFILE;
       
   542 		if( $makefile_time <= $mmp_time)
       
   543 			{
       
   544 			exit;
       
   545 			}
       
   546 		}
       
   547 	undef %FeatureVariantInfo;
       
   548 	%FeatureVariantInfo = featurevariantparser->GetVariant("default");
       
   549 	$FeatureVariantInfo{INVARIANT} = 1;
       
   550 	$FeatureVariantInfo{UREL_LABEL} = 'INVARIANT';
       
   551 	$FeatureVariantInfo{UDEB_LABEL} = 'INVARIANT';
       
   552 	}
       
   553 # modified by SV start: makefile improvement 
       
   554 	elsif(%FeatureVariantInfo)
       
   555 	{
       
   556 	my $variant_info = &Path_Chop($E32env::Data{BldPath}).$Path{BldInfPath}."\\FeatureVariantInfo\\".$Plat{Real}."\\".$Plat{Real}.".".$FeatureVariantInfo{NAME}.".".&Path_Split('Base', $MMPFILE).".info";
       
   557 	#if mmp file does not exists
       
   558 	$variant_info = &Path_Chop($E32env::Data{BldPath}).$Path{BldInfPath}."\\FeatureVariantInfo\\".$Plat{Real}."\\".$Plat{Real}.".".$FeatureVariantInfo{NAME}.".info" if ! -e $MMPFILE;
       
   559 # modified by SV end: makefile improvement 
       
   560 	my $variant_key = "VARIANT_PLAT_NAME_".&Path_Split('Base', $MMPFILE);
       
   561 	$variant_info_new = $variant_info.".tmp";
       
   562 	open VARIANTINFOR_NEW, ">$variant_info_new" or die "ERROR: Can't open or create file \"$variant_info_new\"\n";
       
   563 
       
   564 	# Open the variant infor file
       
   565 	open VARIANTINFOR, "<$variant_info" or die "ERROR: Can't open file \"$variant_info\"\n";
       
   566 	while(<VARIANTINFOR>)
       
   567 		{
       
   568 		if(/^$variant_key/)
       
   569 			{
       
   570 			print VARIANTINFOR_NEW $variant_key.":=".$FeatureVariantInfo{NAME}."\n";
       
   571 			}
       
   572 			else
       
   573 			{
       
   574 			print VARIANTINFOR_NEW $_;
       
   575 			}
       
   576 		}
       
   577 	# Close and cleanup
       
   578 	close VARIANTINFOR or die "ERROR: Can't close file \"$variant_info\"\n";
       
   579 	close VARIANTINFOR_NEW or die "ERROR: Can't close file \"$variant_info\"\n";
       
   580 	unlink $variant_info;
       
   581 	rename($variant_info_new, $variant_info);
       
   582 	if ($Options{v}) {
       
   583 		print "Successful Variant Infor File Creation\n";
       
   584 
       
   585 		}
       
   586 	}
       
   587 # modified end: makefile improvement 
       
   588 
       
   589 # modified by SV start: makefile improvement 
       
   590 if(-e $MAKEFILE)
       
   591 {
       
   592 	my $mmp_time = -M $MMPFILE;
       
   593 	my $makefile_time = -M $MAKEFILE;
       
   594 	if( $makefile_time <= $mmp_time)
       
   595 	{
       
   596 		exit;
       
   597 	}
       
   598 }
       
   599 # modified by SV end: makefile improvement 
       
   600 
       
   601 my $CurAifRef;
       
   602 my $CurBaseObj;
       
   603 my $CurBld;
       
   604 my $CurBitMapRef;
       
   605 my @CurDepList;
       
   606 my $CurDoc;
       
   607 my $CurResrc;
       
   608 my $CurResourceRef;
       
   609 my $CurSrc;
       
   610 my $CurSrcPath;
       
   611 my $ResrcIsSys;
       
   612 # modified start: makefile improvement 
       
   613 my %CurSrcSet;
       
   614 # modified end: makefile improvement 
       
   615 
       
   616 # Set up library paths getting the backend module to help if it wants to
       
   617 {
       
   618 	&InitLinkPaths();
       
   619 }
       
   620 
       
   621 {
       
   622 
       
   623 	# LOOPING SECTION
       
   624 	#----------------
       
   625 	# Load the output module
       
   626 	eval { &Load_ModuleL('OUTPUT'); };
       
   627 	die $@ if $@;
       
   628 
       
   629  
       
   630 	# Believe include first on the system list. 
       
   631     my $VariantFile=&main::VariantFile();
       
   632     if($VariantFile){
       
   633         my $VariantFilePath = Path_Split('Path',$VariantFile);
       
   634         chop($VariantFilePath);
       
   635 
       
   636         push(@SysIncPaths, $VariantFilePath);
       
   637     }
       
   638 
       
   639 	my $ResourceVariantFile=&main::ResourceVariantFile();
       
   640     if($ResourceVariantFile){
       
   641         my $ResourceVariantFilePath = Path_Split('Path',$ResourceVariantFile);
       
   642         chop($ResourceVariantFilePath);
       
   643 
       
   644         push(@ResourceSysIncPaths, $ResourceVariantFilePath);
       
   645     }
       
   646     
       
   647     ## Add default system include info for TOOLS2
       
   648     if ($PlatArg eq 'TOOLS2') {    	
       
   649     	push @SysIncPaths , "$E32env::Data{EPOCPath}include\\tools\\stlport";
       
   650     }
       
   651 
       
   652 	# If the stdcpp keyword is used, or if the target type is STD* ...
       
   653 	if ($StdCpp or $TrgType{Name} eq 'STDEXE' or $TrgType{Name} eq 'STDDLL' or $TrgType{Name} eq 'STDLIB') {
       
   654 		push @SysIncPaths, $E32env::Data{EPOCPath}."include\\stdapis";
       
   655 	}
       
   656 
       
   657 	&PMStartBldList($Plat{MakeCmd}) if defined &PMStartBldList;
       
   658 	my $LoopBld;
       
   659 	foreach $LoopBld (@{$Plat{Blds}}) {
       
   660 		$CurBld=$LoopBld;
       
   661 		&PMBld if defined &PMBld;
       
   662 	}
       
   663 	undef $CurBld;
       
   664 	undef $LoopBld;
       
   665 	&PMEndBldList if defined &PMEndBldList;
       
   666 
       
   667 
       
   668 	# Load the Dependency Generator
       
   669 	eval { &Load_ModuleL('MAKDEPS'); };
       
   670 	die $@ if $@;
       
   671 	eval { &Deps_InitL($E32env::Data{EPOCIncPath},@StdIncPaths); };
       
   672 	die $@ if $@;
       
   673 	if ($Options{v}) {
       
   674 		&Deps_SetVerbose;
       
   675 	}
       
   676 	if ($Plat{UsrHdrsOnly}) {
       
   677 		&Deps_SetUserHdrsOnly;
       
   678 	}
       
   679 
       
   680 	if ($Options{nd} || ($ENV{SYMBIANBUILD_DEPENDENCYOFF} && ($ENV{SYMBIANBUILD_DEPENDENCYOFF}==1))) {
       
   681 		&Deps_SetNoDependencies
       
   682 	}
       
   683 	&Deps_SetNoDependencies if(grep /boostlibrary/i, &Mmp_UserIncPaths);
       
   684 
       
   685 	&Deps_SetUserIncPaths(@UserIncPaths);
       
   686 	&Deps_SetSysIncPaths(@ResourceSysIncPaths);
       
   687 	&Deps_SetPlatMacros(@{$Plat{Macros}});
       
   688 
       
   689 	my $prefixFile;
       
   690 	$prefixFile = &PMPrefixFile if defined &PMPrefixFile;
       
   691 	&Deps_SetPrefixFile($prefixFile) if $prefixFile;
       
   692 
       
   693 #	Start source list - bitmaps, resources, .AIF files, documents, sources.
       
   694 
       
   695 	# If feature variants are in use, dependency analysis may use a different overall variant file to that for "straight" source
       
   696 	my $curDepOSVariantFile = &Deps_GetOSVariantFile();
       
   697 	&Deps_SetOSVariantFile($ResourceVariantFile);
       
   698 
       
   699 	&PMStartSrcList if defined &PMStartSrcList;
       
   700 
       
   701 #	start bitmaps
       
   702 
       
   703 	if ($Options{v}) {
       
   704 		print "Starting bitmaps\n";
       
   705 	}
       
   706 	my $LoopBitMapRef;
       
   707 	foreach $LoopBitMapRef (@BitMapStruct) {
       
   708 		$CurBitMapRef=$LoopBitMapRef;
       
   709 		if ($Options{v}) {
       
   710 			print "BitMap: \"$$CurBitMapRef{Trg}\"\n";
       
   711 		}
       
   712 		&PMBitMapBld if defined &PMBitMapBld;
       
   713 	}
       
   714 	undef $CurBitMapRef;
       
   715 	undef $LoopBitMapRef;
       
   716 
       
   717 #	end bitmaps
       
   718 
       
   719 #	start resources
       
   720 
       
   721 	if ($Options{v}) {
       
   722 		print "Starting resources\n";
       
   723 	}
       
   724 	my $LoopResourceRef;
       
   725 	foreach $LoopResourceRef (@ResourceStruct) {
       
   726 		$CurResourceRef=$LoopResourceRef;
       
   727 		if ($Options{v}) {
       
   728 			print "Resource: \"$$CurResourceRef{Trg}\"\n";
       
   729 		}
       
   730 		eval { @CurDepList=&Deps_GenDependsL($$CurResourceRef{Source}, ("LANGUAGE_$$CurResourceRef{Lang}")); };
       
   731 		die $@ if $@;
       
   732 		&PMResrcBld if defined &PMResrcBld;
       
   733 		undef @CurDepList;
       
   734 	}
       
   735 	undef $CurResourceRef;
       
   736 	undef $LoopResourceRef;
       
   737 
       
   738 #	end resources
       
   739 
       
   740 #	start aifs
       
   741 
       
   742 	if ($Options{v}) {
       
   743 		print "Starting aifs\n";
       
   744 	}
       
   745 
       
   746 # Add tools-relative include path to sys includes, to allow for shared include\aiftool.rh
       
   747 	use FindBin;
       
   748 	$FindBin::Bin =~ /:(.*)\//;
       
   749 	my $extraIncPath = $1;
       
   750 	$extraIncPath =~ s/\//\\/g;
       
   751 	my @SavedResourceSysIncPaths = @ResourceSysIncPaths;
       
   752 	push @ResourceSysIncPaths, "$extraIncPath\\INCLUDE";
       
   753 	&Deps_SetSysIncPaths(@ResourceSysIncPaths);
       
   754 
       
   755 	my $LoopAifRef;
       
   756 	foreach $LoopAifRef (@AifStruct) {
       
   757 		$CurAifRef=$LoopAifRef;
       
   758 		if ($Options{v}) {
       
   759 			print "Aif: \"$$CurAifRef{Trg}\"\n";
       
   760 		}
       
   761 		eval { @CurDepList=&Deps_GenDependsL("$$CurAifRef{Source}"); };
       
   762 		die $@ if $@;
       
   763 		&PMAifBld if defined &PMAifBld;
       
   764 		undef @CurDepList;
       
   765 	}
       
   766 	undef $CurAifRef;
       
   767 	undef $LoopAifRef;
       
   768 
       
   769 	@ResourceSysIncPaths = @SavedResourceSysIncPaths;
       
   770 
       
   771 #	end aifs
       
   772 
       
   773 #	start sources
       
   774 
       
   775 	if ($Options{v}) {
       
   776 		print "Starting sources\n";
       
   777 	}
       
   778 	
       
   779 	my $SrcRef;
       
   780 	&Deps_SetOSVariantFile($curDepOSVariantFile);
       
   781 	&Deps_SetSysIncPaths(@SysIncPaths);
       
   782 
       
   783 	foreach $SrcRef (@SourceStruct){
       
   784 		 $CurSrcPath=$$SrcRef{SrcPath};
       
   785 		 $CurSrc=$$SrcRef{CurFile};
       
   786 
       
   787 		 my @userIncludes = &Mmp_UserIncPaths;
       
   788 		 @userIncludes = (@userIncludes, @StringTableUserIncPaths) if (@StringTableUserIncPaths);
       
   789 		 unshift (@userIncludes, $CurSrcPath);		 
       
   790 
       
   791 		 if ($TruePlat{Ext} !~ /\.DSP|\.xml/i)
       
   792 		 	{
       
   793 			foreach my $buildVariant (@{$Plat{Blds}})
       
   794 				{		 		
       
   795 				my @macros = &MacroList;
       
   796 				@macros = (@macros, @{$BldMacros{$buildVariant}});
       
   797 
       
   798 				my $checkSourceCommandStore;
       
   799 			
       
   800 				if ($buildVariant =~ /rel$/i)
       
   801 					{
       
   802 					$checkSourceCommandStore = \%CheckSourceURELIncludes
       
   803 					}
       
   804 				else
       
   805 					{
       
   806 					$checkSourceCommandStore = \%CheckSourceUDEBIncludes
       
   807 					}
       
   808 				CheckSource_Includes($CurSrcPath.$CurSrc, %$checkSourceCommandStore, $VariantFile, @macros, @userIncludes, @SysIncPaths);
       
   809 			}
       
   810 		 }
       
   811 		 if ($Options{v}) {
       
   812 			print "Sourcepath: \"$CurSrcPath\"\n";
       
   813 		 }
       
   814 		 &PMStartSrc if defined &PMStartSrc;
       
   815 
       
   816 #			strict depend alt 1 start - call different module function if strict depend flag specified
       
   817 			if (((not $MmpFlag{StrictDepend}) || (not defined &PMSrcBldDepend)) && defined &PMSrcDepend) {
       
   818 				eval { @CurDepList=&Deps_GenDependsL($CurSrcPath.$CurSrc);};
       
   819 				die $@ if $@;
       
   820 # modified start: makefile improvement 
       
   821 				foreach $srcFile (@CurDepList) {
       
   822 					if(not exists($CurSrcSet{$srcFile})){
       
   823 						my $srctmp = $srcFile;
       
   824 						$CurSrcSet{$srctmp} = 1;
       
   825 					}
       
   826 				}
       
   827 # modified end: makefile improvement 
       
   828 				&PMSrcDepend if defined &PMSrcDepend;
       
   829 				undef @CurDepList;
       
   830 			}
       
   831 							
       
   832 #			strict depend alt 1 end
       
   833 
       
   834 			my $LoopBld;
       
   835 			foreach $LoopBld (@{$Plat{Blds}}) {
       
   836 				$CurBld=$LoopBld;
       
   837 				&PMStartSrcBld if defined &PMStartSrcBld;
       
   838 
       
   839 #				strict depend alt 2 start - call the module function that deals with dependencies generated for each build variant
       
   840 				if ($MmpFlag{StrictDepend} && defined &PMSrcBldDepend) {
       
   841 					eval { @CurDepList=Deps_GenDependsL($CurSrcPath.$CurSrc,@{$BldMacros{$CurBld}}); };
       
   842 					die $@ if $@;
       
   843 					&PMSrcBldDepend if defined &PMSrcBldDepend;
       
   844 					undef @CurDepList;
       
   845 				}
       
   846 #				strict depend alt 2 end
       
   847 
       
   848 				&PMEndSrcBld if defined &PMEndSrcBld;
       
   849 			}
       
   850 			undef $CurBld;
       
   851 			undef $LoopBld;
       
   852 			&PMEndSrc if defined &PMEndSrc;
       
   853 # modified start: makefile improvement 
       
   854 			my $cursrcfile = $CurSrcPath.$CurSrc;
       
   855 			if(not exists($CurSrcSet{$cursrcfile})){
       
   856 				$CurSrcSet{$cursrcfile} = 1;
       
   857 			}
       
   858 # modified end: makefile improvement 
       
   859 		}
       
   860 		undef $CurSrc;
       
   861 		undef $CurSrcPath;  
       
   862 	
       
   863 	
       
   864 
       
   865 #	end sources
       
   866 
       
   867 #	start documents
       
   868 
       
   869 	if ($Options{v}) {
       
   870 		print "Starting documents\n";
       
   871 	}
       
   872 	my $LoopSrcPath;
       
   873 	foreach $LoopSrcPath (sort keys %DocHash) {
       
   874 		$CurSrcPath=$LoopSrcPath;
       
   875 		if ($Options{v}) {
       
   876 			print "Sourcepath: \"$CurSrcPath\"\n";
       
   877 		}
       
   878 		my $LoopDoc;
       
   879 		foreach $LoopDoc (sort @{$DocHash{$CurSrcPath}}) {
       
   880 			$CurDoc=$LoopDoc;
       
   881 			if ($Options{v}) {
       
   882 				print "Document: \"$CurDoc\"\n";
       
   883 			}
       
   884 			&PMDoc if defined &PMDoc;
       
   885 		}
       
   886 		undef $CurDoc;
       
   887 		undef $LoopDoc;
       
   888 	}
       
   889 	undef $CurSrcPath;
       
   890 	undef $LoopSrcPath;
       
   891 
       
   892 #	end documents
       
   893 
       
   894 #	rombuild
       
   895 
       
   896 	my %SpecialRomFileTypes=(
       
   897 		KEXT=>'extension[MAGIC]',
       
   898 		LDD=>'device[MAGIC]',
       
   899 		PDD=>'device[MAGIC]',
       
   900 		VAR=>'variant[MAGIC]'
       
   901 	);
       
   902 	my %KHash1 = (
       
   903 		kext=>1,
       
   904 		ldd=>1,
       
   905 		pdd=>1,
       
   906 		var=>1,
       
   907 		kdll=>1
       
   908 	);
       
   909 	my %KHash2 = (
       
   910 		primary=>1,
       
   911 		variant=>1,
       
   912 		extension=>1,
       
   913 		device=>1
       
   914 	);
       
   915 	unless ($TrgType{Basic} =~ /^IMPLIB$/io or $TruePlat{Ext} =~ /\.DSP|\.xml/i) { # change to avoid rombuild target for IDE makefiles
       
   916 		&Output("ROMFILE:\n");
       
   917 		unless ($Plat{OS} ne 'EPOC32' or $TrgType{Basic} eq 'LIB') {
       
   918 			my $ref;
       
   919 			foreach $ref (@RomTargets) {
       
   920 				my $ABIDir = '##MAIN##';
       
   921 				my $RomFileType='file';
       
   922 				if ($$ref{FileType}) {	# handle EKERN.EXE and EFILE.EXE with new ROMFILETYPE keyword instead
       
   923 					$RomFileType=$$ref{FileType}; # or just do this bit as a custom build makefile
       
   924 				}
       
   925 				elsif ($CallDllEntryPoints) {
       
   926 					$RomFileType='dll';
       
   927 				}
       
   928 				elsif ($SpecialRomFileTypes{$TrgType{Name}}) {
       
   929 					$RomFileType=$SpecialRomFileTypes{$TrgType{Name}};
       
   930 				}
       
   931 				my $RomPath="sys\\bin\\";
       
   932 				if ($$ref{Path}) {
       
   933 					$RomPath=$$ref{Path};
       
   934 				}
       
   935 				elsif ($TrgType{Path}) {
       
   936 					$RomPath=$TrgType{Path};
       
   937 					$RomPath=~s-z\\(.*)-$1-o;
       
   938 				}
       
   939 				my $RomFile=$LinkAsBase;
       
   940 				if ($$ref{File}) {
       
   941 					$RomFile=$$ref{File};
       
   942 				}
       
   943 				my $RomDecorations='';
       
   944 				if ($DataLinkAddress) {
       
   945 					$RomDecorations="reloc=$DataLinkAddress";
       
   946 				}
       
   947 				elsif ($FixedProcess) {
       
   948 					$RomDecorations.='fixed';
       
   949 				}
       
   950 				
       
   951 				$ABIDir = '##KMAIN##' if ($KHash1{lc $TrgType{Name}});
       
   952 				$ABIDir = '##KMAIN##' if ($KHash2{lc $RomFileType});
       
   953 				my $IbyTextFrom="$RomFileType=$E32env::Data{RelPath}$ABIDir\\##BUILD##\\$Trg";
       
   954 				my $IbyTextTo="$RomPath$RomFile";
       
   955 				my $Spaces= 60>length($IbyTextFrom) ? 60-length($IbyTextFrom) : 1; 
       
   956 				&Output("\t\@echo ", $IbyTextFrom, ' 'x$Spaces, "$IbyTextTo $RomDecorations\n");
       
   957 			}
       
   958 			foreach $ref (@RamTargets) {
       
   959 				my $ABIDir = '##MAIN##';
       
   960 				$ABIDir = '##KMAIN##' if ($KHash1{lc $TrgType{Name}});
       
   961 				my $RomFileType='data';
       
   962 				my $RomPath="sys\\bin\\";
       
   963 				if ($$ref{Path}) {
       
   964 					$RomPath=$$ref{Path};
       
   965 				}
       
   966 				my $RomFile=$Trg;
       
   967 				if ($$ref{File}) {
       
   968 					$RomFile=$$ref{File};
       
   969 				}
       
   970 				my $RomDecorations='attrib=r';
       
   971 
       
   972 				my $IbyTextFrom="$RomFileType=$E32env::Data{RelPath}$ABIDir\\##BUILD##\\$Trg";
       
   973 				my $IbyTextTo="$RomPath$RomFile";
       
   974 				my $Spaces= 60>length($IbyTextFrom) ? 60-length($IbyTextFrom) : 1; 
       
   975 				&Output("\t\@echo ", $IbyTextFrom, ' 'x$Spaces, "$IbyTextTo $RomDecorations\n");
       
   976 			}
       
   977 		}
       
   978 	}
       
   979 #	end rombuild
       
   980 
       
   981 	&PMEndSrcList if defined &PMEndSrcList;
       
   982 }
       
   983 
       
   984 {
       
   985 
       
   986 	# open the makefile and write all the text it requires to it if makmake has so far been successful
       
   987 	#-------------------------------------------------------------------------------------------------
       
   988 	eval { &Path_MakePathL($MAKEFILE); };
       
   989 	die $@ if $@;
       
   990 	if ($Options{v}) {
       
   991 		print "Creating: \"$MAKEFILE\"\n";
       
   992 	}
       
   993 	open MAKEFILE,">$MAKEFILE" or die "ERROR: Can't open or create file \"$MAKEFILE\"\n";
       
   994 	print MAKEFILE &OutText or die "ERROR: Can't write output to file \"$MAKEFILE\"\n";
       
   995 	close MAKEFILE or die "ERROR: Can't close file \"$MAKEFILE\"\n";
       
   996 	if ($Options{v}) {
       
   997 		print "Successful MakeFile Creation\n";
       
   998 	}
       
   999 }
       
  1000 
       
  1001 	
       
  1002 ################ END OF MAIN PROGRAM SECTION #################
       
  1003 #------------------------------------------------------------#
       
  1004 ##############################################################
       
  1005 
       
  1006 
       
  1007 
       
  1008 
       
  1009 
       
  1010 # SUBROUTINE SECTION
       
  1011 ####################
       
  1012 
       
  1013 sub FatalError (@) {
       
  1014 
       
  1015 	print STDERR "MAKMAKE ERROR: @_\n";
       
  1016 	exit 1;
       
  1017 }
       
  1018 
       
  1019 sub Usage () {
       
  1020 
       
  1021 		eval { &Load_ModuleL('MAKHELP'); };
       
  1022 		die $@ if $@; 
       
  1023 		eval { &Help_Invocation; };
       
  1024 		die $@ if $@;
       
  1025 		exit;
       
  1026 }
       
  1027 
       
  1028 sub getEABIDef() {
       
  1029 	# Preprocess the mmp with ARMv5 platform settings so we can pick up 
       
  1030     # EABI specific def file entries etc. 
       
  1031     my ($platname)="ARMV5";
       
  1032     
       
  1033     # get platform info for armv5
       
  1034     eval { &Plat_GetL($platname,\%Plat,\%BldMacros); };
       
  1035 	return $@ if $@;
       
  1036 	&Mmp_Reset;
       
  1037 	# process 
       
  1038     
       
  1039     # set package to ignore warnings about missing .def file. 
       
  1040     &Mmp_SetIgnoreMissingDef;
       
  1041     
       
  1042     eval { &Mmp_ProcessL($E32env::Data{EPOCPath}, $MMPFILE, \%Plat, $FeatureVariantInfo{BUILD_INCLUDES}); };
       
  1043 	return $@ if $@;
       
  1044 	my %EABIDef=%{&Mmp_Def};
       
  1045 	
       
  1046     # handle case that def file doesn't exist -> Simply set to ""
       
  1047     my $EABIDefFile = "$EABIDef{Path}$EABIDef{Base}$EABIDef{Ext}";;
       
  1048    	unless (-e "$EABIDefFile") {
       
  1049         $EABIDefFile = "";
       
  1050 	}
       
  1051     
       
  1052     return $EABIDefFile;
       
  1053 	
       
  1054 }
       
  1055 
       
  1056 sub SetVarsFromMmp ($) {
       
  1057 
       
  1058 	my ($platname)=@_;
       
  1059     
       
  1060 	if($platname eq "GCCXML") {
       
  1061         $EABIDef = getEABIDef();
       
  1062     } 
       
  1063     else {
       
  1064         $EABIDef = "";
       
  1065     }
       
  1066 
       
  1067 	# MMP FILE PROCESSING - filter the mmp file content through the GCC preprecessor
       
  1068 	#-------------------------------------------------------------------------------
       
  1069 	eval { &Plat_GetL($platname,\%Plat,\%BldMacros); };
       
  1070 	return $@ if $@;
       
  1071 	&Mmp_Reset;
       
  1072 
       
  1073 	if($platname eq "GCCXML" || $platname eq "X86GCC" || $platname eq "X86GMP") {
       
  1074 	# set package to ignore warnings about missing .def file, this is necessary,
       
  1075 	# as either EABI .def or GCC .def may not exist, and this shouldn't be reported
       
  1076 	# as a warning or error. Similarly for x86gcc def files - these are autogenerated.
       
  1077 	&Mmp_SetIgnoreMissingDef;
       
  1078 	}
       
  1079 
       
  1080 	eval { &Mmp_ProcessL($E32env::Data{EPOCPath}, $MMPFILE, \%Plat, $FeatureVariantInfo{BUILD_INCLUDES}); };
       
  1081 	return $@ if $@;
       
  1082 
       
  1083 	%WarningLevel=&Mmp_WarningLevel;
       
  1084 	%LinkerOptions=&Mmp_LinkerOptions;
       
  1085 	$ABI=&Mmp_ABI;
       
  1086 	@AifStruct=@{&Mmp_AifStruct};
       
  1087 	$AllowDllData=&Mmp_AllowDllData;
       
  1088 	$CompressTarget=&Mmp_CompressTarget;
       
  1089 	$CompressTargetMode=&Mmp_CompressTargetMode;
       
  1090 	$ASSPExports=&Mmp_ASSPExports;
       
  1091 	@ASSPLibList=&Mmp_ASSPLibList;
       
  1092 	@BitMapStruct=@{&Mmp_BitMapStruct};
       
  1093 	$BuildAsARM=$BuildAsARM || &Mmp_BuildAsARM;
       
  1094 	$CallDllEntryPoints=&Mmp_CallDllEntryPoints;
       
  1095 	$Capability=&Mmp_Capability;
       
  1096 	@CapabilityFlags=&Mmp_CapabilityFlags;
       
  1097 	$DataLinkAddress=&Mmp_DataLinkAddress;
       
  1098 	@DebugLibList=@{&Mmp_DebugLibList};
       
  1099 	%Def=%{&Mmp_Def};
       
  1100 	%DocHash=%{&Mmp_DocHash};
       
  1101 	$ExportUnfrozen=&Mmp_ExportUnfrozen;
       
  1102 	$FirstLib=&Mmp_FirstLib;
       
  1103 	$FixedProcess=&Mmp_FixedProcess;
       
  1104 	%HeapSize=%{&Mmp_HeapSize};
       
  1105 	@LibList=@{&Mmp_LibList};
       
  1106 	$LinkAs=&Mmp_LinkAs;
       
  1107 	$LinkAsBase=&Mmp_LinkAsBase;
       
  1108 	$ExportLibrary=&Mmp_ExportLibrary;
       
  1109 	$NewLib = &Mmp_NewLib;
       
  1110     $NoExportLibrary=&Mmp_NoExportLibrary;
       
  1111 	%MmpFlag=%{&Mmp_MmpFlag};
       
  1112 	@PlatTxt2D=&Mmp_PlatTxt2D;
       
  1113 	$ProcessPriority=&Mmp_ProcessPriority;
       
  1114 	@RamTargets=&Mmp_RamTargets;
       
  1115 	@ResourceStruct=@{&Mmp_ResourceStruct};
       
  1116 	@RomTargets=&Mmp_RomTargets;
       
  1117 	$SmpSafe=&Mmp_SmpSafe;
       
  1118 	@SourceStruct=@{&Mmp_SourceStruct};
       
  1119 	$StackSize=&Mmp_StackSize;
       
  1120 	@StatLibList=&Mmp_StatLibList;    
       
  1121 	$StdCpp = &Mmp_StdCpp;
       
  1122 	$NoStdCpp = &Mmp_NoStdCpp;
       
  1123 	@SysIncPaths=&Mmp_SysIncPaths;
       
  1124 	$Trg=&Mmp_Trg;
       
  1125 	%TrgType=%{&Mmp_TrgType};
       
  1126 	@UidList=&Mmp_UidList;
       
  1127 	@UserIncPaths=&Mmp_UserIncPaths;
       
  1128 	$SrcDbg=&Mmp_SrcDbg;
       
  1129 	%Version=&Mmp_Version;
       
  1130 	$SecureId=&Mmp_SecureId;
       
  1131 	$VendorId=&Mmp_VendorId;
       
  1132 	%ReplaceOptions=&Mmp_Replace;
       
  1133 	$ARMFPU=&Mmp_ARMFPU;
       
  1134 	@StringTable=@{&Mmp_StringTable};
       
  1135 	$CodePagingTargetMode=&Mmp_CodePagingTargetMode;
       
  1136 	$DataPagingTargetMode=&Mmp_DataPagingTargetMode;
       
  1137 	$IsWideCharMain=&Mmp_IsWideCharMain;
       
  1138 	$IsDebuggable=&Mmp_IsDebuggable;
       
  1139 
       
  1140 #	finish defining any macros
       
  1141 
       
  1142 	if ($Plat{CPU} eq 'MARM') {
       
  1143 #		apply the ABI source define - note that it is difficult to define a corresponding
       
  1144 #		.MMP define since we can't be sure what the ABI is until we've processed the .MMP file,
       
  1145 #		though we could apply it for generic MARM builds only
       
  1146 		push @{$Plat{Macros}}, "__MARM_${ABI}__";
       
  1147 	}
       
  1148 
       
  1149 	if ($TrgType{Basic}=~/^(DLL|EXE)$/o) { # this macro may soon be removed
       
  1150 		push @{$Plat{Macros}},'__'.$TrgType{Basic}.'__';
       
  1151 	}
       
  1152 
       
  1153 #	add the macros defined in the .mmp file
       
  1154 	push @{$Plat{Macros}}, &Mmp_Macros;
       
  1155 
       
  1156 # set up a hash containing the start paths for various things
       
  1157 	undef %Path;
       
  1158 
       
  1159 #	set up ASSP link path - this is the path where the target looks for ASSP-specific import libraries
       
  1160         $Path{ASSPLink}="$E32env::Data{LinkPath}$Plat{ASSP}\\";
       
  1161 
       
  1162 #	set up build path
       
  1163 	my $BldInfPath=cwd;
       
  1164 	$BldInfPath=~s-/-\\-go;						# separator from Perl 5.005_02+ is forward slash
       
  1165 	$BldInfPath=~s/^(.:)//o;					# remove drive letter
       
  1166 	$BldInfPath=~s-^(.*[^\\])$-$1\\-o;			# ensure workpath ends with a backslash
       
  1167 	$Path{BldInfPath} = $BldInfPath;			# Remember the path to bldinf
       
  1168 	$Path{Bld}=join('', &Path_Chop($E32env::Data{BldPath}), $BldInfPath, &Path_Split('Base',$MMPFILE), "\\$Plat{Real}\\");
       
  1169 }
       
  1170 
       
  1171 sub generateX86GCCDefFile()
       
  1172 {
       
  1173 	my ($oldPath, $newPath) = @_;
       
  1174 	print "Generating X86GCC deffile from $oldPath\n";
       
  1175 	if (!open(OLDDEF, $oldPath))
       
  1176 	{
       
  1177 		print "Warning: Failed to open $oldPath for reading\n".
       
  1178 		return;
       
  1179 	}
       
  1180 	# Force creation of new def file even if one already exists
       
  1181 	if (!open(NEWDEF, ">$newPath"))
       
  1182 	{
       
  1183 		close OLDDEF;
       
  1184 		print "Warning: Failed to open $newPath for writing\n".
       
  1185 		return;
       
  1186 	}
       
  1187 	while (<OLDDEF>)
       
  1188 	{
       
  1189 		chomp;
       
  1190 		if (/^\s*_ZT(I|V)/ && !/\sABSENT/i)
       
  1191 	    {
       
  1192 		# Typeinfo that isn't already absent. Add the ABSENT keyword.
       
  1193 		    my @frags = split /;/, $_, 2; # 1 or 2 parts depending on the presence of a comment
       
  1194 		    $frags[0] =~ s/\s*$/ ABSENT /;
       
  1195 		    $_ = join ';', @frags;
       
  1196 	    }
       
  1197 	    else
       
  1198 	    {
       
  1199 		# Try to substitute any va_list params with char* (Pc). Ignore if no match
       
  1200 		s/St9__va_list/Pc/g;
       
  1201 	    }
       
  1202 		print NEWDEF "$_\n";	    
       
  1203 	}
       
  1204 	close OLDDEF;
       
  1205 	close NEWDEF;
       
  1206 	print "Successfully generated $newPath\n";
       
  1207 }
       
  1208 
       
  1209 sub InitLinkPaths() {
       
  1210 #	set up lib path - this is the path where the target puts it's import library
       
  1211 
       
  1212 	my $ABI=&Mmp_ABI;
       
  1213 
       
  1214 #	let the build target determine where it puts its import libray and where its links against its imports
       
  1215 	my $UnderlyingABI=$ABI;
       
  1216 	$UnderlyingABI=&PMUnderlyingABI($ABI) if defined &PMUnderlyingABI;
       
  1217 
       
  1218 	$Path{Lib}="$E32env::Data{LinkPath}";
       
  1219 	unless ($ASSPExports) {
       
  1220 		$Path{Lib}.= lc($UnderlyingABI)."\\";
       
  1221 	} 
       
  1222 	else {
       
  1223 		$Path{Lib}.= lc($Plat{ASSP})."\\";
       
  1224 	}
       
  1225 
       
  1226 
       
  1227 #	set up link path - this is the place where the target looks for ordinary libraries
       
  1228 	$Path{Link}="$E32env::Data{LinkPath}"."$UnderlyingABI\\";
       
  1229 
       
  1230 #	set up stat link path - this is where the target looks for static libraries
       
  1231 	$Path{StatLink}="$E32env::Data{LinkPath}";
       
  1232 	if ($Plat{StatLink}) {
       
  1233 			$Path{StatLink}.=lc($Plat{StatLink})."\\";
       
  1234 	} else {
       
  1235 		unless ($Plat{OS} eq 'WINS') {	# WINC and WINS versions of EEXE are different
       
  1236 			$Path{StatLink}.=lc($ABI)."\\"; # ARM static libraries are currently always ASSP-independent
       
  1237 		}
       
  1238 		else {
       
  1239 			$Path{StatLink}.=lc($Plat{ASSP})."\\"; # WINC static libraries are currently always ASSP-specific
       
  1240 		}
       
  1241 	}
       
  1242 
       
  1243 #	set up release path
       
  1244 	$Path{Rel}="$E32env::Data{RelPath}".lc($Plat{Real})."\\";
       
  1245 	
       
  1246 }
       
  1247 
       
  1248 sub CreateExtraFile ($$) { # takes abs path for source and text
       
  1249 # allows modules to create extrafiles
       
  1250 	my ($FILE,$Text)=@_;
       
  1251 	if ($Options{makemakefile}) {	# only create if making the makefile
       
  1252 		if ($Options{v}) {
       
  1253 			print "Creating \"$FILE\"\n";
       
  1254 		}
       
  1255 		eval { &Path_MakePathL($FILE); };
       
  1256 		die $@ if $@;
       
  1257 		open FILE, ">$FILE" or die "WARNING: Can't open or create \"$FILE\"\n";
       
  1258 		print  FILE $Text or die "WARNING: Can't write text to \"$FILE\"\n";
       
  1259 		close FILE or die "WARNING: Can't close \"$FILE\"\n";
       
  1260 	}
       
  1261 }
       
  1262 
       
  1263 sub ABI () {
       
  1264 	$ABI;
       
  1265 }
       
  1266 sub AddSrc ($$) { # needs abs path for source
       
  1267 # allows modules to add a source file to the project and have it created if necessary
       
  1268 	my ($SRCFILE,$Text)=@_;
       
  1269 	my $SrcPath=&Path_Split('Path',$SRCFILE);
       
  1270 	my $CurFile=&Path_Split('File',$SRCFILE);
       
  1271 	my $BaseName=&Path_Split('Base',$SRCFILE);
       
  1272 	
       
  1273 	if ((not -e $SRCFILE) || (-M $SRCFILE > -M $MMPFILE)) {
       
  1274 		# only create the file if it's older than the .MMP file
       
  1275 		CreateExtraFile($SRCFILE,$Text);
       
  1276 	}
       
  1277 	 my %CurSource;
       
  1278 	 $CurSource{SrcPath}=$SrcPath;
       
  1279 	 $CurSource{CurFile}=$CurFile;
       
  1280 	 $CurSource{BaseTrg}=$BaseName;
       
  1281 	 push @SourceStruct, \%CurSource;
       
  1282 }
       
  1283 sub AddPlatMacros (@) {
       
  1284 # allows modules to add extra macros to the platform macro list
       
  1285 	push @{$Plat{Macros}},@_;
       
  1286 }
       
  1287 sub AifRef () {
       
  1288 	$CurAifRef;
       
  1289 }
       
  1290 sub AifStructRef () {
       
  1291 	\@AifStruct;
       
  1292 }
       
  1293 sub AllowDllData () {
       
  1294 	$AllowDllData;
       
  1295 }
       
  1296 sub CompressTarget () {
       
  1297 	$CompressTarget;
       
  1298 }
       
  1299 sub CompressTargetMode () {
       
  1300 	$CompressTargetMode;
       
  1301 }
       
  1302 sub BuildAsARM () {
       
  1303 	return 0 if $Options{ithumb};
       
  1304 	return 1 if $Options{iarm};
       
  1305 	$BuildAsARM;
       
  1306 }
       
  1307 sub ASSPLibList () {
       
  1308 	@ASSPLibList;
       
  1309 }
       
  1310 sub ASSPLinkPath () {
       
  1311 #	this is the path where the target looks for ASSP-specific import libraries
       
  1312 	my $Path=$Path{ASSPLink};
       
  1313 	if ($CurBld) {
       
  1314 		if ($Plat{OS} eq 'EPOC32') {
       
  1315 			$Path.="UREL\\";
       
  1316 		}
       
  1317 		else {
       
  1318 			$Path.="UDEB\\";
       
  1319 		}
       
  1320 	}
       
  1321 	$Path;
       
  1322 }
       
  1323 sub BaseMak () {
       
  1324 	&Path_Split('Base',$MAKEFILE);
       
  1325 }
       
  1326 sub BaseResrc () {
       
  1327 	&Path_Split('Base',$CurResrc);
       
  1328 }
       
  1329 sub BaseResrcList () {
       
  1330 	my @ResrcList=&ResrcList;
       
  1331 	my $Path;
       
  1332 	foreach $Path (@ResrcList) {
       
  1333 		$Path=&Path_Split('Base',$Path);
       
  1334 	}
       
  1335 	@ResrcList;
       
  1336 }
       
  1337 sub BaseSrc () {
       
  1338 	&Path_Split('Base',$CurSrc);
       
  1339 }
       
  1340 sub ExtSrc () {
       
  1341 	&Path_Split('Ext',$CurSrc);
       
  1342 }
       
  1343 sub BaseSrcList () {
       
  1344 	my @SrcList=&SrcList;
       
  1345 	my $Path;
       
  1346 	foreach $Path (@SrcList) {
       
  1347 		$Path=&Path_Split('Base',$Path);
       
  1348 	}
       
  1349 	@SrcList;
       
  1350 }
       
  1351 sub BaseSysResrcList () {
       
  1352 	my @SysResrcList=&SysResrcList;
       
  1353 	my $Path;
       
  1354 	foreach $Path (@SysResrcList) {
       
  1355 		$Path=&Path_Split('Base',$Path);
       
  1356 	}
       
  1357 	@SysResrcList;
       
  1358 }
       
  1359 sub BaseTrg () {
       
  1360 	&Path_Split('Base',$Trg);
       
  1361 }
       
  1362 sub BitMapRef () {
       
  1363 	$CurBitMapRef;
       
  1364 }
       
  1365 sub BitMapStructRef () {
       
  1366 	\@BitMapStruct;
       
  1367 }
       
  1368 sub Bld () {
       
  1369 	$CurBld;
       
  1370 }
       
  1371 sub BldList () {
       
  1372 	@{$Plat{Blds}};
       
  1373 }
       
  1374 sub BldPath () {
       
  1375 	my $Path=$Path{"Bld"};
       
  1376 	if ($CurBld) {
       
  1377 		$Path.=$FeatureVariantInfo{$CurBld."_LABEL"}."\\" if (%FeatureVariantInfo && !$FeatureVariantInfo{INVARIANT} && $FeatureVariantInfo{$CurBld."_LABEL"});
       
  1378 		$Path.="$CurBld\\";
       
  1379 	}
       
  1380 	$Path;
       
  1381 }
       
  1382 sub CallDllEntryPoints () {
       
  1383 	$CallDllEntryPoints;
       
  1384 }
       
  1385 sub Capability () {
       
  1386 	$Capability;
       
  1387 }
       
  1388 sub CapabilityFlags () {
       
  1389 	@CapabilityFlags;
       
  1390 }
       
  1391 sub DataLinkAddress () {
       
  1392 	$DataLinkAddress;
       
  1393 }
       
  1394 sub DataPath () {
       
  1395 	$E32env::Data{DataPath};
       
  1396 }
       
  1397 sub DebugLibList () {
       
  1398 	@DebugLibList;
       
  1399 }
       
  1400 sub DefFile () {
       
  1401 	"$Def{Path}$Def{Base}$Def{Ext}";
       
  1402 }
       
  1403 sub DefFileType () {
       
  1404 	$Plat{DefFile};
       
  1405 }
       
  1406 sub DepList () {
       
  1407 	sort @CurDepList;
       
  1408 }
       
  1409 sub Doc () {
       
  1410 	$CurDoc;
       
  1411 }
       
  1412 sub DocList () {
       
  1413 	if ($CurSrcPath) {
       
  1414 		return sort @{$DocHash{$CurSrcPath}};
       
  1415 	}
       
  1416 	my @DocList;
       
  1417 	my $Key;
       
  1418 	foreach $Key (keys %DocHash) {
       
  1419 		push @DocList,@{$DocHash{$Key}};
       
  1420 	}
       
  1421 	sort @DocList;
       
  1422 }
       
  1423 sub EPOCPath () {
       
  1424 	$E32env::Data{EPOCPath};
       
  1425 }
       
  1426 sub EPOCDataPath () {
       
  1427 	$E32env::Data{EPOCDataPath};
       
  1428 }
       
  1429 sub EPOCIncPath () {
       
  1430 	$E32env::Data{EPOCIncPath};
       
  1431 }
       
  1432 sub EPOCRelPath () {
       
  1433 	$E32env::Data{RelPath};
       
  1434 }
       
  1435 sub EPOCSecurePlatform () {
       
  1436 	$E32env::Data{SecurePlatform};
       
  1437 }
       
  1438 sub EPOCToolsPath () {
       
  1439 	$E32env::Data{EPOCToolsPath};
       
  1440 }
       
  1441 sub Exports () {
       
  1442 	@{$TrgType{Exports}{$Plat{"DefFile"}}};
       
  1443 }
       
  1444 sub ExportUnfrozen () {
       
  1445 	$ExportUnfrozen;
       
  1446 }
       
  1447 sub FirstLib () {
       
  1448 	$FirstLib;
       
  1449 }
       
  1450 sub FixedProcess () {
       
  1451 	$FixedProcess;
       
  1452 }
       
  1453 sub BasicTrgType () {
       
  1454 	$TrgType{Basic};
       
  1455 }
       
  1456 sub HeapSize () {
       
  1457 	%HeapSize;
       
  1458 }
       
  1459 sub LibList () {
       
  1460 	@LibList;
       
  1461 }
       
  1462 sub LibPath () {
       
  1463 #	this is the path where the target puts it's import library
       
  1464 	my $Path=$Path{Lib};
       
  1465 	if ($CurBld) {
       
  1466 		if (($Plat{DefFile} eq 'EABI') || ($Plat{DefFile} eq 'x86gcc') || ($Plat{OS} eq 'TOOLS2')) {
       
  1467 			$Path.="lib\\";
       
  1468 		}
       
  1469 		elsif ($Plat{OS} eq 'EPOC32') {
       
  1470 			$Path.="urel\\";
       
  1471 		}
       
  1472 		else {
       
  1473 			$Path.="udeb\\";
       
  1474 		}
       
  1475 	}
       
  1476 	$Path;
       
  1477 }
       
  1478 sub LinkAs () {
       
  1479 	$LinkAs;
       
  1480 }
       
  1481 sub LinkAsBase () {
       
  1482 	$LinkAsBase;
       
  1483 }
       
  1484 sub ExportLibrary () {
       
  1485 	$ExportLibrary;
       
  1486 }
       
  1487 sub NoExportLibrary () {
       
  1488 	$NoExportLibrary;
       
  1489 }
       
  1490 sub LinkPath () {
       
  1491 #	this is the place where the target looks for CPU-specific libraries
       
  1492 	my $Path=$Path{Link};
       
  1493 	if ($CurBld) {
       
  1494 		if ($Plat{DefFile} eq 'EABI' || $Plat{DefFile} eq 'x86gcc') {
       
  1495 			$Path.="LIB\\";
       
  1496 		}
       
  1497 		elsif ($Plat{OS} eq 'EPOC32') {
       
  1498 			$Path.="UREL\\";
       
  1499 		}
       
  1500 		else {
       
  1501 			$Path.="UDEB\\";
       
  1502 		}
       
  1503 	}
       
  1504 	$Path;
       
  1505 }
       
  1506 
       
  1507 sub MacroList ($) {
       
  1508 	if ($_[0]) {
       
  1509 	return @{$BldMacros{$_[0]}};
       
  1510 	}
       
  1511 	return @{$Plat{Macros}} unless $CurBld;
       
  1512 	(@{$Plat{Macros}},@{$BldMacros{$CurBld}});
       
  1513 }
       
  1514 
       
  1515 # returns the file containing Variant specific Macros
       
  1516 sub VariantFile($)
       
  1517 {
       
  1518     return $variantMacroHRHFile;
       
  1519 }
       
  1520 # returns the file containing Variant specific Macros, which may differ from the above if feature variants are used
       
  1521 sub ResourceVariantFile($)
       
  1522 {
       
  1523     return $ResourceVariantMacroHRHFile;
       
  1524 }
       
  1525 sub MakeFilePath () {
       
  1526 	&Path_Split('Path',$MAKEFILE);
       
  1527 }
       
  1528 sub MmpFile () {
       
  1529 	$MMPFILE;
       
  1530 }
       
  1531 sub PerlLibPath () {
       
  1532 	$PerlLibPath;
       
  1533 }
       
  1534 sub Plat () {
       
  1535 	$Plat{Real};
       
  1536 }
       
  1537 sub PlatABI () {
       
  1538 	$Plat{"ABI"};
       
  1539 }
       
  1540 sub PlatCompiler () {
       
  1541 	$Plat{"Compiler"};
       
  1542 }
       
  1543 sub PlatName () {
       
  1544 	$Plat{Name};
       
  1545 }
       
  1546 sub PlatOS () {
       
  1547 	$Plat{OS};
       
  1548 }
       
  1549 sub PlatOverrideList () {
       
  1550 	@PlatOverrideList;
       
  1551 }
       
  1552 sub ProcessPriority () {
       
  1553 	$ProcessPriority;
       
  1554 }
       
  1555 sub RelPath () {
       
  1556 	my $Path=$Path{Rel};
       
  1557 	if ($CurBld) {
       
  1558 		$Path .= lc($CurBld)."\\";
       
  1559 	}
       
  1560 	$Path;
       
  1561 }
       
  1562 sub ResourceRef () {
       
  1563 	$CurResourceRef;
       
  1564 }
       
  1565 sub ResourceStructRef () {
       
  1566 	\@ResourceStruct;
       
  1567 }
       
  1568 sub SetCurBld($) {
       
  1569 	$CurBld=$_[0];		# used by ide_cw.pm when handling additional platforms
       
  1570 }
       
  1571 sub	SetStdIncPaths (@) {
       
  1572 # allows module to set standard include paths
       
  1573 	@StdIncPaths=();
       
  1574 	my $Path;
       
  1575 	foreach $Path (@_) {
       
  1576 		$Path=~s-^(.*[^\\])$-$1\\-o if defined($Path);
       
  1577 		push @StdIncPaths, $Path;	# only place drive letters may appear, up to modules to handle
       
  1578 	}
       
  1579 }
       
  1580 sub Src () {
       
  1581 	$CurSrc;
       
  1582 }
       
  1583 sub SourceStructRef () {
       
  1584 	\@SourceStruct;		#array of references to hashes of SOURCEPATH => (filename1, filename2, ...)
       
  1585 	}
       
  1586 sub SrcList () {
       
  1587 	my @SrcList;
       
  1588     my $KeyRef;
       
  1589     foreach $KeyRef (@SourceStruct) {
       
  1590             push @SrcList,$$KeyRef{CurFile};
       
  1591            } 
       
  1592 	 @SrcList;
       
  1593 }
       
  1594 
       
  1595 sub SmpSafe () {
       
  1596 	$SmpSafe;
       
  1597 }
       
  1598 
       
  1599 sub StackSize () {
       
  1600 	$StackSize;
       
  1601 }
       
  1602 sub StatLibList () {
       
  1603 	@StatLibList;
       
  1604 }
       
  1605 sub StatLinkPath () {
       
  1606 	my $Path=$Path{StatLink};
       
  1607 	if ($CurBld) {
       
  1608 		$Path.="$CurBld\\";
       
  1609 	}
       
  1610 	$Path;
       
  1611 }
       
  1612 sub StdCpp () {
       
  1613 	$StdCpp;
       
  1614 }
       
  1615 sub NoStdCpp () {
       
  1616 	$NoStdCpp;
       
  1617 }
       
  1618 
       
  1619 sub NewLib () {
       
  1620 	$NewLib;
       
  1621 }
       
  1622 sub SetStatLinkPath($) {
       
  1623 	($Path{StatLink}) = @_;
       
  1624 }
       
  1625 sub SrcPath () {
       
  1626 	$CurSrcPath;
       
  1627 }
       
  1628 sub SysIncPaths () {
       
  1629 	@SysIncPaths;
       
  1630 }
       
  1631 sub ResourceSysIncPaths () {
       
  1632 	return @ResourceSysIncPaths;
       
  1633 }
       
  1634 sub Trg (;$) {
       
  1635 	# The optional $bld argument permits (U)DEB and (U)REL distinction in situations where $CurBld isn't set/relevant
       
  1636 	my ($bld) = @_;
       
  1637 	$bld = $CurBld if (!$bld);
       
  1638 
       
  1639 	return "" if !$Trg;
       
  1640 
       
  1641 	my $localTrg = $Trg;	
       
  1642 	my $vinfo = $FeatureVariantInfo{$bld."_LABEL"};
       
  1643 	$localTrg =~ s/(\.[^\.]+)$/\.$vinfo$1/ if ($bld && %FeatureVariantInfo && !$FeatureVariantInfo{INVARIANT} && $vinfo);
       
  1644 	return $localTrg;
       
  1645 }
       
  1646 sub TrgPath () {
       
  1647 	$TrgType{Path};
       
  1648 }
       
  1649 sub TrgType () {
       
  1650 	$TrgType{Name};
       
  1651 }
       
  1652 # this can probably go as its always 0 now
       
  1653 sub KernelTrg () {
       
  1654 	$TrgType{Kernel};
       
  1655 }
       
  1656 sub SystemTrg () {
       
  1657 	$TrgType{System};
       
  1658 }
       
  1659 sub UidList () {
       
  1660 	@UidList;
       
  1661 }
       
  1662 sub UserIncPaths () {
       
  1663 	@UserIncPaths;
       
  1664 }
       
  1665 sub SrcDbg () {
       
  1666 	$SrcDbg;
       
  1667 }
       
  1668 sub CompilerOption
       
  1669 {
       
  1670 	my $CompOption=$WarningLevel{$_[0]};
       
  1671 	$CompOption="" if (!defined($CompOption)); 
       
  1672 	$CompOption;
       
  1673 }
       
  1674 sub LinkerOption
       
  1675 {
       
  1676     my $lnkOption = $LinkerOptions{$_[0]};
       
  1677     $lnkOption="" if (!defined($lnkOption));
       
  1678     $lnkOption;
       
  1679 }
       
  1680 
       
  1681 sub PlatRec () {
       
  1682 	%Plat;
       
  1683 }
       
  1684 
       
  1685 sub Version() {
       
  1686 	%Version;
       
  1687 }
       
  1688 
       
  1689 sub SecureId() {
       
  1690 	$SecureId;
       
  1691 }
       
  1692 
       
  1693 sub VendorId () {
       
  1694 	$VendorId;
       
  1695 }
       
  1696 
       
  1697 sub EABIDef () {
       
  1698 	$EABIDef;
       
  1699 }
       
  1700 
       
  1701 sub ReplaceOptions () {
       
  1702 	my @ReplacementOptions = ();
       
  1703 	if (defined($ReplaceOptions{$_[0]}))
       
  1704 	{
       
  1705 		@ReplacementOptions=@{$ReplaceOptions{$_[0]}};
       
  1706 	}	
       
  1707 	@ReplacementOptions;
       
  1708 }
       
  1709 
       
  1710 sub ARMFPU () {
       
  1711 	$ARMFPU;
       
  1712 }
       
  1713 
       
  1714 sub IsDebuggable () {
       
  1715 	$IsDebuggable;
       
  1716 }
       
  1717 
       
  1718 sub PlatTxt2D () {
       
  1719 	@PlatTxt2D;
       
  1720 }
       
  1721 
       
  1722 sub ToolChain () {
       
  1723 	my $ToolChain = $TruePlat{Toolchain};
       
  1724 	$ToolChain ="" if(!defined ($TruePlat{Toolchain}) );
       
  1725 	$ToolChain;
       
  1726 }
       
  1727 
       
  1728 sub StringTables () 
       
  1729 {
       
  1730 	@StringTable;
       
  1731 }
       
  1732 
       
  1733 
       
  1734 #This generates and adds the generated source of the stringtable to the source list so it's included in the binary.
       
  1735 sub AddStringTables ()
       
  1736 {
       
  1737 	if(@StringTable)
       
  1738 	{
       
  1739 		foreach my $stringtable (@StringTable)
       
  1740 		{
       
  1741 			my %genSrcHash;
       
  1742 
       
  1743 			$genSrcHash{SrcPath} = $Path{Bld};
       
  1744 			$genSrcHash{CurFile} = $stringtable->{BaseTrg}.".cpp";
       
  1745 			$genSrcHash{BaseTrg} = $stringtable->{BaseTrg};
       
  1746 
       
  1747 			push(@SourceStruct, \%genSrcHash) if !$stringtable->{Hdronly};
       
  1748 
       
  1749 			# Execute it now.  This can probably be moved into the makefile by adding a suitable rule
       
  1750 			# to ensure the resource file is generated before the source tries to #include it.
       
  1751 			my $stPath = $Path{Bld};
       
  1752 
       
  1753 			my $stCpp = $stringtable->{BaseTrg}.".cpp";
       
  1754 			my $stHeader = lc($stringtable->{BaseTrg}).".h";
       
  1755 			my $stFile = $stringtable->{STFile};
       
  1756 			my $stOrigin = $stringtable->{STPath};
       
  1757 			system("perl -S ecopyfile.pl $stOrigin$stFile $stPath$stFile");
       
  1758 			system("perl -S stringtable.pl $stPath$stFile");
       
  1759 
       
  1760 			#If it's an exported header we'll need to export it.
       
  1761 			if(defined $stringtable->{ExportPath}) 
       
  1762 			{
       
  1763 				my $exportpath = $stringtable->{ExportPath};
       
  1764 
       
  1765 				system("perl -S ecopyfile.pl $stPath$stHeader $exportpath\\$stHeader");
       
  1766 
       
  1767 				push(@UserIncPaths, $exportpath);
       
  1768 				push(@StringTableUserIncPaths, $exportpath);
       
  1769 			}
       
  1770 			#otherwise we just need the path of the generated header to be added 'userinclude'.
       
  1771 			else 
       
  1772 			{
       
  1773 				push(@UserIncPaths, $Path{Bld});
       
  1774 				push(@StringTableUserIncPaths, $Path{Bld});
       
  1775 			}
       
  1776 		}
       
  1777 	}
       
  1778 }
       
  1779 
       
  1780 sub CheckSourceMMPMetaData () {
       
  1781 	%CheckSourceMMPMetaData;
       
  1782 }
       
  1783 
       
  1784 sub CheckSourceMMPIncludes () {
       
  1785 	%CheckSourceMMPIncludes;
       
  1786 }
       
  1787 
       
  1788 sub CheckSourceURELIncludes () {
       
  1789 	%CheckSourceURELIncludes;
       
  1790 }
       
  1791 
       
  1792 sub CheckSourceUDEBIncludes () {
       
  1793 	%CheckSourceUDEBIncludes;
       
  1794 }
       
  1795 
       
  1796 sub CodePagingTargetMode() {
       
  1797 	$CodePagingTargetMode;
       
  1798 }
       
  1799 
       
  1800 sub DataPagingTargetMode() {
       
  1801 	$DataPagingTargetMode;
       
  1802 }
       
  1803 
       
  1804 sub DebugSwitchUsed () {
       
  1805 	return 1 if (defined $DebugSwitch);
       
  1806 	return 0;
       
  1807 }
       
  1808 
       
  1809 sub SymbolicDebugEnabled () {
       
  1810 	return $DebugSwitch;
       
  1811 }
       
  1812 
       
  1813 sub IsFunctionCallLogging() {
       
  1814 	$Options{logfc};
       
  1815 }
       
  1816 
       
  1817 sub IsWideCharMain() {
       
  1818 	return $IsWideCharMain;
       
  1819 }
       
  1820 
       
  1821 sub MmpMacros(){
       
  1822 	my @mmpMacros=&Mmp_Macros;
       
  1823 	return @mmpMacros;
       
  1824 }
       
  1825 
       
  1826 sub FeatureVariantInfo()
       
  1827 	{
       
  1828 	return %FeatureVariantInfo;
       
  1829 	}
       
  1830 
       
  1831 sub FeatureVariantVMapFile()
       
  1832 	{
       
  1833 	return "" if !%FeatureVariantInfo || defined $FeatureVariantInfo{INVARIANT};
       
  1834 
       
  1835 	my $target = RelPath().Trg();
       
  1836 	$target =~ s/\.$FeatureVariantInfo{$CurBld."_LABEL"}//;
       
  1837 # modified by SV start: makefile improvement 
       
  1838 	my $vmap = $target. "." . $FeatureVariantInfo{NAME}.".vmap";
       
  1839 # modified by SV end: makefile improvement 
       
  1840 
       
  1841 	eval { &Path_MakePathL($vmap); };	
       
  1842 
       
  1843 	if (featurevariantmap->Save($target, $FeatureVariantInfo{$CurBld."_LABEL"}, $FeatureVariantInfo{NAME}, $FeatureVariantInfo{$CurBld."_FEATURES"}, &Mmp_IsFeatureVariant ? [ 'FEATUREVARIANT' ] : undef))
       
  1844 		{
       
  1845 		die "ERROR: Couldn't create feature variant map file \"$vmap\".\n";
       
  1846 		}
       
  1847 
       
  1848 	return $vmap;
       
  1849 	}
       
  1850 
       
  1851 sub FeatureVariantBaseTrg()
       
  1852 	{
       
  1853 	# In some situations, for example .sym files, we need a feature variant tagged name
       
  1854 	# based on the normal BaseTrg i.e. root target name but minus extension.
       
  1855 	my $localBaseTrg = BaseTrg();
       
  1856 		
       
  1857 	if (%FeatureVariantInfo && !defined $FeatureVariantInfo{INVARIANT})
       
  1858 		{
       
  1859 		$localBaseTrg .= ".".$FeatureVariantInfo{$CurBld."_LABEL"};
       
  1860 		}
       
  1861 
       
  1862 	return $localBaseTrg;
       
  1863 	}
       
  1864 
       
  1865 sub CommandFile()
       
  1866 	{
       
  1867 	my $plat = Plat();	
       
  1868 	$plat .= ".$FeatureVariantInfo{NAME}" if %FeatureVariantInfo;
       
  1869 	return MakeFilePath().BaseTrg().".$plat.".Bld().".objects.via";
       
  1870 	}
       
  1871 
       
  1872 #Compiler wrapper option support
       
  1873 sub CompilerWrapperOption()
       
  1874 {
       
  1875   # Return 1 if compiler wrapper option option(-wrap) is specified else return 0	
       
  1876   $IsCompilerWrapperOption;
       
  1877 }
       
  1878 
       
  1879 #Proxy wrapper option support
       
  1880 sub ProxyWrapperOption()
       
  1881 {
       
  1882   # Return 1 if compiler wrapper option option(-wrap) is specified else return 0	
       
  1883   $IsProxyWrapperOption;
       
  1884 }
       
  1885 # modified start: makefile improvement 
       
  1886 sub getSrcSet()
       
  1887 {
       
  1888 	return \%CurSrcSet;
       
  1889 }
       
  1890 # modified end: makefile improvement 
       
  1891 
       
  1892 #1 = STDCPP support is available
       
  1893 #others = STDCPP support is not available
       
  1894 my $stdcppsupport;
       
  1895 
       
  1896 #STDCPP support check (SYMBIAN_OE_LIBSTDCPP)
       
  1897 #return non-zero means STDCPP support is available,
       
  1898 #otherwise it's not available
       
  1899 sub StdCppSupport()
       
  1900 {
       
  1901 	return $stdcppsupport if (defined $stdcppsupport);
       
  1902 	
       
  1903 	my @hrhMacros = &Variant_GetMacroList;
       
  1904 	if (grep /^\s*SYMBIAN_OE_LIBSTDCPP\s*$/, @hrhMacros)
       
  1905 	{
       
  1906 		$stdcppsupport = 1;
       
  1907 	}
       
  1908 	else
       
  1909 	{
       
  1910 	    $stdcppsupport = 0;
       
  1911 	}
       
  1912 	
       
  1913 	return $stdcppsupport;
       
  1914 }