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