sbsv1/abld/makmake/makmake.pl
changeset 599 fa7a3cc6effd
child 626 ac03b93ca9c4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv1/abld/makmake/makmake.pl	Fri Jun 25 17:29:25 2010 +0800
@@ -0,0 +1,1901 @@
+# Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# all variables called *Path* are set up to end with a backslash
+# all variables called *Path or *File are stored as absolute (file)paths within makmake
+# all variables called UpPath* are stored as relative paths within makmake
+# 
+#
+
+
+use FindBin;		# for FindBin::Bin
+use Getopt::Long;
+use Cwd;
+# modified start: makefile improvement 
+use File::stat;
+use Time::localtime;
+# modified end: makefile improvement 
+
+my $PerlLibPath;    # fully qualified pathname of the directory containing our Perl modules
+
+# Prototype to remove warning.
+sub AddStringTables();
+
+BEGIN {
+# check user has a version of perl that will cope
+	require 5.005_03;
+# establish the path to the Perl libraries: currently the same directory as this script
+	$PerlLibPath = $FindBin::Bin;	# X:/epoc32/tools
+	$PerlLibPath =~ s/\//\\/g;	# X:\epoc32\tools
+	$PerlLibPath .= "\\";
+}
+
+use lib $PerlLibPath;
+use E32env;
+use E32Plat;
+use E32Variant;
+use Genutl;
+use Modload;
+use Pathutl;
+use Trgtype;
+use CheckSource;
+use featurevariantparser;
+use featurevariantmap;
+
+# THE MAIN PROGRAM SECTION
+##########################
+
+{
+	Load_SetModulePath($PerlLibPath);
+	Plat_Init($PerlLibPath);
+}
+
+my $MAKEFILE;
+my $MMPFILE;
+my %Options;
+my %Plat;
+my %TruePlat;
+my %BldMacros;
+my $PlatArg;
+my @PlatOverrideList=();
+my $EABIDef;
+my $DebugSwitch=undef;
+
+my $IsCompilerWrapperOption = 0;
+my $IsProxyWrapperOption = 0;
+my $FeatureVariantArg;
+my %FeatureVariantInfo;
+
+{
+	# process the command line
+	unless (GetOptions(\%Options, 'd', 'mmp', 'plat=s', 'v', 'arm', 'nd' , 'ithumb' , 'iarm' , 'debug', 'no_debug', 'logfc','wrap:s')) {
+		exit 1;
+	}
+	#Update the variable to set the information of -wrap option
+	if(exists($Options{wrap})) {
+		if ($Options{wrap} eq "") {
+			# Set the Compiler wrapper option information i.e. '1'
+			$IsCompilerWrapperOption = 1;
+		} elsif ($Options{wrap} eq "proxy") {
+			$IsProxyWrapperOption = 1;
+		} else {
+			print "WARNING: Invalid value for option -wrap: $Options{wrap}\n";
+		}
+	}
+	
+	$Options{makemakefile}='1' unless ($Options{mmp} || $Options{plat});
+
+	if ($Options{mmp} or $Options{plat}) {
+		eval { &Load_ModuleL('MAKHELP'); };
+		die $@ if $@;
+	}
+
+	if ($Options{mmp}) {
+		&Help_Mmp;
+		exit;
+	}
+
+	if ($Options{plat}) {
+		eval { &Plat_GetL($Options{plat},\%Plat,\%BldMacros); };
+		die $@ if $@;
+		eval { &Load_ModuleL($Plat{MakeMod}); };
+		die $@ if $@;
+		&Help_Plat($Plat{Real},$Plat{CPU}, $Plat{DefFile}, \@{$Plat{MmpMacros}},\@{$Plat{Macros}});
+		exit;
+	}
+
+#	show help & exit if necessary
+	if (@ARGV != 2) {
+		&Usage();
+	}
+	if ($Options{v}) {
+		print "perl -S makmake.pl @ARGV\n";
+		&Load_SetVerbose;
+		&Path_SetVerbose;
+		&Plat_SetVerbose;
+	}
+
+	$PlatArg=uc pop @ARGV;
+
+	# Process build platform arguments where they differ from the "norm"
+	if ($PlatArg=~/^(\S+)\.(\S+)$/)
+		{
+		# Explicit feature variant platforms take the form <base platform>.<variant name>
+		# e.g. armv5.variant1
+		$PlatArg=$1;
+		$FeatureVariantArg=$2;
+		}
+	elsif ($PlatArg=~/^(\S+):(\S+)$/)
+		{
+		# IDE platforms can take the form cw_ide:<platform-1>+<platform-2>+<platform-n>
+		# e.g. cw_ide:plat1+plat2+plat3
+		# 			
+		$PlatArg=$1;
+		@PlatOverrideList=split(/\+/,$2);
+		}
+
+	eval { &Plat_GetL($PlatArg,\%TruePlat,\%BldMacros); };
+	die $@ if $@;
+	if (scalar @PlatOverrideList) {
+		$PlatArg=$PlatOverrideList[0];
+	}
+
+	
+	$MMPFILE=pop @ARGV;
+	die "ERROR: Can't specify MMP file on a different drive\n" if $MMPFILE=~/^\w:\\/o;
+	if ($MMPFILE!~/.MMP$/io) {
+		$MMPFILE.='.MMP';
+	}
+	$MMPFILE=&Path_AbsToWork($MMPFILE);
+
+	eval { &Load_ModuleL('Mmp'); };
+	die $@ if $@;
+	if ($Options{v}) {
+		&Mmp_SetVerbose;
+	}
+	if ($Options{d}) {
+		die "ERROR: $E32env::Data{EPOCPath} does not exist\n" if (!-d $E32env::Data{EPOCPath});
+	}
+	
+	if ($Options{debug}) {
+		$DebugSwitch = 1;
+	}
+	elsif($Options{no_debug}){
+		$DebugSwitch = 0;
+	}
+}
+
+my %LinkerOptions;
+my %WarningLevel;
+my $ABI;
+my @AifStruct;
+my $AllowDllData;
+my $CompressTarget;
+my $CompressTargetMode;   #NONE
+my $ASSPExports;
+my @ASSPLibList;
+my @BitMapStruct;
+my $BuildAsARM=$Options{arm};
+my $CallDllEntryPoints;
+my $Capability;
+my @CapabilityFlags;
+my $DataLinkAddress;
+my @DebugLibList;
+my %Def;
+my %DocHash;
+my $ExportUnfrozen;
+my $FirstLib;
+my $FixedProcess;
+my %HeapSize;
+my @LibList;
+my $LinkAs;
+my $LinkAsBase;
+my $ExportLibrary;
+my $NoExportLibrary;
+my %MmpFlag;
+my @PlatTxt2D;
+my $ProcessPriority;
+my @RamTargets;
+my @ResourceStruct;
+my @RomTargets;
+my $SmpSafe;
+my @SourceStruct;
+my $StackSize;
+my @StatLibList;    
+my $StdCpp;
+my $NoStdCpp;
+my $NewLib;
+my @SysIncPaths;
+my @ResourceSysIncPaths;
+my $ResourceVariantMacroHRHFile;
+my $Trg;
+my %TrgType;
+my @UidList;
+my @UserIncPaths;
+my $SrcDbg;
+my %Path;
+my %Version;
+my $SecureId;
+my $VendorId;
+my $variantMacroHRHFile = Variant_GetMacroHRHFile();  # HRH file containing macros specific to a variant
+my %ReplaceOptions;
+my $ARMFPU;
+my @StringTable;
+my @StringTableUserIncPaths;
+my $CodePagingTargetMode;	# 0-N/A, 1-UNPAGED, 2-PAGED
+my $DataPagingTargetMode;	# 0-N/A, 1-UNPAGED, 2-PAGED
+my %CheckSourceUDEBIncludes;
+my %CheckSourceURELIncludes;
+my %CheckSourceMMPMetaData;
+my %CheckSourceMMPIncludes;
+my $IsWideCharMain=0;
+my $IsDebuggable; # 0-NONDEBUGGABLE, 1-DEBUGGABLE, 2-DEBUGGABLE_UDEBONLY
+
+
+use constant NOTPAGED => 0;
+use constant UNPAGED => 1;
+use constant PAGED => 2;
+
+use constant INFLATECOMPRESSIONMETHOD => 1;
+use constant BYTEPAIRCOMPRESSIONMETHOD => 2;
+
+use constant NOTDEBUGGABLE => 0;
+use constant DEBUGGABLE =>  1;
+use constant DEBUGGABLE_UDEBONLY => 2;
+
+# If the platform does support feature variants but none are specified, then we assume the use of "DEFAULT" if it exists
+# If default doesn't exist feature variantion is basically disabled?
+$FeatureVariantArg = 'default' if (!$FeatureVariantArg && defined &PMSupportsFeatureVariants && featurevariantparser->DefaultExists());
+
+# Preload the details of the variant requested if any - we need the HRH file for MMP file processing
+if ($FeatureVariantArg)
+	{
+	# First check the feature variant is valid
+	my @buildableFeatureVariants = featurevariantparser->GetBuildableFeatureVariants();
+	die "ERROR: \"$PlatArg.$FeatureVariantArg\" feature variant is either invalid or virtual.\n" if !(grep /^$FeatureVariantArg$/i, @buildableFeatureVariants);
+
+	# Now load the variant
+	%FeatureVariantInfo = featurevariantparser->GetVariant($FeatureVariantArg);
+	
+	# Change the HRH file to use
+	$variantMacroHRHFile = $FeatureVariantInfo{VARIANT_HRH} if $FeatureVariantInfo{VARIANT_HRH};
+	}
+	
+&SetVarsFromMmp($PlatArg);
+die $@ if $@;
+
+{
+	# set up the makefile filepath - need to do this before loading the platform module
+	# because UID source file will be added and set up in the makefile path under WINS
+	if ($Options{d}) {
+		$MAKEFILE=join ('', $Path{Bld}, &Path_Split('Base',$MMPFILE), $TruePlat{Ext});
+	}
+	else {
+		$MAKEFILE=join "", &Path_WorkPath, &Path_Split('Base',$MMPFILE), $TruePlat{Ext};
+	}
+}
+
+{
+	# Generate an X86GCC def file from eabi def file in build dir if needed
+	if (($PlatArg eq "X86GCC" || $PlatArg eq "X86GMP") && $Def{Base} && not -e &DefFile)
+	{
+		# Find the equivalent eabi def file
+		my $eabiDefFile = File::Spec->canonpath("$Def{Path}../eabi/$Def{Base}$Def{Ext}");
+		if (-e $eabiDefFile)
+		{
+			# Need to create MAKEFILE directory early in this case
+			eval { &Path_MakePathL($MAKEFILE); };
+			die $@ if $@;
+			# Change def file path to build path 
+			$Def{Path} = $Path{Bld};
+			&generateX86GCCDefFile($eabiDefFile, &DefFile);
+		}
+		else
+		{
+			print "WARNING: Unable to find EABI def file at $eabiDefFile to generate X86GCC def file with\n";
+		}
+	}
+}
+
+{
+
+
+#	load the platform module
+	eval { &Load_ModuleL($TruePlat{MakeMod}); };
+	die $@ if $@;
+
+	unless (defined &PMHelp_Mmp) {
+#		check this function is defined - all modules must have it - if not perhaps the
+#		platform module has not loaded is compiler module successfully via "use"
+		die "ERROR: Module \"$Plat{MakeMod}\" not loaded successfully\n";
+	}
+}
+
+	# Allow the platform to bow out if feature variants have been specified but it doesn't support them
+	if ($FeatureVariantArg && !defined &PMSupportsFeatureVariants)
+		{
+		die "ERROR: The \"$PlatArg\" platform does not support feature variants.\n";
+		}
+
+{
+	# allow the platform to bow out if it can't support some .MMP file specifications
+	if (defined &PMCheckPlatformL) {
+		eval { &PMCheckPlatformL(); };
+		die $@ if $@;
+	}
+}
+
+my @StdIncPaths=();
+
+{
+	# get the platform module to do it's mmpfile processing - WINS modules may set up an extra source file
+	# for UIDs here depending upon the targettype
+	&PMPlatProcessMmp(@PlatTxt2D) if defined &PMPlatProcessMmp;
+}
+
+%CheckSourceMMPMetaData = &Mmp_CheckSourceMMPMetaData();
+%CheckSourceMMPIncludes = &Mmp_CheckSourceMMPIncludes();
+
+# merge checksource processing from platform specific .mmp sections, if applicable
+%CheckSourceMMPMetaData = (%CheckSourceMMPMetaData, &PMPlatCheckSource()) if defined &PMPlatCheckSource;
+
+@ResourceSysIncPaths = @SysIncPaths;
+$ResourceVariantMacroHRHFile = $variantMacroHRHFile;
+
+AddStringTables();
+
+# Process feature variants if applicable
+
+if ($FeatureVariantArg)
+	{
+	if ($Options{v})
+		{
+		$featurevariantmap::verbose = 1;
+		$featurevariantparser::verbose = 1;
+		}
+
+	# Get the default variant details
+	my %DefaultFeatureVariantInfo = $FeatureVariantInfo{NAME} =~ /^default$/i ? %FeatureVariantInfo : featurevariantparser->GetVariant("DEFAULT");	
+	die "ERROR: Feature variant \"$PlatArg.default\" is invalid.\n" if !$DefaultFeatureVariantInfo{VALID};
+
+	# The following IF statement decides whether to use the default variant and not use the hash in the filename 
+	# This prevents the generation of dll's/exe's for which variants are not needed (i.e they are invariant)
+	# It also avoids the time-consuming and redundant hash generation
+	# A component is considered invariant if it's not a DLL or EXE or FEATUREVARIANT isn't present in the .mmp file
+	
+# modified start: makefile improvement 
+	if ($TrgType{Basic} =~ /^(EXEDLL|EXE|DLL|LIB)$/ && &Mmp_IsFeatureVariant)
+# modified end: makefile improvement 
+		{
+		# Load the requested variant if it hasn't already been preloaded		
+		%FeatureVariantInfo = featurevariantparser->GetVariant($FeatureVariantArg) if !$FeatureVariantInfo{NAME} || $FeatureVariantInfo{NAME} ne $FeatureVariantArg;
+		}
+	else
+		{
+		# Use the default variant
+		%FeatureVariantInfo = %DefaultFeatureVariantInfo;
+		$FeatureVariantInfo{INVARIANT} = 1;
+		$FeatureVariantInfo{NAME} = uc $FeatureVariantArg;
+		}
+
+	die "ERROR: Feature variant \"$PlatArg.$FeatureVariantInfo{NAME}\" is invalid.\n" if !$FeatureVariantInfo{VALID};
+	
+	my @featureVariantSysIncPaths = (@{$FeatureVariantInfo{BUILD_INCLUDES}},@SysIncPaths);
+	
+	# Further process paths and filenames so that they include a drive letter.
+	# We store this in a hash specifically for passing on to featurevariantmap->Hash
+	
+	my @processedIncludes = &Path_PrefixWithDrive(&Path_Chop(@UserIncPaths), &Path_Chop(@featureVariantSysIncPaths));
+	push @processedIncludes, &Path_Chop(&PMToolChainIncDir) if defined &PMToolChainIncDir && &PMToolChainIncDir;
+	
+	my $processedPreInclude = "";
+	if (defined &PMPrefixFile)
+		{
+		$processedPreInclude = &PMPrefixFile;
+		$processedPreInclude =~ s/\"//g;
+		$processedPreInclude = &Path_PrefixWithDrive($processedPreInclude);		
+		}
+
+	my %processedFeatureVariantInfo;
+	$processedFeatureVariantInfo{PREINCLUDE} = $processedPreInclude if $processedPreInclude;
+	$processedFeatureVariantInfo{BUILD_INCLUDES} = \@processedIncludes if @processedIncludes;
+	$processedFeatureVariantInfo{VALID} = 1;
+	
+	# Pass in the details of the macros tested in the MMP
+	$processedFeatureVariantInfo{MMPTESTED} = &Mmp_TestedMacros();
+
+	my @pathedSrcList = ();
+	push @pathedSrcList, Path_PrefixWithDrive($$_{SrcPath}.$$_{CurFile}) foreach (@SourceStruct);
+
+	foreach my $bld (@{$Plat{Blds}})
+		{
+# modified start: makefile improvement 
+		my @reusedHash;
+# modified end: makefile improvement 
+		if ($FeatureVariantInfo{INVARIANT})															# Invariant override
+			{
+			$FeatureVariantInfo{$bld."_LABEL"} = "INVARIANT";
+			}
+		else
+			{
+# modified by SV start: makefile improvement 
+			my $vmap = "$E32env::Data{RelPath}".lc($Plat{Real})."\\".lc($bld)."\\".Trg()."." . $FeatureVariantInfo{NAME}.".vmap";
+# modified by SV end: makefile improvement 
+			$vmap = Path_PrefixWithDrive($vmap);
+			if(-e $vmap){
+				my @variantlist = featurevariantmap->GetVariantListFromVmap($vmap);
+				my @calls;
+				foreach(@variantlist)
+				{
+					my $target = "CHECKVMAP".uc($bld);
+					my $makefile = $MAKEFILE.".".$_;
+					if(-e $makefile){
+						push @calls, "make -r -f \"$makefile\"  $target";
+					}
+				}
+				foreach my $call (@calls)
+				{
+					print "call: $call" if $Options{v};
+					open PIPE, "$call |";
+					while(<PIPE>) {
+						print $_;
+					}
+					close PIPE;
+				}
+				if(-e $vmap){
+					@reusedHash = featurevariantmap->CheckOldVmapFile($vmap, \%FeatureVariantInfo);
+				}
+			}
+			if(defined(@reusedHash))
+			{
+				$FeatureVariantInfo{$bld."_LABEL"} = $reusedHash[0];
+				$FeatureVariantInfo{$bld."_FEATURES"} = $reusedHash[1];
+				next;
+			}
+# modified end: makefile improvement 
+			my @macros = (@{$Plat{Macros}}, @{$BldMacros{$bld}}, "__SUPPORT_CPP_EXCEPTIONS__");
+			push @macros, "__PRODUCT_INCLUDE__=\"".&Path_PrefixWithDrive($FeatureVariantInfo{VARIANT_HRH})."\"" if $FeatureVariantInfo{VARIANT_HRH};
+			$processedFeatureVariantInfo{MACROS} = \@macros;
+
+			print ("Feature variant hash processing: \"$FeatureVariantInfo{NAME} $bld\"\n") if $Options{v};
+			
+			my @result = featurevariantmap->HashAndFeatures(\@pathedSrcList, \%processedFeatureVariantInfo);
+			$FeatureVariantInfo{$bld."_LABEL"} = $result[0];
+			$FeatureVariantInfo{$bld."_FEATURES"} = $result[1];
+			
+			die "ERROR: Can't obtain hash for \"$PlatArg.$FeatureVariantInfo{NAME}\" feature variant.\n" if !$FeatureVariantInfo{$bld."_LABEL"};
+			}
+		}
+
+	# Customise standard content based on feature variant updates
+	@SysIncPaths = @featureVariantSysIncPaths;
+	$variantMacroHRHFile = $FeatureVariantInfo{VARIANT_HRH};
+	$MAKEFILE .= ".$FeatureVariantInfo{NAME}";
+
+	# Resources are always processed in the context of the default variant's system include and variant files when
+	# feature variants are in use
+	@ResourceSysIncPaths = (@{$DefaultFeatureVariantInfo{BUILD_INCLUDES}},@ResourceSysIncPaths);
+	$ResourceVariantMacroHRHFile = $DefaultFeatureVariantInfo{VARIANT_HRH};
+	}
+
+
+{
+	# if verbose mode set, output some info
+	#--------------------------------------
+	if ($Options{v}) {
+		print  
+			"Target: \"$Trg\"\n",
+			"TargetType: \"$TrgType{Name}\"\n",
+			"Libraries: \"@LibList\"\n",
+			"Debug Libraries: \"@DebugLibList\"\n",
+			"Static Libraries: \"@StatLibList\"\n",
+			"Uids: \"@UidList\"\n",
+			"BuildVariants: \"@{$Plat{Blds}}\"\n",
+			"TargetMakeFile: \"$MAKEFILE\"\n",
+			"UserIncludes: \"<Source Dir> @UserIncPaths\"\n",
+			"SystemIncludes: \"@SysIncPaths\"\n"
+		;
+
+	if (%FeatureVariantInfo)
+		{
+		print 
+			"Feature Variant Name: \"$FeatureVariantInfo{NAME}\"\n",
+			"Feature Variant SystemIncludes: \"@{$FeatureVariantInfo{BUILD_INCLUDES}}\"\n",
+			"Feature Variant HRH file: \"$FeatureVariantInfo{VARIANT_HRH}\"\n";
+
+		foreach my $bld (@{$Plat{Blds}})
+			{
+			print "Feature Variant $bld Label: \"".$FeatureVariantInfo{$bld."_LABEL"}."\"\n";			
+			}
+		
+		}
+	}
+}
+
+# Special handling for non-default invariant makefiles without FEATUREVARIANT in the MMP file
+# In this situation the default variant makefle is just included into the variant makefile
+# modified start: makefile improvement 
+if ($TrgType{Basic} =~ /^(EXEDLL|EXE|DLL|LIB)$/ && %FeatureVariantInfo && $FeatureVariantInfo{INVARIANT})
+	{
+	$MAKEFILE =~ s/([^.]*$)/DEFAULT/;
+# modified by SV start: makefile improvement 
+		if( $FeatureVariantInfo{NAME} !~ /^default$/i)
+			{
+				print "not creating makefile for  : $FeatureVariantInfo{NAME}\n" if ($Options{v});
+			}
+# modified by SV end: makefile improvement 
+	if(-e $MAKEFILE )
+		{
+		my $mmp_time = -M $MMPFILE;
+		my $makefile_time = -M $MAKEFILE;
+		if( $makefile_time <= $mmp_time)
+			{
+			exit;
+			}
+		}
+	undef %FeatureVariantInfo;
+	%FeatureVariantInfo = featurevariantparser->GetVariant("default");
+	$FeatureVariantInfo{INVARIANT} = 1;
+	$FeatureVariantInfo{UREL_LABEL} = 'INVARIANT';
+	$FeatureVariantInfo{UDEB_LABEL} = 'INVARIANT';
+	}
+# modified by SV start: makefile improvement 
+	elsif(%FeatureVariantInfo)
+	{
+	my $variant_info = &Path_Chop($E32env::Data{BldPath}).$Path{BldInfPath}."\\FeatureVariantInfo\\".$Plat{Real}."\\".$Plat{Real}.".".$FeatureVariantInfo{NAME}.".".&Path_Split('Base', $MMPFILE).".info";
+	#if mmp file does not exists
+	$variant_info = &Path_Chop($E32env::Data{BldPath}).$Path{BldInfPath}."\\FeatureVariantInfo\\".$Plat{Real}."\\".$Plat{Real}.".".$FeatureVariantInfo{NAME}.".info" if ! -e $MMPFILE;
+# modified by SV end: makefile improvement 
+	my $variant_key = "VARIANT_PLAT_NAME_".&Path_Split('Base', $MMPFILE);
+	$variant_info_new = $variant_info.".tmp";
+	open VARIANTINFOR_NEW, ">$variant_info_new" or die "ERROR: Can't open or create file \"$variant_info_new\"\n";
+
+	# Open the variant infor file
+	open VARIANTINFOR, "<$variant_info" or die "ERROR: Can't open file \"$variant_info\"\n";
+	while(<VARIANTINFOR>)
+		{
+		if(/^$variant_key/)
+			{
+			print VARIANTINFOR_NEW $variant_key.":=".$FeatureVariantInfo{NAME}."\n";
+			}
+			else
+			{
+			print VARIANTINFOR_NEW $_;
+			}
+		}
+	# Close and cleanup
+	close VARIANTINFOR or die "ERROR: Can't close file \"$variant_info\"\n";
+	close VARIANTINFOR_NEW or die "ERROR: Can't close file \"$variant_info\"\n";
+	unlink $variant_info;
+	rename($variant_info_new, $variant_info);
+	if ($Options{v}) {
+		print "Successful Variant Infor File Creation\n";
+
+		}
+	}
+# modified end: makefile improvement 
+
+my $CurAifRef;
+my $CurBaseObj;
+my $CurBld;
+my $CurBitMapRef;
+my @CurDepList;
+my $CurDoc;
+my $CurResrc;
+my $CurResourceRef;
+my $CurSrc;
+my $CurSrcPath;
+my $ResrcIsSys;
+# modified start: makefile improvement 
+my %CurSrcSet;
+# modified end: makefile improvement 
+
+# Set up library paths getting the backend module to help if it wants to
+{
+	&InitLinkPaths();
+}
+
+{
+
+	# LOOPING SECTION
+	#----------------
+	# Load the output module
+	eval { &Load_ModuleL('OUTPUT'); };
+	die $@ if $@;
+
+ 
+	# Believe include first on the system list. 
+    my $VariantFile=&main::VariantFile();
+    if($VariantFile){
+        my $VariantFilePath = Path_Split('Path',$VariantFile);
+        chop($VariantFilePath);
+
+        push(@SysIncPaths, $VariantFilePath);
+    }
+
+	my $ResourceVariantFile=&main::ResourceVariantFile();
+    if($ResourceVariantFile){
+        my $ResourceVariantFilePath = Path_Split('Path',$ResourceVariantFile);
+        chop($ResourceVariantFilePath);
+
+        push(@ResourceSysIncPaths, $ResourceVariantFilePath);
+    }
+    
+    ## Add default system include info for TOOLS2
+    if ($PlatArg eq 'TOOLS2') {    	
+    	push @SysIncPaths , "$E32env::Data{EPOCPath}include\\tools\\stlport";
+    }
+
+	# If the stdcpp keyword is used, or if the target type is STD* ...
+	if ($StdCpp or $TrgType{Name} eq 'STDEXE' or $TrgType{Name} eq 'STDDLL' or $TrgType{Name} eq 'STDLIB') {
+		push @SysIncPaths, $E32env::Data{EPOCPath}."include\\stdapis";
+	}
+
+	&PMStartBldList($Plat{MakeCmd}) if defined &PMStartBldList;
+	my $LoopBld;
+	foreach $LoopBld (@{$Plat{Blds}}) {
+		$CurBld=$LoopBld;
+		&PMBld if defined &PMBld;
+	}
+	undef $CurBld;
+	undef $LoopBld;
+	&PMEndBldList if defined &PMEndBldList;
+
+
+	# Load the Dependency Generator
+	eval { &Load_ModuleL('MAKDEPS'); };
+	die $@ if $@;
+	eval { &Deps_InitL($E32env::Data{EPOCIncPath},@StdIncPaths); };
+	die $@ if $@;
+	if ($Options{v}) {
+		&Deps_SetVerbose;
+	}
+	if ($Plat{UsrHdrsOnly}) {
+		&Deps_SetUserHdrsOnly;
+	}
+
+	if ($Options{nd} || ($ENV{SYMBIANBUILD_DEPENDENCYOFF} && ($ENV{SYMBIANBUILD_DEPENDENCYOFF}==1))) {
+		&Deps_SetNoDependencies
+	}
+	&Deps_SetNoDependencies if(grep /boostlibrary/i, &Mmp_UserIncPaths);
+
+	&Deps_SetUserIncPaths(@UserIncPaths);
+	&Deps_SetSysIncPaths(@ResourceSysIncPaths);
+	&Deps_SetPlatMacros(@{$Plat{Macros}});
+
+	my $prefixFile;
+	$prefixFile = &PMPrefixFile if defined &PMPrefixFile;
+	&Deps_SetPrefixFile($prefixFile) if $prefixFile;
+
+#	Start source list - bitmaps, resources, .AIF files, documents, sources.
+
+	# If feature variants are in use, dependency analysis may use a different overall variant file to that for "straight" source
+	my $curDepOSVariantFile = &Deps_GetOSVariantFile();
+	&Deps_SetOSVariantFile($ResourceVariantFile);
+
+	&PMStartSrcList if defined &PMStartSrcList;
+
+#	start bitmaps
+
+	if ($Options{v}) {
+		print "Starting bitmaps\n";
+	}
+	my $LoopBitMapRef;
+	foreach $LoopBitMapRef (@BitMapStruct) {
+		$CurBitMapRef=$LoopBitMapRef;
+		if ($Options{v}) {
+			print "BitMap: \"$$CurBitMapRef{Trg}\"\n";
+		}
+		&PMBitMapBld if defined &PMBitMapBld;
+	}
+	undef $CurBitMapRef;
+	undef $LoopBitMapRef;
+
+#	end bitmaps
+
+#	start resources
+
+	if ($Options{v}) {
+		print "Starting resources\n";
+	}
+	my $LoopResourceRef;
+	foreach $LoopResourceRef (@ResourceStruct) {
+		$CurResourceRef=$LoopResourceRef;
+		if ($Options{v}) {
+			print "Resource: \"$$CurResourceRef{Trg}\"\n";
+		}
+		eval { @CurDepList=&Deps_GenDependsL($$CurResourceRef{Source}, ("LANGUAGE_$$CurResourceRef{Lang}")); };
+		die $@ if $@;
+		&PMResrcBld if defined &PMResrcBld;
+		undef @CurDepList;
+	}
+	undef $CurResourceRef;
+	undef $LoopResourceRef;
+
+#	end resources
+
+#	start aifs
+
+	if ($Options{v}) {
+		print "Starting aifs\n";
+	}
+
+# Add tools-relative include path to sys includes, to allow for shared include\aiftool.rh
+	use FindBin;
+	$FindBin::Bin =~ /:(.*)\//;
+	my $extraIncPath = $1;
+	$extraIncPath =~ s/\//\\/g;
+	my @SavedResourceSysIncPaths = @ResourceSysIncPaths;
+	push @ResourceSysIncPaths, "$extraIncPath\\INCLUDE";
+	&Deps_SetSysIncPaths(@ResourceSysIncPaths);
+
+	my $LoopAifRef;
+	foreach $LoopAifRef (@AifStruct) {
+		$CurAifRef=$LoopAifRef;
+		if ($Options{v}) {
+			print "Aif: \"$$CurAifRef{Trg}\"\n";
+		}
+		eval { @CurDepList=&Deps_GenDependsL("$$CurAifRef{Source}"); };
+		die $@ if $@;
+		&PMAifBld if defined &PMAifBld;
+		undef @CurDepList;
+	}
+	undef $CurAifRef;
+	undef $LoopAifRef;
+
+	@ResourceSysIncPaths = @SavedResourceSysIncPaths;
+
+#	end aifs
+
+#	start sources
+
+	if ($Options{v}) {
+		print "Starting sources\n";
+	}
+	
+	my $SrcRef;
+	&Deps_SetOSVariantFile($curDepOSVariantFile);
+	&Deps_SetSysIncPaths(@SysIncPaths);
+
+	foreach $SrcRef (@SourceStruct){
+		 $CurSrcPath=$$SrcRef{SrcPath};
+		 $CurSrc=$$SrcRef{CurFile};
+
+		 my @userIncludes = &Mmp_UserIncPaths;
+		 @userIncludes = (@userIncludes, @StringTableUserIncPaths) if (@StringTableUserIncPaths);
+		 unshift (@userIncludes, $CurSrcPath);		 
+
+		 if ($TruePlat{Ext} !~ /\.DSP|\.xml/i)
+		 	{
+			foreach my $buildVariant (@{$Plat{Blds}})
+				{		 		
+				my @macros = &MacroList;
+				@macros = (@macros, @{$BldMacros{$buildVariant}});
+
+				my $checkSourceCommandStore;
+			
+				if ($buildVariant =~ /rel$/i)
+					{
+					$checkSourceCommandStore = \%CheckSourceURELIncludes
+					}
+				else
+					{
+					$checkSourceCommandStore = \%CheckSourceUDEBIncludes
+					}
+				CheckSource_Includes($CurSrcPath.$CurSrc, %$checkSourceCommandStore, $VariantFile, @macros, @userIncludes, @SysIncPaths);
+			}
+		 }
+		 if ($Options{v}) {
+			print "Sourcepath: \"$CurSrcPath\"\n";
+		 }
+		 &PMStartSrc if defined &PMStartSrc;
+
+#			strict depend alt 1 start - call different module function if strict depend flag specified
+			if (((not $MmpFlag{StrictDepend}) || (not defined &PMSrcBldDepend)) && defined &PMSrcDepend) {
+				eval { @CurDepList=&Deps_GenDependsL($CurSrcPath.$CurSrc);};
+				die $@ if $@;
+# modified start: makefile improvement 
+				foreach $srcFile (@CurDepList) {
+					if(not exists($CurSrcSet{$srcFile})){
+						my $srctmp = $srcFile;
+						$CurSrcSet{$srctmp} = 1;
+					}
+				}
+# modified end: makefile improvement 
+				&PMSrcDepend if defined &PMSrcDepend;
+				undef @CurDepList;
+			}
+							
+#			strict depend alt 1 end
+
+			my $LoopBld;
+			foreach $LoopBld (@{$Plat{Blds}}) {
+				$CurBld=$LoopBld;
+				&PMStartSrcBld if defined &PMStartSrcBld;
+
+#				strict depend alt 2 start - call the module function that deals with dependencies generated for each build variant
+				if ($MmpFlag{StrictDepend} && defined &PMSrcBldDepend) {
+					eval { @CurDepList=Deps_GenDependsL($CurSrcPath.$CurSrc,@{$BldMacros{$CurBld}}); };
+					die $@ if $@;
+					&PMSrcBldDepend if defined &PMSrcBldDepend;
+					undef @CurDepList;
+				}
+#				strict depend alt 2 end
+
+				&PMEndSrcBld if defined &PMEndSrcBld;
+			}
+			undef $CurBld;
+			undef $LoopBld;
+			&PMEndSrc if defined &PMEndSrc;
+# modified start: makefile improvement 
+			my $cursrcfile = $CurSrcPath.$CurSrc;
+			if(not exists($CurSrcSet{$cursrcfile})){
+				$CurSrcSet{$cursrcfile} = 1;
+			}
+# modified end: makefile improvement 
+		}
+		undef $CurSrc;
+		undef $CurSrcPath;  
+	
+	
+
+#	end sources
+
+#	start documents
+
+	if ($Options{v}) {
+		print "Starting documents\n";
+	}
+	my $LoopSrcPath;
+	foreach $LoopSrcPath (sort keys %DocHash) {
+		$CurSrcPath=$LoopSrcPath;
+		if ($Options{v}) {
+			print "Sourcepath: \"$CurSrcPath\"\n";
+		}
+		my $LoopDoc;
+		foreach $LoopDoc (sort @{$DocHash{$CurSrcPath}}) {
+			$CurDoc=$LoopDoc;
+			if ($Options{v}) {
+				print "Document: \"$CurDoc\"\n";
+			}
+			&PMDoc if defined &PMDoc;
+		}
+		undef $CurDoc;
+		undef $LoopDoc;
+	}
+	undef $CurSrcPath;
+	undef $LoopSrcPath;
+
+#	end documents
+
+#	rombuild
+
+	my %SpecialRomFileTypes=(
+		KEXT=>'extension[MAGIC]',
+		LDD=>'device[MAGIC]',
+		PDD=>'device[MAGIC]',
+		VAR=>'variant[MAGIC]'
+	);
+	my %KHash1 = (
+		kext=>1,
+		ldd=>1,
+		pdd=>1,
+		var=>1,
+		kdll=>1
+	);
+	my %KHash2 = (
+		primary=>1,
+		variant=>1,
+		extension=>1,
+		device=>1
+	);
+	unless ($TrgType{Basic} =~ /^IMPLIB$/io or $TruePlat{Ext} =~ /\.DSP|\.xml/i) { # change to avoid rombuild target for IDE makefiles
+		&Output("ROMFILE:\n");
+		unless ($Plat{OS} ne 'EPOC32' or $TrgType{Basic} eq 'LIB') {
+			my $ref;
+			foreach $ref (@RomTargets) {
+				my $ABIDir = '##MAIN##';
+				my $RomFileType='file';
+				if ($$ref{FileType}) {	# handle EKERN.EXE and EFILE.EXE with new ROMFILETYPE keyword instead
+					$RomFileType=$$ref{FileType}; # or just do this bit as a custom build makefile
+				}
+				elsif ($CallDllEntryPoints) {
+					$RomFileType='dll';
+				}
+				elsif ($SpecialRomFileTypes{$TrgType{Name}}) {
+					$RomFileType=$SpecialRomFileTypes{$TrgType{Name}};
+				}
+				my $RomPath="sys\\bin\\";
+				if ($$ref{Path}) {
+					$RomPath=$$ref{Path};
+				}
+				elsif ($TrgType{Path}) {
+					$RomPath=$TrgType{Path};
+					$RomPath=~s-z\\(.*)-$1-o;
+				}
+				my $RomFile=$LinkAsBase;
+				if ($$ref{File}) {
+					$RomFile=$$ref{File};
+				}
+				my $RomDecorations='';
+				if ($DataLinkAddress) {
+					$RomDecorations="reloc=$DataLinkAddress";
+				}
+				elsif ($FixedProcess) {
+					$RomDecorations.='fixed';
+				}
+				
+				$ABIDir = '##KMAIN##' if ($KHash1{lc $TrgType{Name}});
+				$ABIDir = '##KMAIN##' if ($KHash2{lc $RomFileType});
+				my $IbyTextFrom="$RomFileType=$E32env::Data{RelPath}$ABIDir\\##BUILD##\\$Trg";
+				my $IbyTextTo="$RomPath$RomFile";
+				my $Spaces= 60>length($IbyTextFrom) ? 60-length($IbyTextFrom) : 1; 
+				&Output("\t\@echo ", $IbyTextFrom, ' 'x$Spaces, "$IbyTextTo $RomDecorations\n");
+			}
+			foreach $ref (@RamTargets) {
+				my $ABIDir = '##MAIN##';
+				$ABIDir = '##KMAIN##' if ($KHash1{lc $TrgType{Name}});
+				my $RomFileType='data';
+				my $RomPath="sys\\bin\\";
+				if ($$ref{Path}) {
+					$RomPath=$$ref{Path};
+				}
+				my $RomFile=$Trg;
+				if ($$ref{File}) {
+					$RomFile=$$ref{File};
+				}
+				my $RomDecorations='attrib=r';
+
+				my $IbyTextFrom="$RomFileType=$E32env::Data{RelPath}$ABIDir\\##BUILD##\\$Trg";
+				my $IbyTextTo="$RomPath$RomFile";
+				my $Spaces= 60>length($IbyTextFrom) ? 60-length($IbyTextFrom) : 1; 
+				&Output("\t\@echo ", $IbyTextFrom, ' 'x$Spaces, "$IbyTextTo $RomDecorations\n");
+			}
+		}
+	}
+#	end rombuild
+
+	&PMEndSrcList if defined &PMEndSrcList;
+}
+
+{
+
+	# open the makefile and write all the text it requires to it if makmake has so far been successful
+	#-------------------------------------------------------------------------------------------------
+	eval { &Path_MakePathL($MAKEFILE); };
+	die $@ if $@;
+	if ($Options{v}) {
+		print "Creating: \"$MAKEFILE\"\n";
+	}
+	open MAKEFILE,">$MAKEFILE" or die "ERROR: Can't open or create file \"$MAKEFILE\"\n";
+	print MAKEFILE &OutText or die "ERROR: Can't write output to file \"$MAKEFILE\"\n";
+	close MAKEFILE or die "ERROR: Can't close file \"$MAKEFILE\"\n";
+	if ($Options{v}) {
+		print "Successful MakeFile Creation\n";
+	}
+}
+
+	
+################ END OF MAIN PROGRAM SECTION #################
+#------------------------------------------------------------#
+##############################################################
+
+
+
+
+
+# SUBROUTINE SECTION
+####################
+
+sub FatalError (@) {
+
+	print STDERR "MAKMAKE ERROR: @_\n";
+	exit 1;
+}
+
+sub Usage () {
+
+		eval { &Load_ModuleL('MAKHELP'); };
+		die $@ if $@; 
+		eval { &Help_Invocation; };
+		die $@ if $@;
+		exit;
+}
+
+sub getEABIDef() {
+	# Preprocess the mmp with ARMv5 platform settings so we can pick up 
+    # EABI specific def file entries etc. 
+    my ($platname)="ARMV5";
+    
+    # get platform info for armv5
+    eval { &Plat_GetL($platname,\%Plat,\%BldMacros); };
+	return $@ if $@;
+	&Mmp_Reset;
+	# process 
+    
+    # set package to ignore warnings about missing .def file. 
+    &Mmp_SetIgnoreMissingDef;
+    
+    eval { &Mmp_ProcessL($E32env::Data{EPOCPath}, $MMPFILE, \%Plat, $FeatureVariantInfo{BUILD_INCLUDES}); };
+	return $@ if $@;
+	my %EABIDef=%{&Mmp_Def};
+	
+    # handle case that def file doesn't exist -> Simply set to ""
+    my $EABIDefFile = "$EABIDef{Path}$EABIDef{Base}$EABIDef{Ext}";;
+   	unless (-e "$EABIDefFile") {
+        $EABIDefFile = "";
+	}
+    
+    return $EABIDefFile;
+	
+}
+
+sub SetVarsFromMmp ($) {
+
+	my ($platname)=@_;
+    
+	if($platname eq "GCCXML") {
+        $EABIDef = getEABIDef();
+    } 
+    else {
+        $EABIDef = "";
+    }
+
+	# MMP FILE PROCESSING - filter the mmp file content through the GCC preprecessor
+	#-------------------------------------------------------------------------------
+	eval { &Plat_GetL($platname,\%Plat,\%BldMacros); };
+	return $@ if $@;
+	&Mmp_Reset;
+
+	if($platname eq "GCCXML" || $platname eq "X86GCC" || $platname eq "X86GMP") {
+	# set package to ignore warnings about missing .def file, this is necessary,
+	# as either EABI .def or GCC .def may not exist, and this shouldn't be reported
+	# as a warning or error. Similarly for x86gcc def files - these are autogenerated.
+	&Mmp_SetIgnoreMissingDef;
+	}
+
+	eval { &Mmp_ProcessL($E32env::Data{EPOCPath}, $MMPFILE, \%Plat, $FeatureVariantInfo{BUILD_INCLUDES}); };
+	return $@ if $@;
+
+	%WarningLevel=&Mmp_WarningLevel;
+	%LinkerOptions=&Mmp_LinkerOptions;
+	$ABI=&Mmp_ABI;
+	@AifStruct=@{&Mmp_AifStruct};
+	$AllowDllData=&Mmp_AllowDllData;
+	$CompressTarget=&Mmp_CompressTarget;
+	$CompressTargetMode=&Mmp_CompressTargetMode;
+	$ASSPExports=&Mmp_ASSPExports;
+	@ASSPLibList=&Mmp_ASSPLibList;
+	@BitMapStruct=@{&Mmp_BitMapStruct};
+	$BuildAsARM=$BuildAsARM || &Mmp_BuildAsARM;
+	$CallDllEntryPoints=&Mmp_CallDllEntryPoints;
+	$Capability=&Mmp_Capability;
+	@CapabilityFlags=&Mmp_CapabilityFlags;
+	$DataLinkAddress=&Mmp_DataLinkAddress;
+	@DebugLibList=@{&Mmp_DebugLibList};
+	%Def=%{&Mmp_Def};
+	%DocHash=%{&Mmp_DocHash};
+	$ExportUnfrozen=&Mmp_ExportUnfrozen;
+	$FirstLib=&Mmp_FirstLib;
+	$FixedProcess=&Mmp_FixedProcess;
+	%HeapSize=%{&Mmp_HeapSize};
+	@LibList=@{&Mmp_LibList};
+	$LinkAs=&Mmp_LinkAs;
+	$LinkAsBase=&Mmp_LinkAsBase;
+	$ExportLibrary=&Mmp_ExportLibrary;
+	$NewLib = &Mmp_NewLib;
+    $NoExportLibrary=&Mmp_NoExportLibrary;
+	%MmpFlag=%{&Mmp_MmpFlag};
+	@PlatTxt2D=&Mmp_PlatTxt2D;
+	$ProcessPriority=&Mmp_ProcessPriority;
+	@RamTargets=&Mmp_RamTargets;
+	@ResourceStruct=@{&Mmp_ResourceStruct};
+	@RomTargets=&Mmp_RomTargets;
+	$SmpSafe=&Mmp_SmpSafe;
+	@SourceStruct=@{&Mmp_SourceStruct};
+	$StackSize=&Mmp_StackSize;
+	@StatLibList=&Mmp_StatLibList;    
+	$StdCpp = &Mmp_StdCpp;
+	$NoStdCpp = &Mmp_NoStdCpp;
+	@SysIncPaths=&Mmp_SysIncPaths;
+	$Trg=&Mmp_Trg;
+	%TrgType=%{&Mmp_TrgType};
+	@UidList=&Mmp_UidList;
+	@UserIncPaths=&Mmp_UserIncPaths;
+	$SrcDbg=&Mmp_SrcDbg;
+	%Version=&Mmp_Version;
+	$SecureId=&Mmp_SecureId;
+	$VendorId=&Mmp_VendorId;
+	%ReplaceOptions=&Mmp_Replace;
+	$ARMFPU=&Mmp_ARMFPU;
+	@StringTable=@{&Mmp_StringTable};
+	$CodePagingTargetMode=&Mmp_CodePagingTargetMode;
+	$DataPagingTargetMode=&Mmp_DataPagingTargetMode;
+	$IsWideCharMain=&Mmp_IsWideCharMain;
+	$IsDebuggable=&Mmp_IsDebuggable;
+
+#	finish defining any macros
+
+	if ($Plat{CPU} eq 'MARM') {
+#		apply the ABI source define - note that it is difficult to define a corresponding
+#		.MMP define since we can't be sure what the ABI is until we've processed the .MMP file,
+#		though we could apply it for generic MARM builds only
+		push @{$Plat{Macros}}, "__MARM_${ABI}__";
+	}
+
+	if ($TrgType{Basic}=~/^(DLL|EXE)$/o) { # this macro may soon be removed
+		push @{$Plat{Macros}},'__'.$TrgType{Basic}.'__';
+	}
+
+#	add the macros defined in the .mmp file
+	push @{$Plat{Macros}}, &Mmp_Macros;
+
+# set up a hash containing the start paths for various things
+	undef %Path;
+
+#	set up ASSP link path - this is the path where the target looks for ASSP-specific import libraries
+        $Path{ASSPLink}="$E32env::Data{LinkPath}$Plat{ASSP}\\";
+
+#	set up build path
+	my $BldInfPath=cwd;
+	$BldInfPath=~s-/-\\-go;						# separator from Perl 5.005_02+ is forward slash
+	$BldInfPath=~s/^(.:)//o;					# remove drive letter
+	$BldInfPath=~s-^(.*[^\\])$-$1\\-o;			# ensure workpath ends with a backslash
+	$Path{BldInfPath} = $BldInfPath;			# Remember the path to bldinf
+	$Path{Bld}=join('', &Path_Chop($E32env::Data{BldPath}), $BldInfPath, &Path_Split('Base',$MMPFILE), "\\$Plat{Real}\\");
+}
+
+sub generateX86GCCDefFile()
+{
+	my ($oldPath, $newPath) = @_;
+	print "Generating X86GCC deffile from $oldPath\n";
+	if (!open(OLDDEF, $oldPath))
+	{
+		print "Warning: Failed to open $oldPath for reading\n".
+		return;
+	}
+	# Force creation of new def file even if one already exists
+	if (!open(NEWDEF, ">$newPath"))
+	{
+		close OLDDEF;
+		print "Warning: Failed to open $newPath for writing\n".
+		return;
+	}
+	while (<OLDDEF>)
+	{
+		chomp;
+		if (/^\s*_ZT(I|V)/ && !/\sABSENT/i)
+	    {
+		# Typeinfo that isn't already absent. Add the ABSENT keyword.
+		    my @frags = split /;/, $_, 2; # 1 or 2 parts depending on the presence of a comment
+		    $frags[0] =~ s/\s*$/ ABSENT /;
+		    $_ = join ';', @frags;
+	    }
+	    else
+	    {
+		# Try to substitute any va_list params with char* (Pc). Ignore if no match
+		s/St9__va_list/Pc/g;
+	    }
+		print NEWDEF "$_\n";	    
+	}
+	close OLDDEF;
+	close NEWDEF;
+	print "Successfully generated $newPath\n";
+}
+
+sub InitLinkPaths() {
+#	set up lib path - this is the path where the target puts it's import library
+
+	my $ABI=&Mmp_ABI;
+
+#	let the build target determine where it puts its import libray and where its links against its imports
+	my $UnderlyingABI=$ABI;
+	$UnderlyingABI=&PMUnderlyingABI($ABI) if defined &PMUnderlyingABI;
+
+	$Path{Lib}="$E32env::Data{LinkPath}";
+	unless ($ASSPExports) {
+		$Path{Lib}.= lc($UnderlyingABI)."\\";
+	} 
+	else {
+		$Path{Lib}.= lc($Plat{ASSP})."\\";
+	}
+
+
+#	set up link path - this is the place where the target looks for ordinary libraries
+	$Path{Link}="$E32env::Data{LinkPath}"."$UnderlyingABI\\";
+
+#	set up stat link path - this is where the target looks for static libraries
+	$Path{StatLink}="$E32env::Data{LinkPath}";
+	if ($Plat{StatLink}) {
+			$Path{StatLink}.=lc($Plat{StatLink})."\\";
+	} else {
+		unless ($Plat{OS} eq 'WINS') {	# WINC and WINS versions of EEXE are different
+			$Path{StatLink}.=lc($ABI)."\\"; # ARM static libraries are currently always ASSP-independent
+		}
+		else {
+			$Path{StatLink}.=lc($Plat{ASSP})."\\"; # WINC static libraries are currently always ASSP-specific
+		}
+	}
+
+#	set up release path
+	$Path{Rel}="$E32env::Data{RelPath}".lc($Plat{Real})."\\";
+	
+}
+
+sub CreateExtraFile ($$) { # takes abs path for source and text
+# allows modules to create extrafiles
+	my ($FILE,$Text)=@_;
+	if ($Options{makemakefile}) {	# only create if making the makefile
+		if ($Options{v}) {
+			print "Creating \"$FILE\"\n";
+		}
+		eval { &Path_MakePathL($FILE); };
+		die $@ if $@;
+		open FILE, ">$FILE" or die "WARNING: Can't open or create \"$FILE\"\n";
+		print  FILE $Text or die "WARNING: Can't write text to \"$FILE\"\n";
+		close FILE or die "WARNING: Can't close \"$FILE\"\n";
+	}
+}
+
+sub ABI () {
+	$ABI;
+}
+sub AddSrc ($$) { # needs abs path for source
+# allows modules to add a source file to the project and have it created if necessary
+	my ($SRCFILE,$Text)=@_;
+	my $SrcPath=&Path_Split('Path',$SRCFILE);
+	my $CurFile=&Path_Split('File',$SRCFILE);
+	my $BaseName=&Path_Split('Base',$SRCFILE);
+	
+	if ((not -e $SRCFILE) || (-M $SRCFILE > -M $MMPFILE)) {
+		# only create the file if it's older than the .MMP file
+		CreateExtraFile($SRCFILE,$Text);
+	}
+	 my %CurSource;
+	 $CurSource{SrcPath}=$SrcPath;
+	 $CurSource{CurFile}=$CurFile;
+	 $CurSource{BaseTrg}=$BaseName;
+	 push @SourceStruct, \%CurSource;
+}
+sub AddPlatMacros (@) {
+# allows modules to add extra macros to the platform macro list
+	push @{$Plat{Macros}},@_;
+}
+sub AifRef () {
+	$CurAifRef;
+}
+sub AifStructRef () {
+	\@AifStruct;
+}
+sub AllowDllData () {
+	$AllowDllData;
+}
+sub CompressTarget () {
+	$CompressTarget;
+}
+sub CompressTargetMode () {
+	$CompressTargetMode;
+}
+sub BuildAsARM () {
+	return 0 if $Options{ithumb};
+	return 1 if $Options{iarm};
+	$BuildAsARM;
+}
+sub ASSPLibList () {
+	@ASSPLibList;
+}
+sub ASSPLinkPath () {
+#	this is the path where the target looks for ASSP-specific import libraries
+	my $Path=$Path{ASSPLink};
+	if ($CurBld) {
+		if ($Plat{OS} eq 'EPOC32') {
+			$Path.="UREL\\";
+		}
+		else {
+			$Path.="UDEB\\";
+		}
+	}
+	$Path;
+}
+sub BaseMak () {
+	&Path_Split('Base',$MAKEFILE);
+}
+sub BaseResrc () {
+	&Path_Split('Base',$CurResrc);
+}
+sub BaseResrcList () {
+	my @ResrcList=&ResrcList;
+	my $Path;
+	foreach $Path (@ResrcList) {
+		$Path=&Path_Split('Base',$Path);
+	}
+	@ResrcList;
+}
+sub BaseSrc () {
+	&Path_Split('Base',$CurSrc);
+}
+sub ExtSrc () {
+	&Path_Split('Ext',$CurSrc);
+}
+sub BaseSrcList () {
+	my @SrcList=&SrcList;
+	my $Path;
+	foreach $Path (@SrcList) {
+		$Path=&Path_Split('Base',$Path);
+	}
+	@SrcList;
+}
+sub BaseSysResrcList () {
+	my @SysResrcList=&SysResrcList;
+	my $Path;
+	foreach $Path (@SysResrcList) {
+		$Path=&Path_Split('Base',$Path);
+	}
+	@SysResrcList;
+}
+sub BaseTrg () {
+	&Path_Split('Base',$Trg);
+}
+sub BitMapRef () {
+	$CurBitMapRef;
+}
+sub BitMapStructRef () {
+	\@BitMapStruct;
+}
+sub Bld () {
+	$CurBld;
+}
+sub BldList () {
+	@{$Plat{Blds}};
+}
+sub BldPath () {
+	my $Path=$Path{"Bld"};
+	if ($CurBld) {
+		$Path.=$FeatureVariantInfo{$CurBld."_LABEL"}."\\" if (%FeatureVariantInfo && !$FeatureVariantInfo{INVARIANT} && $FeatureVariantInfo{$CurBld."_LABEL"});
+		$Path.="$CurBld\\";
+	}
+	$Path;
+}
+sub CallDllEntryPoints () {
+	$CallDllEntryPoints;
+}
+sub Capability () {
+	$Capability;
+}
+sub CapabilityFlags () {
+	@CapabilityFlags;
+}
+sub DataLinkAddress () {
+	$DataLinkAddress;
+}
+sub DataPath () {
+	$E32env::Data{DataPath};
+}
+sub DebugLibList () {
+	@DebugLibList;
+}
+sub DefFile () {
+	"$Def{Path}$Def{Base}$Def{Ext}";
+}
+sub DefFileType () {
+	$Plat{DefFile};
+}
+sub DepList () {
+	sort @CurDepList;
+}
+sub Doc () {
+	$CurDoc;
+}
+sub DocList () {
+	if ($CurSrcPath) {
+		return sort @{$DocHash{$CurSrcPath}};
+	}
+	my @DocList;
+	my $Key;
+	foreach $Key (keys %DocHash) {
+		push @DocList,@{$DocHash{$Key}};
+	}
+	sort @DocList;
+}
+sub EPOCPath () {
+	$E32env::Data{EPOCPath};
+}
+sub EPOCDataPath () {
+	$E32env::Data{EPOCDataPath};
+}
+sub EPOCIncPath () {
+	$E32env::Data{EPOCIncPath};
+}
+sub EPOCRelPath () {
+	$E32env::Data{RelPath};
+}
+sub EPOCSecurePlatform () {
+	$E32env::Data{SecurePlatform};
+}
+sub EPOCToolsPath () {
+	$E32env::Data{EPOCToolsPath};
+}
+sub Exports () {
+	@{$TrgType{Exports}{$Plat{"DefFile"}}};
+}
+sub ExportUnfrozen () {
+	$ExportUnfrozen;
+}
+sub FirstLib () {
+	$FirstLib;
+}
+sub FixedProcess () {
+	$FixedProcess;
+}
+sub BasicTrgType () {
+	$TrgType{Basic};
+}
+sub HeapSize () {
+	%HeapSize;
+}
+sub LibList () {
+	@LibList;
+}
+sub LibPath () {
+#	this is the path where the target puts it's import library
+	my $Path=$Path{Lib};
+	if ($CurBld) {
+		if (($Plat{DefFile} eq 'EABI') || ($Plat{DefFile} eq 'x86gcc') || ($Plat{OS} eq 'TOOLS2')) {
+			$Path.="lib\\";
+		}
+		elsif ($Plat{OS} eq 'EPOC32') {
+			$Path.="urel\\";
+		}
+		else {
+			$Path.="udeb\\";
+		}
+	}
+	$Path;
+}
+sub LinkAs () {
+	$LinkAs;
+}
+sub LinkAsBase () {
+	$LinkAsBase;
+}
+sub ExportLibrary () {
+	$ExportLibrary;
+}
+sub NoExportLibrary () {
+	$NoExportLibrary;
+}
+sub LinkPath () {
+#	this is the place where the target looks for CPU-specific libraries
+	my $Path=$Path{Link};
+	if ($CurBld) {
+		if ($Plat{DefFile} eq 'EABI' || $Plat{DefFile} eq 'x86gcc') {
+			$Path.="LIB\\";
+		}
+		elsif ($Plat{OS} eq 'EPOC32') {
+			$Path.="UREL\\";
+		}
+		else {
+			$Path.="UDEB\\";
+		}
+	}
+	$Path;
+}
+
+sub MacroList ($) {
+	if ($_[0]) {
+	return @{$BldMacros{$_[0]}};
+	}
+	return @{$Plat{Macros}} unless $CurBld;
+	(@{$Plat{Macros}},@{$BldMacros{$CurBld}});
+}
+
+# returns the file containing Variant specific Macros
+sub VariantFile($)
+{
+    return $variantMacroHRHFile;
+}
+# returns the file containing Variant specific Macros, which may differ from the above if feature variants are used
+sub ResourceVariantFile($)
+{
+    return $ResourceVariantMacroHRHFile;
+}
+sub MakeFilePath () {
+	&Path_Split('Path',$MAKEFILE);
+}
+sub MmpFile () {
+	$MMPFILE;
+}
+sub PerlLibPath () {
+	$PerlLibPath;
+}
+sub Plat () {
+	$Plat{Real};
+}
+sub PlatABI () {
+	$Plat{"ABI"};
+}
+sub PlatCompiler () {
+	$Plat{"Compiler"};
+}
+sub PlatName () {
+	$Plat{Name};
+}
+sub PlatOS () {
+	$Plat{OS};
+}
+sub PlatOverrideList () {
+	@PlatOverrideList;
+}
+sub ProcessPriority () {
+	$ProcessPriority;
+}
+sub RelPath () {
+	my $Path=$Path{Rel};
+	if ($CurBld) {
+		$Path .= lc($CurBld)."\\";
+	}
+	$Path;
+}
+sub ResourceRef () {
+	$CurResourceRef;
+}
+sub ResourceStructRef () {
+	\@ResourceStruct;
+}
+sub SetCurBld($) {
+	$CurBld=$_[0];		# used by ide_cw.pm when handling additional platforms
+}
+sub	SetStdIncPaths (@) {
+# allows module to set standard include paths
+	@StdIncPaths=();
+	my $Path;
+	foreach $Path (@_) {
+		$Path=~s-^(.*[^\\])$-$1\\-o if defined($Path);
+		push @StdIncPaths, $Path;	# only place drive letters may appear, up to modules to handle
+	}
+}
+sub Src () {
+	$CurSrc;
+}
+sub SourceStructRef () {
+	\@SourceStruct;		#array of references to hashes of SOURCEPATH => (filename1, filename2, ...)
+	}
+sub SrcList () {
+	my @SrcList;
+    my $KeyRef;
+    foreach $KeyRef (@SourceStruct) {
+            push @SrcList,$$KeyRef{CurFile};
+           } 
+	 @SrcList;
+}
+
+sub SmpSafe () {
+	$SmpSafe;
+}
+
+sub StackSize () {
+	$StackSize;
+}
+sub StatLibList () {
+	@StatLibList;
+}
+sub StatLinkPath () {
+	my $Path=$Path{StatLink};
+	if ($CurBld) {
+		$Path.="$CurBld\\";
+	}
+	$Path;
+}
+sub StdCpp () {
+	$StdCpp;
+}
+sub NoStdCpp () {
+	$NoStdCpp;
+}
+
+sub NewLib () {
+	$NewLib;
+}
+sub SetStatLinkPath($) {
+	($Path{StatLink}) = @_;
+}
+sub SrcPath () {
+	$CurSrcPath;
+}
+sub SysIncPaths () {
+	@SysIncPaths;
+}
+sub ResourceSysIncPaths () {
+	return @ResourceSysIncPaths;
+}
+sub Trg (;$) {
+	# The optional $bld argument permits (U)DEB and (U)REL distinction in situations where $CurBld isn't set/relevant
+	my ($bld) = @_;
+	$bld = $CurBld if (!$bld);
+
+	return "" if !$Trg;
+
+	my $localTrg = $Trg;	
+	my $vinfo = $FeatureVariantInfo{$bld."_LABEL"};
+	$localTrg =~ s/(\.[^\.]+)$/\.$vinfo$1/ if ($bld && %FeatureVariantInfo && !$FeatureVariantInfo{INVARIANT} && $vinfo);
+	return $localTrg;
+}
+sub TrgPath () {
+	$TrgType{Path};
+}
+sub TrgType () {
+	$TrgType{Name};
+}
+# this can probably go as its always 0 now
+sub KernelTrg () {
+	$TrgType{Kernel};
+}
+sub SystemTrg () {
+	$TrgType{System};
+}
+sub UidList () {
+	@UidList;
+}
+sub UserIncPaths () {
+	@UserIncPaths;
+}
+sub SrcDbg () {
+	$SrcDbg;
+}
+sub CompilerOption
+{
+	my $CompOption=$WarningLevel{$_[0]};
+	$CompOption="" if (!defined($CompOption)); 
+	$CompOption;
+}
+sub LinkerOption
+{
+    my $lnkOption = $LinkerOptions{$_[0]};
+    $lnkOption="" if (!defined($lnkOption));
+    $lnkOption;
+}
+
+sub PlatRec () {
+	%Plat;
+}
+
+sub Version() {
+	%Version;
+}
+
+sub SecureId() {
+	$SecureId;
+}
+
+sub VendorId () {
+	$VendorId;
+}
+
+sub EABIDef () {
+	$EABIDef;
+}
+
+sub ReplaceOptions () {
+	my @ReplacementOptions = ();
+	if (defined($ReplaceOptions{$_[0]}))
+	{
+		@ReplacementOptions=@{$ReplaceOptions{$_[0]}};
+	}	
+	@ReplacementOptions;
+}
+
+sub ARMFPU () {
+	$ARMFPU;
+}
+
+sub IsDebuggable () {
+	$IsDebuggable;
+}
+
+sub PlatTxt2D () {
+	@PlatTxt2D;
+}
+
+sub ToolChain () {
+	my $ToolChain = $TruePlat{Toolchain};
+	$ToolChain ="" if(!defined ($TruePlat{Toolchain}) );
+	$ToolChain;
+}
+
+sub StringTables () 
+{
+	@StringTable;
+}
+
+
+#This generates and adds the generated source of the stringtable to the source list so it's included in the binary.
+sub AddStringTables ()
+{
+	if(@StringTable)
+	{
+		foreach my $stringtable (@StringTable)
+		{
+			my %genSrcHash;
+
+			$genSrcHash{SrcPath} = $Path{Bld};
+			$genSrcHash{CurFile} = $stringtable->{BaseTrg}.".cpp";
+			$genSrcHash{BaseTrg} = $stringtable->{BaseTrg};
+
+			push(@SourceStruct, \%genSrcHash) if !$stringtable->{Hdronly};
+
+			# Execute it now.  This can probably be moved into the makefile by adding a suitable rule
+			# to ensure the resource file is generated before the source tries to #include it.
+			my $stPath = $Path{Bld};
+
+			my $stCpp = $stringtable->{BaseTrg}.".cpp";
+			my $stHeader = lc($stringtable->{BaseTrg}).".h";
+			my $stFile = $stringtable->{STFile};
+			my $stOrigin = $stringtable->{STPath};
+			system("perl -S ecopyfile.pl $stOrigin$stFile $stPath$stFile");
+			system("perl -S stringtable.pl $stPath$stFile");
+
+			#If it's an exported header we'll need to export it.
+			if(defined $stringtable->{ExportPath}) 
+			{
+				my $exportpath = $stringtable->{ExportPath};
+
+				system("perl -S ecopyfile.pl $stPath$stHeader $exportpath\\$stHeader");
+
+				push(@UserIncPaths, $exportpath);
+				push(@StringTableUserIncPaths, $exportpath);
+			}
+			#otherwise we just need the path of the generated header to be added 'userinclude'.
+			else 
+			{
+				push(@UserIncPaths, $Path{Bld});
+				push(@StringTableUserIncPaths, $Path{Bld});
+			}
+		}
+	}
+}
+
+sub CheckSourceMMPMetaData () {
+	%CheckSourceMMPMetaData;
+}
+
+sub CheckSourceMMPIncludes () {
+	%CheckSourceMMPIncludes;
+}
+
+sub CheckSourceURELIncludes () {
+	%CheckSourceURELIncludes;
+}
+
+sub CheckSourceUDEBIncludes () {
+	%CheckSourceUDEBIncludes;
+}
+
+sub CodePagingTargetMode() {
+	$CodePagingTargetMode;
+}
+
+sub DataPagingTargetMode() {
+	$DataPagingTargetMode;
+}
+
+sub DebugSwitchUsed () {
+	return 1 if (defined $DebugSwitch);
+	return 0;
+}
+
+sub SymbolicDebugEnabled () {
+	return $DebugSwitch;
+}
+
+sub IsFunctionCallLogging() {
+	$Options{logfc};
+}
+
+sub IsWideCharMain() {
+	return $IsWideCharMain;
+}
+
+sub MmpMacros(){
+	my @mmpMacros=&Mmp_Macros;
+	return @mmpMacros;
+}
+
+sub FeatureVariantInfo()
+	{
+	return %FeatureVariantInfo;
+	}
+
+sub FeatureVariantVMapFile()
+	{
+	return "" if !%FeatureVariantInfo || defined $FeatureVariantInfo{INVARIANT};
+
+	my $target = RelPath().Trg();
+	$target =~ s/\.$FeatureVariantInfo{$CurBld."_LABEL"}//;
+# modified by SV start: makefile improvement 
+	my $vmap = $target. "." . $FeatureVariantInfo{NAME}.".vmap";
+# modified by SV end: makefile improvement 
+
+	eval { &Path_MakePathL($vmap); };	
+
+	if (featurevariantmap->Save($target, $FeatureVariantInfo{$CurBld."_LABEL"}, $FeatureVariantInfo{NAME}, $FeatureVariantInfo{$CurBld."_FEATURES"}, &Mmp_IsFeatureVariant ? [ 'FEATUREVARIANT' ] : undef))
+		{
+		die "ERROR: Couldn't create feature variant map file \"$vmap\".\n";
+		}
+
+	return $vmap;
+	}
+
+sub FeatureVariantBaseTrg()
+	{
+	# In some situations, for example .sym files, we need a feature variant tagged name
+	# based on the normal BaseTrg i.e. root target name but minus extension.
+	my $localBaseTrg = BaseTrg();
+		
+	if (%FeatureVariantInfo && !defined $FeatureVariantInfo{INVARIANT})
+		{
+		$localBaseTrg .= ".".$FeatureVariantInfo{$CurBld."_LABEL"};
+		}
+
+	return $localBaseTrg;
+	}
+
+sub CommandFile()
+	{
+	my $plat = Plat();	
+	$plat .= ".$FeatureVariantInfo{NAME}" if %FeatureVariantInfo;
+	return MakeFilePath().BaseTrg().".$plat.".Bld().".objects.via";
+	}
+
+#Compiler wrapper option support
+sub CompilerWrapperOption()
+{
+  # Return 1 if compiler wrapper option option(-wrap) is specified else return 0	
+  $IsCompilerWrapperOption;
+}
+
+#Proxy wrapper option support
+sub ProxyWrapperOption()
+{
+  # Return 1 if compiler wrapper option option(-wrap) is specified else return 0	
+  $IsProxyWrapperOption;
+}
+# modified start: makefile improvement 
+sub getSrcSet()
+{
+	return \%CurSrcSet;
+}
+# modified end: makefile improvement 
+
+#1 = STDCPP support is available
+#others = STDCPP support is not available
+my $stdcppsupport;
+
+#STDCPP support check (SYMBIAN_OE_LIBSTDCPP)
+#return non-zero means STDCPP support is available,
+#otherwise it's not available
+sub StdCppSupport()
+{
+	return $stdcppsupport if (defined $stdcppsupport);
+	
+	my @hrhMacros = &Variant_GetMacroList;
+	if (grep /^\s*SYMBIAN_OE_LIBSTDCPP\s*$/, @hrhMacros)
+	{
+		$stdcppsupport = 1;
+	}
+	else
+	{
+	    $stdcppsupport = 0;
+	}
+	
+	return $stdcppsupport;
+}