sbsv1/abld/platform/ide_cw.pm
changeset 40 68f68128601f
equal deleted inserted replaced
39:fa9d7d89d3d6 40:68f68128601f
       
     1 # Copyright (c) 2001-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 # Makmake-module for creating XML files which can be imported as CodeWarrior IDE projects
       
    15 # 
       
    16 #
       
    17 
       
    18 package Ide_cw;
       
    19 
       
    20 my $CW_minimum_supported_version = 2.8;
       
    21 
       
    22 # declare variables global for module
       
    23 my $BaseAddress="";
       
    24 my %IdeBlds=();
       
    25 my %PrjHdrs=();
       
    26 my @Win32LibList=();
       
    27 my $Win32Resrc;
       
    28 my $Win32StdHeaders;
       
    29 
       
    30 my $ExtraFilesPath="";
       
    31 my @KnownRoots=();
       
    32 
       
    33 my @addedFiles=();
       
    34 my $addHeaders = 1;
       
    35 my $addDocuments = 1;
       
    36 
       
    37 my %processedPlatforms;
       
    38 
       
    39 require Exporter;
       
    40 @ISA=qw(Exporter);
       
    41 
       
    42 @EXPORT=qw(
       
    43 	PMHelp_Mmp
       
    44 
       
    45 	PMCheckPlatformL
       
    46 
       
    47 	PMPlatProcessMmp
       
    48 
       
    49 	PMStartBldList
       
    50 		PMBld
       
    51 			PMResrcBld
       
    52 
       
    53 	PMEndSrcList
       
    54 );
       
    55 
       
    56 require Cl_bpabi;
       
    57 use BPABIutl;
       
    58 use E32Variant;
       
    59 use E32Plat; 
       
    60 use Winutl;
       
    61 use Armutl;
       
    62 use Pathutl;
       
    63 use Win32API::Registry qw( :ALL );
       
    64 use Preprocessor;
       
    65 use RVCT_plat2set;
       
    66 
       
    67 sub PMHelp_Mmp {
       
    68 	&Winutl_Help_Mmp;
       
    69 }
       
    70 
       
    71 my $RVCTMajorVersion = Armutl_RVCTMajorVersion();
       
    72 my $RVCTMinorVersion = Armutl_RVCTMinorVersion();
       
    73 my $RVCTVersion = "${RVCTMajorVersion}_${RVCTMinorVersion}";
       
    74 
       
    75 my $oP = "--";
       
    76 $oP = "-" if ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2);
       
    77 
       
    78 my $cfgMacro = &Variant_GetMacro();
       
    79 
       
    80 use FindBin;
       
    81 use lib $FindBin::Bin."\\perllib";
       
    82 
       
    83 #use the DOM xml module
       
    84 use XML::DOM;
       
    85 
       
    86 my $projectTemplate;
       
    87 my $linkDescriptorTemplate;
       
    88 
       
    89 my $xmlParser;
       
    90 my $xmlProjectDoc;
       
    91 my $xmlLinkDescriptorDoc;
       
    92 my $xmlLinkDescriptorCommandParent;
       
    93 my $xmlLinkDescriptorSymbolParent;
       
    94 my $xmlLinkDescriptorDumpFileParent;
       
    95 
       
    96 my $xmlLinkOrder;		# for accumulating the link order
       
    97 my $xmlFileList;		# for accumulating the file list
       
    98 my $xmlSourceGroup;		# for accumulating the source
       
    99 my $xmlHeadersGroup;	# for accumulating local header files
       
   100 my $xmlRootGroup;		# for accumulating files to be added outside of project groups
       
   101 my $xmlLinkGroup;		# for accumulating the link descriptor files
       
   102 my $xmlLibGroup;		# for accumulating the libraries
       
   103 my $xmlResourcesGroup;	# for accumulating resource related files
       
   104 my $xmlDocumentsGroup;	# for accumulating supported files specified with DOCUMENT in the .mmp file
       
   105 
       
   106 my $MmpFile;
       
   107 my $VariantFile;
       
   108 my $PrefixFile;
       
   109 
       
   110 my $CW_major_version;
       
   111 my $CW_minor_version;
       
   112 my $CW_libpath;
       
   113 my @CW_librarypath;
       
   114 my @ToolChainLibList;
       
   115 
       
   116 # Hash to store configuration makefile data for furthur processing
       
   117 my %configdata;
       
   118 
       
   119 sub RoundUp1k($) {
       
   120 	# Accept C hexadecimal number (0xNNN).  Convert argument to Kb
       
   121 	# rounded up to the next 1kb boundary.
       
   122 	use integer;
       
   123 	return (hex($_[0]) + 1023) / 1024;
       
   124 }
       
   125 
       
   126 use Genutl;
       
   127 use cl_generic;
       
   128 
       
   129 my $ToolPrefix='';
       
   130 my $HelperLib='';
       
   131 my %PlatOpt=(
       
   132 	'Dlltool'=>'',
       
   133 	'Entry'=>'-e',
       
   134 	'Gcc'=>'',
       
   135 	'Ld'=>'',
       
   136 	'Petran'=>'',
       
   137 	'Optimize'=>'-O'
       
   138 );
       
   139 my $Dlltool;
       
   140 my $Archive;
       
   141 my $Link;
       
   142 my $Objcopy;
       
   143 
       
   144 my %CompatibleABIs=(
       
   145 	ARMI=>['ARM4', 'THUMB'],
       
   146 	ARM4=>['ARMI'],
       
   147 	THUMB=>['ARMI'],
       
   148 	ARMV5=>['ARMV5_ABIV1'],
       
   149 	GCCE=>['GCCE'],
       
   150 	BPABI=>['ARMV5_ABIV2']
       
   151 );
       
   152 my @CompatibleABIs;
       
   153 
       
   154 my $Makecmd;
       
   155 my %ABILibPath=();
       
   156 
       
   157 sub SystemTarget() {
       
   158 	return 1 if &main::SystemTrg;
       
   159 	my $ExportLibrary=&main::ExportLibrary;
       
   160 	# N.B. should get better way to detect kernel probably!!
       
   161 	return 1 if ($ExportLibrary =~ /EKERN/i);
       
   162 	
       
   163 	return 0;
       
   164 }
       
   165 
       
   166 sub SysTrg () {
       
   167 	return 1 if &main::SystemTrg;
       
   168 	my $ExportLibrary=&main::ExportLibrary;
       
   169 	return 1 if ($ExportLibrary =~ /EKERN/i);
       
   170 	my $Trg=&main::Trg;
       
   171 	return 1 if ($Trg =~ /KSRT/i);
       
   172 	return 0;
       
   173 }
       
   174 
       
   175 sub PMUnderlyingABI($) {
       
   176 	my ($ABI) = @_;
       
   177 	if ($ABI eq 'ARM4T') {
       
   178 		if (&main::BuildAsARM) {
       
   179 			return 'ARMI';
       
   180 		}
       
   181 		elsif (SystemTarget()) {
       
   182 			return 'ARM4';
       
   183 		}
       
   184 		else {
       
   185 			return 'ARMV4';
       
   186 		}
       
   187 	}
       
   188 	return $ABI;
       
   189 }
       
   190 
       
   191 ##### ARMV5 specific options #####
       
   192 my $diag_suppressions;
       
   193 my $diag_warnings;
       
   194 my $diag_errors;
       
   195 
       
   196 #The options here are handcoded for ABIV1 mode.
       
   197 my $contingentOptions;
       
   198 my $exceptions = ' --exceptions --exceptions_unwind';
       
   199 my $thumbOptions = '--thumb ';
       
   200 my $armOptions = '--arm ';
       
   201 my $kernelOptions = '--arm --no_exceptions --no_exceptions_unwind';
       
   202 my $invariantOptions = 
       
   203   '--cpu 5T --enum_is_int -Ono_known_library --fpmode ieee_no_fenv --export_all_vtbl --no_vfe --apcs /inter';
       
   204 $invariantOptions .= ' --dllimport_runtime' unless ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2);  
       
   205 # specify floating point model here
       
   206 my $floatingpointmodel = "softvfp";
       
   207 if (&main::ARMFPU && (&main::ARMFPU =~ /^VFPV2$/i)) {
       
   208 	$floatingpointmodel = "vfpv2";
       
   209 }
       
   210 my $floatingpoint = ' --fpu '.$floatingpointmodel.'';
       
   211 
       
   212 # Set compiler settings
       
   213 $diag_suppressions = '--diag_suppress 66,161,611,654,997,1152,1300,1464,1488,6318,6331';
       
   214 $diag_warnings = '';
       
   215 $diag_errors = '--diag_error 1267';
       
   216 my $commonOptions = "$diag_suppressions $diag_warnings $diag_errors";  
       
   217 # variables added to fetch the options from the BSF files
       
   218 my @commonOptions;
       
   219 my @thumbOptions;
       
   220 my @armOptions;
       
   221 my @kernelOptions;
       
   222 my @invariantOptions;
       
   223 my @linkerOptions;
       
   224 my @archiverOptions;
       
   225 
       
   226 my $linkCommand = "";		
       
   227 # variables to process and store the default and BSF file options
       
   228 my $invopts = $invariantOptions;
       
   229 my $linkeropts;
       
   230 my $archiveropts;
       
   231 #varible to store the BSF add options
       
   232 my $bsfaddoptions = undef;
       
   233 #variable to store the compiler flags, defs and other options
       
   234 my $CCFLAGS = undef;
       
   235 my $CCDEFS = undef;
       
   236 my $CCUREL = undef;
       
   237 my $CCUDEB = undef;
       
   238 
       
   239 
       
   240 #GCCE specific OPIONS
       
   241 
       
   242 my $GCCE_CompilerOption = '-march=armv5t -mthumb-interwork -mapcs';
       
   243 $GCCE_CompilerOption .= " -msoft-float -fexceptions -pipe -nostdinc -Wall -Wno-ctor-dtor-privacy -Wno-unknown-pragmas";
       
   244 #Flag to check for the customized GCCE platform
       
   245 my $CustGCCE=0;
       
   246 #Variable to fetch the Customized platform
       
   247 my %CustPlat=&main::PlatRec;
       
   248 #Flags to read the options
       
   249 my $kernelOption=0;
       
   250 my $buildAsArmOption=0;
       
   251 my $thumbOption=0;
       
   252 
       
   253 
       
   254 my $ArmIncDir;
       
   255 my @ArmLibList;
       
   256 my $ArmRT;
       
   257 
       
   258 my %BSF_keywords = (
       
   259 		    COMMON_OPTIONS => 1,
       
   260 		    THUMB_OPTIONS => 1,
       
   261 		    ARM_OPTIONS => 1,
       
   262 		    KERNEL_OPTIONS => 1,
       
   263 		    INVARIANT_OPTIONS => 1,
       
   264 			LD_OPTIONS => 1,
       
   265 			AR_OPTIONS => 1
       
   266 		   );
       
   267 sub PMStartBldList($) 
       
   268 {
       
   269 	($Makecmd) = @_;
       
   270 	my @BldList=&main::BldList;
       
   271 	my $BasicTrgType=&main::BasicTrgType;
       
   272 	my $ABI=&main::ABI;
       
   273 	my $kernelOption=0;
       
   274 	my $buildAsArmOption=0;
       
   275 	my $thumbOption=0;
       
   276 	my @MacroList=&main::MacroList();
       
   277 	push @MacroList, "__SUPPORT_CPP_EXCEPTIONS__ ";
       
   278 	my %plat = &main::PlatRec();
       
   279 
       
   280 	$CCFLAGS = "";
       
   281 	$CCDEFS = "";
       
   282 	$CCUREL = "";
       
   283 	$CCUDEB = "";
       
   284 	
       
   285 	$VariantFile=&main::VariantFile();	
       
   286 
       
   287 	#read the configuration make file into the hash for only the BPABI platforms
       
   288 	my $config_file = BPABIutl_Config_Path(&main::Plat);
       
   289 	if ($config_file) {
       
   290 		collect_config_data($config_file);
       
   291 	}
       
   292 		
       
   293 	Read_BSF_Options() if ($plat{'CUSTOMIZES'});
       
   294 
       
   295 	if (SysTrg()) {
       
   296 		$kernelOption=1;
       
   297 	} elsif (main::BuildAsARM() or ($ABI eq 'ARMV4')) {
       
   298 		$buildAsArmOption=1;
       
   299 	} else {
       
   300 		$thumbOption=1;
       
   301 	}
       
   302 
       
   303 	my $OtherOpts = undef;
       
   304 	my $toolchain = $configdata{COMPILER_PLAT};
       
   305 	
       
   306 	$OtherOpts = &main::CompilerOption($toolchain);
       
   307 	
       
   308 	if($kernelOption==1)
       
   309 	{
       
   310 		if(@kernelOptions) {
       
   311 # Kernel options as read from BSF file (KERNEL_OPTIONS keyword)
       
   312 			Set_BSF_Options('KERNEL_OPTIONS',\@kernelOptions);
       
   313 		}
       
   314 		$OtherOpts .= " ".fetch_config_data($configdata{KERNEL_OPTIONS});
       
   315 	}
       
   316 	elsif($buildAsArmOption==1)
       
   317 	{	
       
   318 		if(@armOptions) {
       
   319 # Arm options as read from BSF file (ARM_OPTIONS keyword)
       
   320 			Set_BSF_Options('ARM_OPTIONS',\@armOptions);
       
   321 		}
       
   322 		$OtherOpts .= " ".fetch_config_data($configdata{ARM_OPTIONS});	
       
   323 	}
       
   324 	elsif($thumbOption==1)
       
   325 	{
       
   326 		if(@thumbOptions) {
       
   327 # Thumb options as read from BSF file (THUMB_OPTIONS keyword)
       
   328 			Set_BSF_Options('THUMB_OPTIONS',\@thumbOptions);
       
   329 		}
       
   330 		$OtherOpts .= " ".fetch_config_data($configdata{THUMB_OPTIONS});
       
   331 	}
       
   332 	
       
   333 	if($thumbOption==1 || $buildAsArmOption==1)
       
   334 	{
       
   335 		if (&main::ARMFPU && (&main::ARMFPU =~ /^VFPV2$/i))
       
   336 		{
       
   337 			$OtherOpts .= "	".$configdata{VFP2MODE_OPTION};
       
   338 		}
       
   339 		else
       
   340 		{
       
   341 			$OtherOpts .= "	".$configdata{SOFTVFPMODE_OPTION};
       
   342 		}
       
   343 	}
       
   344 
       
   345 	if ($thumbOption==1)
       
   346 	{
       
   347 		$OtherOpts .= "	".$configdata{COMPILER_THUMB_DEFINES};
       
   348 	}
       
   349 	
       
   350 	$OtherOpts .= "	".$configdata{COMPILER_INTERWORK_DEFINES};
       
   351 	
       
   352 	if((&main::Plat eq "ARMV5_ABIV1") || (&main::Plat eq "ARMV5" && !$cfgMacro)
       
   353 	|| ($CustPlat{'CUSTOMIZES'} 
       
   354 	&& (($CustPlat{'ROOTPLATNAME'} eq "ARMV5_ABIV1" && $cfgMacro) 
       
   355 	|| ($CustPlat{'ROOTPLATNAME'} eq "ARMV5" && !$cfgMacro)))) {
       
   356 		ComputeCompilerOpts();
       
   357 	}
       
   358 	elsif($config_file) {
       
   359 		$CCFLAGS = &Cl_bpabi::getConfigVariable('CCFLAGS');
       
   360 	}
       
   361 	$CCFLAGS .= $OtherOpts;
       
   362 
       
   363 	if(@invariantOptions)
       
   364 	{
       
   365 	# Invariant options as read from BSF file (INVARIANT_OPTIONS keyword)
       
   366 		Set_BSF_Options('INVARIANT_OPTIONS',\@invariantOptions);
       
   367 	}
       
   368 	if(@commonOptions)
       
   369 	{
       
   370 	# Common options as read from BSF file (COMMON_OPTIONS keyword)
       
   371 		Set_BSF_Options('COMMON_OPTIONS',\@commonOptions);
       
   372 	}
       
   373 	if(@linkerOptions)
       
   374 	{
       
   375 	# Invariant options as read from BSF file (LD_OPTIONS keyword)
       
   376 		Set_BSF_Options('LD_OPTIONS',\@linkerOptions);
       
   377 	}
       
   378 	if ($BasicTrgType=~/^LIB$/o) {
       
   379 		if(@archiverOptions)
       
   380 		{
       
   381 		# Invariant options as read from BSF file (AR_OPTIONS keyword)
       
   382 			Set_BSF_Options('AR_OPTIONS',\@archiverOptions);
       
   383 		}	
       
   384 	}
       
   385 
       
   386 	if($bsfaddoptions)
       
   387 	{
       
   388 		fixbsfoptions($bsfaddoptions);
       
   389 	}
       
   390 	$CCFLAGS .= $bsfaddoptions;
       
   391 	$CCDEFS = $configdata{COMPILER_DEFINES};
       
   392 	$CCDEFS .= printlist("-D", @MacroList);
       
   393 	$CCDEFS .= $configdata{PLATFORM_DEFINES};
       
   394 
       
   395 	if($kernelOption==1)
       
   396 	{
       
   397 		$CCDEFS .= -D__KERNEL_MODE__;
       
   398 	}
       
   399 	
       
   400 	if($VariantFile) { 
       
   401 		$CCDEFS .= " -D__PRODUCT_INCLUDE__="."\\\"".&main::Path_Split('File',$VariantFile)."\\\"";
       
   402 	}
       
   403 	
       
   404 	foreach (@BldList) 
       
   405 	{
       
   406 		if($kernelOption == 0)
       
   407 		{
       
   408 			if (/DEB$/o) {
       
   409 				$CCUDEB .= " ".$configdata{EXCEPTIONS};
       
   410 			}
       
   411 			else {
       
   412 				$CCUREL .= " ".$configdata{EXCEPTIONS};
       
   413 			}
       
   414 		}
       
   415 		#collect the options and macro's depending on the whether it is a UREL or UDEB		
       
   416 		my @ml = &main::MacroList($_);
       
   417 		if (/DEB$/o) {
       
   418 			$CCUDEB .= " ".$CCFLAGS;
       
   419 			$CCUDEB .= printlist("-D", @ml);
       
   420 			$CCUDEB .= " ".$CCDEFS;
       
   421 		}
       
   422 		else {
       
   423 			$CCUREL .= " ".$CCFLAGS;
       
   424 			$CCUREL .= printlist("-D", @ml);
       
   425 			$CCUREL .= " ".$CCDEFS;
       
   426 		}
       
   427 	}
       
   428 }
       
   429 
       
   430 sub ComputeCompilerOpts() {
       
   431 	my %plat = &main::PlatRec();
       
   432 	my $ABI=&main::ABI;
       
   433 	my $TrgType=&main::TrgType;
       
   434 
       
   435 	if (SysTrg()) {
       
   436 	        $contingentOptions = $kernelOptions;
       
   437         } elsif (main::BuildAsARM() or ($ABI eq 'ARMV4')) {
       
   438 	        $contingentOptions = $armOptions.$floatingpoint.$exceptions;
       
   439 	    } else {
       
   440 			$contingentOptions = $thumbOptions.$floatingpoint.$exceptions.' -D__MARM_THUMB__';	
       
   441 	}
       
   442 	# change support for ARMV4
       
   443 	if ($ABI eq 'ARMV4') {
       
   444 		$invopts =~ s/5T/4/;
       
   445 		$invopts =~ s/inter/nointer/;
       
   446 	} else {
       
   447 		$contingentOptions .= ' -D__MARM_INTERWORK__';
       
   448 	}
       
   449 	$CCFLAGS = $commonOptions.' '.$contingentOptions.' '.$invopts.' -c '.' '.&main::CompilerOption("ARMCC");
       
   450 }
       
   451 
       
   452 sub GetMajorVersion ($)
       
   453 	{
       
   454 	my ($versionString) = @_;
       
   455 
       
   456 	if ($versionString =~ /^\d\.\d\.\d$/)
       
   457 		{
       
   458 		$versionString =~ s/\.\d$//;
       
   459 		}
       
   460 
       
   461 	return $versionString;
       
   462 	}
       
   463 
       
   464 sub GetMinorVersion ($)
       
   465 	{
       
   466 	my ($versionString) = @_;
       
   467 
       
   468 	if ($versionString =~ /^\d\.\d\.\d$/)
       
   469 		{
       
   470 		$versionString =~ s/^\d\.\d\.//;
       
   471 		}
       
   472 	else
       
   473 		{
       
   474 		$versionString = 0;
       
   475 		}
       
   476 
       
   477 	return $versionString;
       
   478 	}
       
   479 
       
   480 sub PMCheckPlatformL {
       
   481 
       
   482 	# check version of CodeWarrior for Symbian OS
       
   483 
       
   484 	my @compatibleCWInstallations;
       
   485 
       
   486 	$CW_major_version = 0;
       
   487 	$CW_minor_version = 0;
       
   488 
       
   489 	my $minimumMajorVersion = GetMajorVersion ($CW_minimum_supported_version);
       
   490 	my $minimumMinorVersion = GetMinorVersion ($CW_minimum_supported_version);
       
   491 
       
   492 	if (defined $ENV{CW_SYMBIAN_VERSION})
       
   493 		{
       
   494 		# CW_SYMBIAN_VERSION is set - either MAKMAKE is being executed by an IDE's .mmp Importer,
       
   495 		# or the user is specifying a specific CW version to target from the command line.
       
   496 		# Either way, we've been given a single version to target, so we attempt to do just that.
       
   497 
       
   498 		$CW_major_version = GetMajorVersion ($ENV{CW_SYMBIAN_VERSION});
       
   499 		$CW_minor_version = GetMinorVersion ($ENV{CW_SYMBIAN_VERSION});
       
   500 		
       
   501 		push @compatibleCWInstallations, $ENV{CW_SYMBIAN_VERSION};
       
   502 		}
       
   503 	else
       
   504 		{
       
   505 		# CW_SYMBIAN_VERSION isn't set - either MAKMAKE is being executed by a pre-OEM3.0 IDE .mmp
       
   506 		# Importer or from the command line.  Either way, we delve into the registry and attempt to
       
   507 		# target the latest CW for Symbian OS installed, recording all CW for Symbian OS installations
       
   508 		# too.
       
   509 
       
   510 		my $regKeyHandle;
       
   511 		my $topLevelKey = HKEY_LOCAL_MACHINE;
       
   512 		my $productVersionKey = 'SOFTWARE\\Metrowerks\\CodeWarrior\\Product Versions';
       
   513 
       
   514 		if (!RegOpenKeyEx($topLevelKey, $productVersionKey, 0, KEY_READ, $regKeyHandle))
       
   515 			{		    		
       
   516 			die "Can't read \"HKEY_LOCAL_MACHINE\\$productVersionKey\" : ", regLastError(), "\n";
       
   517 		    }
       
   518 
       
   519 		my $subKeyIndex = 0;
       
   520 		my $subKeySize = 0;
       
   521 		my $subKeyName;
       
   522 
       
   523 		my @installedCWForSymbianKeys;
       
   524 
       
   525 		while (RegEnumKeyEx($regKeyHandle, $subKeyIndex, $subKeyName, $subKeySize, [], [], [], []))
       
   526 			{
       
   527 			push (@installedCWForSymbianKeys, $productVersionKey."\\".$subKeyName) unless ($subKeyName !~ /Symbian/);
       
   528 			$subKeyIndex++;
       
   529 			}
       
   530 
       
   531 		RegCloseKey($regKeyHandle) || print STDERR "WARNING: Could not close registry key.";
       
   532 
       
   533 		my $versionType;
       
   534 		my $versionValue;
       
   535 
       
   536 		foreach my $installedCWForSymbianKey (@installedCWForSymbianKeys)
       
   537 			{
       
   538 			if (!RegOpenKeyEx($topLevelKey, $installedCWForSymbianKey, 0, KEY_READ, $regKeyHandle))
       
   539 				{		    		
       
   540 				die "Can't read \"HKEY_LOCAL_MACHINE\\$installedCWForSymbianKey\" : ", regLastError(), "\n";
       
   541 			    }
       
   542 
       
   543 			if (!RegQueryValueEx($regKeyHandle, "VERSION", [], $versionType, $versionValue, []))
       
   544 				{
       
   545 				die "Can't read \"HKEY_LOCAL_MACHINE\\$installedCWForSymbianKey\\VERSION\" : ", regLastError(), "\n";
       
   546 				}
       
   547 
       
   548 			my $temp_major_version = GetMajorVersion ($versionValue);
       
   549 			my $temp_minor_version = GetMinorVersion ($versionValue);
       
   550 
       
   551 			if (($temp_major_version > $CW_major_version) ||
       
   552 				(($temp_minor_version > $CW_minor_version) &&
       
   553 				   ($temp_major_version >= $CW_major_version)))
       
   554 				{
       
   555 				$CW_major_version = $temp_major_version;
       
   556 				$CW_minor_version = $temp_minor_version;
       
   557 				}
       
   558 			
       
   559 			if (($temp_major_version > $minimumMajorVersion) ||
       
   560 				(($temp_minor_version > $minimumMinorVersion) &&
       
   561 				   ($temp_major_version >= $minimumMajorVersion)))
       
   562 				{
       
   563 				push @compatibleCWInstallations, $versionValue;
       
   564 				}
       
   565 
       
   566 			RegCloseKey($regKeyHandle);
       
   567 			}
       
   568 		}
       
   569 
       
   570 	# We've determined a CW version to target, now we validate if we actually support this
       
   571 
       
   572 	if (!$CW_major_version ||
       
   573 		($CW_major_version < $minimumMajorVersion) ||
       
   574 		(($CW_major_version >= $minimumMajorVersion) && ($CW_minor_version < $minimumMinorVersion)))
       
   575 		{
       
   576 		if (defined $ENV{CW_SYMBIAN_VERSION})
       
   577 			{
       
   578 			die "Error: CW_SYMBIAN_VERSION is set to $ENV{CW_SYMBIAN_VERSION}.\n       The minimum version supported by these tools is $CW_minimum_supported_version.\n";
       
   579 			}
       
   580 		else
       
   581 			{
       
   582 			die "ERROR: Unable to identify a compatible CodeWarrior for Symbian OS installation.\n";
       
   583 			}
       
   584 		}
       
   585 
       
   586 	if (@compatibleCWInstallations > 1)
       
   587 		{
       
   588 		my $targetVersion = $CW_major_version;
       
   589 		$targetVersion .= ".$CW_minor_version" if $CW_minor_version;
       
   590 			
       
   591 		print ("Info: More than one compatible CodeWarrior for Symbian OS installation has been detected.\n");
       
   592 		print ("      The generated project will target $targetVersion - to override this, set the CW_SYMBIAN_VERSION\n");
       
   593 		print ("      environment variable to the version number you wish to target and re-run this command.\n");
       
   594 		print ("      Supported version numbers detected : @compatibleCWInstallations.\n");
       
   595 		}
       
   596 	else
       
   597 		{
       
   598 		print ("Info: Detected CodeWarrior Version Major=$CW_major_version Minor=$CW_minor_version\n");
       
   599 		}
       
   600 
       
   601 	# CW version has been validated, tailor generated projects on this basis
       
   602 
       
   603 	$CW_libpath = 'Symbian_Support\Win32-x86 Support\Libraries\Win32 SDK';
       
   604  	push @CW_librarypath,$CW_libpath;
       
   605  	# Lib path to support the Carbide runtime libraries
       
   606  	$CW_libpath = 'Symbian_Support\Runtime\Runtime_x86\Runtime_Win32\Libs';
       
   607  	push @CW_librarypath,$CW_libpath;
       
   608 		
       
   609 	if ($CW_major_version == 2.8)
       
   610 		{
       
   611 		$projectTemplate = "CW_project_template_v3.xml";
       
   612 		$linkDescriptorTemplate = "cw_link_descriptor_template.cwlink";
       
   613 		}
       
   614 	else
       
   615 		{
       
   616 		$projectTemplate = "CW_project_template_v4.xml";
       
   617 		$linkDescriptorTemplate = "cw_link_descriptor_template_v2.cwlink";		
       
   618 		}
       
   619 		
       
   620 	$xmlParser = new XML::DOM::Parser; 
       
   621 	$xmlProjectDoc = $xmlParser->parsefile ($FindBin::Bin."\\$projectTemplate");
       
   622 }
       
   623 
       
   624 # Check if a platform is a customization
       
   625 sub IsCustomization($) {
       
   626 	my ($plat) = @_;
       
   627 	return 1 if (Plat_Customizes($plat));
       
   628 	return 0;
       
   629 }
       
   630 
       
   631 sub PMPlatProcessMmp (@) {
       
   632 	
       
   633 	my $currentPlat=&main::Plat;
       
   634 
       
   635 	return if ($processedPlatforms{$currentPlat});
       
   636 	$processedPlatforms{$currentPlat}=1;
       
   637 	@ToolChainLibList = &GetLibList;
       
   638 	my $TrgType=&main::TrgType;
       
   639 	if ($CustPlat{'CUSTOMIZES'} && ($CustPlat{'ROOTPLATNAME'} eq "GCCE"))
       
   640 	{
       
   641 		$CustGCCE=1;
       
   642 	}
       
   643 
       
   644 	if ($currentPlat =~ /^WINSCW$/)
       
   645 		{	
       
   646 		my $includes = $ENV{MWCWinx86Includes};
       
   647 		&Winutl_DoMmp_Parse(\@_, $includes);
       
   648 		@Win32LibList=&Winutl_Win32LibList;
       
   649 		$Win32Resrc=&Winutl_Win32Resrc;
       
   650 		$Win32StdHeaders=&Winutl_Win32StdHeaders;
       
   651 		$BaseAddress=&Winutl_BaseAddress unless ($TrgType eq 'EXE');
       
   652 		}
       
   653 	elsif ($currentPlat =~ /^ARMV5/ || IsCustomization($currentPlat))
       
   654 		{	
       
   655 		&Armutl_DoMmp(@_);
       
   656 		$ArmIncDir = &Armutl_ArmIncDir;
       
   657 		&main::SetStdIncPaths($ArmIncDir);
       
   658 		@ArmLibList = &Armutl_ArmLibList;
       
   659 		$ArmRT = &Armutl_ArmRT;
       
   660 		}
       
   661 
       
   662 	my $BaseTrg=&main::BaseTrg;
       
   663 	my $MakeFilePath=&main::MakeFilePath;
       
   664 	$MmpFile=&main::MmpFile;
       
   665 	$VariantFile=&main::VariantFile();		
       
   666 
       
   667 	# Set up the list of known roots
       
   668 
       
   669 	my $epocroot=&main::Path_Drive . &main::EPOCPath;
       
   670 	$epocroot =~ s/EPOC32\\$//i;
       
   671 
       
   672 	if ($currentPlat eq "GCCE" || $CustGCCE)
       
   673 	{
       
   674 		$PrefixFile=$epocroot.'epoc32\\include\\gcce\\gcce.h';
       
   675 	}
       
   676 	else
       
   677 	{
       
   678 		$PrefixFile=$epocroot.'epoc32\\include\\rvct'.$RVCTVersion.'\\rvct'.$RVCTVersion.'.h';
       
   679 	}
       
   680 	my $mmproot = &main::Path_Drive . &main::Path_Split('Path',$MmpFile);
       
   681 	my $mmprootname = "MMPDir";
       
   682 	my $mmpisglobal = 0;
       
   683 
       
   684 	if (defined $ENV{CW_ROOT_NAME})
       
   685 		{
       
   686 		# generate KnownRoots suitable for the IDE MMP importer
       
   687 		# This has a global source tree for EPOCROOT, and puts the
       
   688 		# project next to the MMP file
       
   689 
       
   690 		addKnownRoot($ENV{CW_ROOT_NAME}, 1, $epocroot, "");
       
   691 		$mmprootname = "Project";
       
   692 		$mmpisglobal = 1;
       
   693 		}
       
   694 	else
       
   695 		{
       
   696 		# generate KnownRoots suitable for command-line generated XML files
       
   697 		# We will add a user source tree for MMPDir and EPOCROOT, but can't use
       
   698 		# EPOCROOT for the OutputDirectory
       
   699 
       
   700 		addKnownRoot("EPOCROOT", 0, $epocroot, "");
       
   701 		}
       
   702 	addKnownRoot($mmprootname, $mmpisglobal, $mmproot, "");
       
   703 
       
   704 	# Allow for MMP files in component subdirectories by matching multiple levels
       
   705 	# up to get {MMPDir}..\whatever paths. Stop one level down from the root,
       
   706 	# since "everything on this drive" seems a bit extreme
       
   707 	#
       
   708 	my $tmppath = $mmproot;
       
   709 	my $dotdots = '';
       
   710 	while ($tmppath =~ /^(.:.+\\)[^\\]+\\$/i)
       
   711 		{
       
   712 		$tmppath = $1;
       
   713 		$dotdots .= "..\\";
       
   714 		addKnownRoot($mmprootname, $mmpisglobal, $tmppath, $dotdots);
       
   715 		}
       
   716 }
       
   717 
       
   718 sub findTarget($$$) {
       
   719 	my ($name,$platbld,$abibld) = @_;
       
   720 
       
   721 	my @targets = $xmlProjectDoc->getElementsByTagName("TARGET",1); 
       
   722 
       
   723 	foreach my $target (@targets)
       
   724 		{
       
   725 		
       
   726 		my $element = $target->getElementsByTagName("NAME",0)->item(0);
       
   727 		$element = $element->getFirstChild;
       
   728 		
       
   729 	#   here we want to get the plat build that is specified in the cw project tempalte
       
   730 	#   and not the abi build - there are more platbuilds than abibuilds so other targets
       
   731 	#   (e.g. GCCE) can get the wrong tempalte "NAME" (i.e. it will be ARMV5 rather than GCCE, which is not want we want)
       
   732 		if ($element->getData() =~ /$platbld$/)
       
   733 			{
       
   734 			
       
   735 			my $newtarget=$target->cloneNode(1);
       
   736 			$target->getParentNode()->appendChild($newtarget);
       
   737 			$element = $newtarget->getElementsByTagName("NAME",0)->item(0);
       
   738 			$element = $element->getFirstChild;
       
   739 			$element->setData("$platbld");
       
   740 			
       
   741 			# remember name as an attribute: this is removed before
       
   742 			# writing out the project.
       
   743 			$newtarget->setAttribute("NAME", "$platbld");
       
   744 			return $newtarget;
       
   745 			}
       
   746 			else
       
   747 			{
       
   748 				my $newtarget=$target->cloneNode(1);
       
   749 				my $newplat=&main::Plat." ".&main::Bld;
       
   750 				$target->getParentNode()->appendChild($newtarget);
       
   751 				$element = $newtarget->getElementsByTagName("NAME",0)->item(0);
       
   752 				$element = $element->getFirstChild;
       
   753 				$element->setData("$newplat");
       
   754 	 			
       
   755 				# remember name as an attribute: this is removed before
       
   756 				# writing out the project.
       
   757 				$newtarget->setAttribute("NAME", "$newplat");
       
   758 				return $newtarget;
       
   759 			}
       
   760 		}
       
   761 	return undef;
       
   762 }
       
   763 
       
   764 sub newList($$$) {
       
   765 	my ($target, $tag, $replace) = @_;
       
   766 
       
   767 	my $newlist = new XML::DOM::Element($xmlProjectDoc,$tag);
       
   768 	if ($replace==1)
       
   769 		{
       
   770 		my $elements = $target->getElementsByTagName($tag,0);
       
   771 		my $element = $elements->item(0);
       
   772 		$target->replaceChild($newlist, $element);
       
   773 		}
       
   774 	else
       
   775 		{
       
   776 		$target->appendChild($newlist);
       
   777 		}
       
   778 	return $newlist;
       
   779 }
       
   780 
       
   781 sub changeValue($$) {
       
   782 	my ($setting, $replacement) = @_;
       
   783 	my $value = $setting->getElementsByTagName("VALUE",0)->item(0);
       
   784 
       
   785 	if (defined $value)
       
   786 		{
       
   787 		if ($value->hasChildNodes)
       
   788 			{
       
   789 			$value->getFirstChild->setData($replacement);
       
   790 			}
       
   791 		else
       
   792 			{
       
   793 			$value->addText($replacement);
       
   794 			}
       
   795 		}
       
   796 }
       
   797 
       
   798 sub textSetting($$$$) {
       
   799 	my ($element,$name,$value,$insertionpoint)=@_;
       
   800 
       
   801 	my $setting = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
   802 	&textElement($setting, "NAME", $name);
       
   803 	&textElement($setting, "VALUE", $value);
       
   804 	$element->insertBefore($setting, $insertionpoint);
       
   805 	$element->addText("\n");
       
   806 }
       
   807 
       
   808 sub addKnownRoot($$$$) {
       
   809 	my ($rootname, $global, $rootpath, $pathprefix) = @_;
       
   810 	$rootpath=&main::Path_Chop($rootpath);
       
   811 	push @KnownRoots, [$rootname, $global, quotemeta($rootpath), $pathprefix];
       
   812 }
       
   813 
       
   814 sub addRootedPath($$$) {
       
   815 	my ($setting,$needglobal,$path) = @_;
       
   816 	my $root = "Absolute";
       
   817 
       
   818 	if ($path =~ /^\\/)
       
   819 		{
       
   820 		$path = &main::Path_Drive . $path;	# ensure it has a drive letter
       
   821 		}
       
   822 
       
   823 	foreach (@KnownRoots)
       
   824 		{
       
   825 		my ($rootname, $global, $rootpath, $pathprefix) = @{$_};
       
   826 
       
   827 		next if ($needglobal && !$global);
       
   828 		if ($path =~ /^$rootpath\\/i)
       
   829 			{			
       
   830 			$path =~ s/^$rootpath\\/$pathprefix/i;
       
   831 			$root = $rootname;
       
   832 			last;
       
   833 			}
       
   834 		}
       
   835 	$path=&main::Path_Chop($path);
       
   836 	if ($root eq "Absolute" && $path =~ /^(.:)$/)
       
   837 		{
       
   838 		$path .= "\\";
       
   839 		}
       
   840 
       
   841 	&textSetting($setting, "Path", $path);
       
   842 	&textSetting($setting, "PathFormat", "Windows");
       
   843 	&textSetting($setting, "PathRoot", $root);
       
   844 }
       
   845 
       
   846 sub changePathSetting($$$) {	
       
   847 	my ($setting,$global,$value) = @_;
       
   848 
       
   849 	my @oldstuff = $setting->getElementsByTagName("SETTING",0);
       
   850 	foreach my $old (@oldstuff)
       
   851 		{
       
   852 		&removeNode($old);
       
   853 		}
       
   854 
       
   855 	&addRootedPath($setting,$global,$value);
       
   856 }
       
   857 
       
   858 sub addSourceTrees($) {
       
   859 	my ($node) = @_;
       
   860 
       
   861 	my $element = $node->getElementsByTagName("VALUE",0)->item(0);
       
   862 	&removeNode($element) if (defined $element);
       
   863 
       
   864 	if (defined $ENV{CW_ROOT_NAME})
       
   865 		{
       
   866 		return;	# paths were converted to be relative to global source trees
       
   867 		}
       
   868 
       
   869 	my $sourcepath = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
   870 	$sourcepath->addText("\n");
       
   871 	&textSetting($sourcepath, "Name", "EPOCROOT");
       
   872 	&textSetting($sourcepath, "Kind", "AbsolutePath");
       
   873 
       
   874 	my $pathdata = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
   875 	&textElement($pathdata, "NAME", "Path"); 
       
   876 	$pathdata->addText("\n");
       
   877 
       
   878 	my $epocroot=&main::EPOCPath;
       
   879 	$epocroot =~ s/\\EPOC32\\$/\\/i;
       
   880 
       
   881 	&addRootedPath($pathdata, 1, $epocroot);
       
   882 
       
   883 	$sourcepath->appendChild($pathdata);
       
   884 	$node->appendChild($sourcepath);
       
   885 
       
   886 	my $mmproot = &main::Path_Split('Path',$MmpFile);
       
   887 	my $sourcepath2 = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
   888 	$sourcepath2->addText("\n");
       
   889 	&textSetting($sourcepath2, "Name", "MMPDir");
       
   890 	&textSetting($sourcepath2, "Kind", "AbsolutePath");
       
   891 
       
   892 	my $pathdata2 = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
   893 	&textElement($pathdata2, "NAME", "Path"); 
       
   894 	$pathdata2->addText("\n");
       
   895 	&addRootedPath($pathdata2, 1, $mmproot);
       
   896 
       
   897 	$sourcepath2->appendChild($pathdata2);
       
   898 	$node->appendChild($sourcepath2);
       
   899 
       
   900 }
       
   901 
       
   902 sub addUserSearchPaths($) {
       
   903 	my ($node) = @_;
       
   904 
       
   905 	my @elements = $node->getElementsByTagName("SETTING",0);
       
   906 	foreach (@elements)
       
   907 		{
       
   908 		&removeNode($_);
       
   909 		}
       
   910 
       
   911 	my %ordereddirs;
       
   912 	my @ordereddirlist=();
       
   913 	foreach my $dir (&main::UserIncPaths)
       
   914 		{
       
   915 		next if (!defined $dir);
       
   916 		$dir = &main::Path_Chop($dir)."\\";
       
   917 		my $key = uc $dir;
       
   918 		if (! defined($ordereddirs{$key}))
       
   919 			{
       
   920 			$ordereddirs{$key}=1;
       
   921 			push @ordereddirlist, $dir;
       
   922 			}
       
   923 		}
       
   924 
       
   925 	# now add the directories used to find source files
       
   926 	
       
   927 	my %dirs;
       
   928 	my $SourceStructRef=&main::SourceStructRef;
       
   929 	foreach my $SourceRef (@$SourceStructRef)
       
   930 		{
       
   931 		 $dirs{$$SourceRef{SrcPath}}=1;
       
   932 		}
       
   933 	my $DefFile = &main::DefFile;
       
   934 	if ($DefFile)
       
   935 		{			
       
   936 		$DefFile = &main::Path_Split('Path',$DefFile);
       
   937 		$dirs{$DefFile}=1;
       
   938 		}
       
   939 
       
   940 	my $MmpFilePath = &main::Path_Split('Path',$MmpFile);
       
   941 	$dirs{$MmpFilePath}=1;
       
   942 		
       
   943 	$dirs{$ExtraFilesPath}=1;
       
   944 		
       
   945 
       
   946 	foreach my $srcdir (sort keys %dirs)
       
   947 		{
       
   948 		if (!defined($ordereddirs{uc $srcdir}))
       
   949 			{
       
   950 			push @ordereddirlist, $srcdir;
       
   951 			}
       
   952 		}
       
   953 		
       
   954 	foreach my $srcdir (@ordereddirlist)
       
   955 		{
       
   956 		my $accesspath = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
   957 		$accesspath->addText("\n");
       
   958 		my $pathdata = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
   959 		&textElement($pathdata, "NAME", "SearchPath"); 
       
   960 		$pathdata->addText("\n");
       
   961 		&addRootedPath($pathdata, 0, $srcdir);
       
   962 
       
   963 		$accesspath->appendChild($pathdata);
       
   964 		&textSetting($accesspath, "Recursive", "false");
       
   965 		&textSetting($accesspath, "FrameworkPath", "false");
       
   966 		&textSetting($accesspath, "HostFlags", "All");
       
   967 		$node->appendChild($accesspath);
       
   968 		}
       
   969 }
       
   970 
       
   971 sub addSystemSearchPaths($) {
       
   972 	my ($node) = @_;
       
   973 
       
   974 	my @elements = $node->getElementsByTagName("SETTING",0);
       
   975 	foreach (@elements)
       
   976 		{
       
   977 		&removeNode($_);
       
   978 		}
       
   979 
       
   980 	my $ASSPLinkPath;
       
   981 	$ASSPLinkPath = &main::ASSPLinkPath if (&main::ASSPLibList);
       
   982 
       
   983 	my @extraIncPaths=();
       
   984 	push @extraIncPaths, $ArmIncDir if $ArmIncDir;
       
   985 
       
   986 	my %ordereddirs;
       
   987 	my @ordereddirlist=();
       
   988 	
       
   989 	foreach my $dir (&main::SysIncPaths, @extraIncPaths, &main::StatLinkPath, $ASSPLinkPath, &main::LinkPath)
       
   990 		{
       
   991 		next if (!defined $dir);
       
   992 		$dir = &main::Path_Chop($dir)."\\";
       
   993 		my $key = uc $dir;
       
   994 		if (! defined($ordereddirs{$key}))
       
   995 			{
       
   996 			$ordereddirs{$key}=1;
       
   997 			push @ordereddirlist, $dir;
       
   998 			}
       
   999 		}
       
  1000 
       
  1001 	my %dirs;
       
  1002 
       
  1003 	if ($VariantFile)
       
  1004 		{
       
  1005 		my $VariantFilePath = &main::Path_Split('Path',$VariantFile);
       
  1006 		$dirs{$VariantFilePath}=1;
       
  1007 		}
       
  1008 
       
  1009 	if (((&main::Plat =~ /^ARMV5/) || (&main::Plat =~ /^GCCE$/) ||(IsCustomization(&main::Plat))) && $PrefixFile) 
       
  1010 		{
       
  1011 		my $PrefixFilePath = &main::Path_Split('Path',$PrefixFile);
       
  1012 		$dirs{$PrefixFilePath}=1;
       
  1013 		}
       
  1014 
       
  1015 	foreach my $srcdir (sort keys %dirs)
       
  1016 		{
       
  1017 		if (!defined($ordereddirs{uc $srcdir}))
       
  1018 			{
       
  1019 			push @ordereddirlist, $srcdir;
       
  1020 			}
       
  1021 		}
       
  1022 		
       
  1023 	foreach my $srcdir (@ordereddirlist)
       
  1024 		{
       
  1025 		my $accesspath = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
  1026 		$accesspath->addText("\n");
       
  1027 		my $pathdata = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
  1028 		&textElement($pathdata, "NAME", "SearchPath"); 
       
  1029 		$pathdata->addText("\n");
       
  1030 		&addRootedPath($pathdata, 0, $srcdir);
       
  1031 
       
  1032 		$accesspath->appendChild($pathdata);
       
  1033 		&textSetting($accesspath, "Recursive", "false");
       
  1034 		&textSetting($accesspath, "FrameworkPath", "false");
       
  1035 		&textSetting($accesspath, "HostFlags", "All");
       
  1036 		$node->appendChild($accesspath);
       
  1037 		}
       
  1038 	
       
  1039 	if (&main::Plat =~ /^WINSCW$/)
       
  1040 	{
       
  1041  		my $lpath;
       
  1042  		foreach $lpath (@CW_librarypath)
       
  1043  		{
       
  1044  			# only add Win32 SDK for WINSCW system access paths	
       
  1045  			my $accesspath = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
  1046  			$accesspath->addText("\n");
       
  1047  			my $pathdata = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
  1048  			&textElement($pathdata, "NAME", "SearchPath"); 
       
  1049  			$pathdata->addText("\n");
       
  1050  			
       
  1051  			&textSetting($pathdata, "Path", $lpath);
       
  1052  			&textSetting($pathdata, "PathFormat", "Windows");
       
  1053  			&textSetting($pathdata, "PathRoot", "CodeWarrior");
       
  1054  			$accesspath->appendChild($pathdata);
       
  1055  			&textSetting($accesspath, "Recursive", "false");
       
  1056  			&textSetting($accesspath, "FrameworkPath", "false");
       
  1057  			&textSetting($accesspath, "HostFlags", "All");
       
  1058  			$node->appendChild($accesspath);
       
  1059  		}
       
  1060 	}
       
  1061 	if ($CustPlat{'CUSTOMIZES'} && ($CustPlat{'ROOTPLATNAME'} eq "GCCE"))
       
  1062 	{
       
  1063 		$CustGCCE=1;
       
  1064 	}
       
  1065 	if (&main::Plat =~ /^GCCE$/ || $CustGCCE)
       
  1066 	{
       
  1067 		my $accesspath = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
  1068 		$accesspath->addText("\n");
       
  1069 		my $pathdata = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
  1070 		&textElement($pathdata, "NAME", "SearchPath"); 
       
  1071 		$pathdata->addText("\n");
       
  1072 		
       
  1073 		my $GCCE_IncludePath = GetGCCELibPath("-print-libgcc-file-name");
       
  1074 		$GCCE_IncludePath .= '\\include';
       
  1075 		&textSetting($pathdata, "Path", $GCCE_IncludePath);
       
  1076 		
       
  1077 		&textSetting($pathdata, "PathFormat", "Windows");
       
  1078 		&textSetting($pathdata, "PathRoot", "Absolute");
       
  1079 		$accesspath->appendChild($pathdata);
       
  1080 		&textSetting($accesspath, "Recursive", "false");
       
  1081 		&textSetting($accesspath, "FrameworkPath", "false");
       
  1082 		&textSetting($accesspath, "HostFlags", "All");
       
  1083 		$node->appendChild($accesspath);
       
  1084 	}
       
  1085 	
       
  1086 }
       
  1087 
       
  1088 sub addDownloadFileList($) {
       
  1089 	my ($node, @DownloadList) = @_;
       
  1090 	
       
  1091 	my @elements = $node->getElementsByTagName("SETTING",0);
       
  1092 	foreach (@elements)
       
  1093 		{
       
  1094 		&removeNode($_);
       
  1095 		}
       
  1096 
       
  1097 	my $epocdata = &main::EPOCPath . "data\\";
       
  1098 	foreach my $srcfile (@DownloadList)
       
  1099 		{
       
  1100 		my $targetpath = $srcfile;
       
  1101 		$targetpath =~ s/^Z\\/C:\\/i;
       
  1102 		
       
  1103 		my $download = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
  1104 		$download->addText("\n");
       
  1105 		my $pathdata = new XML::DOM::Element($xmlProjectDoc,"SETTING");
       
  1106 		&textElement($pathdata, "NAME", "HostFilePath"); 
       
  1107 		$pathdata->addText("\n");
       
  1108 		&addRootedPath($pathdata, 0, "$epocdata$srcfile");
       
  1109 
       
  1110 		$download->appendChild($pathdata);
       
  1111 		&textSetting($download, "TargetFilePath", $targetpath);
       
  1112 		$node->appendChild($download);
       
  1113 		}
       
  1114 	}
       
  1115 
       
  1116 sub kitRelativePath ($) {
       
  1117 	my ($kitRootBasedPath) = @_;
       
  1118 		
       
  1119 	my $kitRoot = &main::EPOCPath;
       
  1120 	$kitRoot =~ s/EPOC32\\$//i;
       
  1121 	$kitRoot = quotemeta (&main::Path_Chop($kitRoot));
       
  1122 
       
  1123 	$kitRootBasedPath =~ s/^$kitRoot//i;
       
  1124 
       
  1125 	$kitRootBasedPath;
       
  1126 }
       
  1127 	
       
  1128 sub PMBld() {
       
  1129 
       
  1130 	my %changedsettings;
       
  1131 
       
  1132 	my $ABI=&main::ABI;
       
  1133 	my $Bld=&main::Bld;
       
  1134 	my $Plat=&main::Plat;
       
  1135 	my $BaseName=&main::BaseMak;
       
  1136 	my @SrcList=&main::SrcList;
       
  1137 	my $BaseTrg=&main::BaseTrg;
       
  1138 	my @BldList=&main::BldList;
       
  1139 	my $DefFile=&main::DefFile;
       
  1140 	my $FirstLib=&main::FirstLib;
       
  1141 	# IsCustomDllUseCase() subroutine is called to check if the given executable 
       
  1142 	# is a custom dll or not.
       
  1143 	my $IsCustomDll = Cl_bpabi::IsCustomDllUseCase();
       
  1144 	# ABI flags set depending on the ENABLE_ABIV2_MODE macro set in the variant file.
       
  1145 	my $ABIV1 = 0;
       
  1146 	my $ABIV2 = 0;
       
  1147 	if (($Plat eq "ARMV5_ABIV1" && $cfgMacro) || ($Plat eq "ARMV5" && !$cfgMacro)
       
  1148 	|| ($CustPlat{'CUSTOMIZES'} 
       
  1149 	&& (($CustPlat{'ROOTPLATNAME'} eq "ARMV5_ABIV1" && $cfgMacro) || ($CustPlat{'ROOTPLATNAME'} eq "ARMV5" && !$cfgMacro))))
       
  1150 	{
       
  1151 		$ABIV1=1;
       
  1152 	}
       
  1153 	elsif (($Plat eq "ARMV5_ABIV2" && !$cfgMacro) || ($Plat eq "ARMV5" && $cfgMacro)
       
  1154 	|| ($CustPlat{'CUSTOMIZES'} 
       
  1155 	&& (($CustPlat{'ROOTPLATNAME'} eq "ARMV5_ABIV2" && !$cfgMacro) || ($CustPlat{'ROOTPLATNAME'} eq "ARMV5" && $cfgMacro))))
       
  1156 	{
       
  1157 		$ABIV2=1;
       
  1158 	}
       
  1159 	
       
  1160 	if ($CustPlat{'CUSTOMIZES'} && ($CustPlat{'ROOTPLATNAME'} eq "GCCE"))
       
  1161 	{
       
  1162 		$CustGCCE=1;
       
  1163 	}
       
  1164 
       
  1165  	if ($ABIV1 && ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2)) {
       
  1166 	        # Temporary Workaround for RVCT2.1 static libs problem with RVCT2.2 builds
       
  1167 		# Rename FirstLib.lib static lib used with RVCT2.1 as FirstLib2_1.lib
       
  1168 		if ($FirstLib=~/^\s*(\S+)(\.lib)$/io) {
       
  1169 		        if ($1!~/$RVCTVersion/i) {
       
  1170 				$FirstLib=$1.$RVCTVersion.".lib";
       
  1171 			}
       
  1172 		}
       
  1173 	}	
       
  1174 
       
  1175 	my $BasicTrgType=&main::BasicTrgType;
       
  1176 	my @LibList;
       
  1177 	my @StatLibList=&main::StatLibList;
       
  1178 	if ($ABIV1 && ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2)) {
       
  1179 	        # Temporary Workaround for RVCT2.1 static libs problem with RVCT2.2 builds
       
  1180 		# Rename all the static libs used with RVCT2.1 as libname2_1.lib
       
  1181 		for (my $i =0; $i < scalar(@StatLibList); $i++) {
       
  1182 		        if ($StatLibList[$i]=~/^\s*(\S+)(\.lib)$/io) {
       
  1183 			        if ($1!~/$RVCTVersion/i) {
       
  1184 				        $StatLibList[$i]=$1.$RVCTVersion.".lib";
       
  1185 				}
       
  1186 			}
       
  1187 		}
       
  1188 	}
       
  1189 	
       
  1190 
       
  1191 	my @ASSPLibList = &main::ASSPLibList;
       
  1192 	my $Trg=&main::Trg;
       
  1193 	if ($ABIV1 && ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2)) {
       
  1194 		if ($BasicTrgType=~/^LIB$/o) {
       
  1195 			# Temporary Workaround for RVCT2.1 static libs problem with RVCT2.2 builds
       
  1196 			# Rename all the static libs produced with RVCT2.1 as {libname}2_1.lib
       
  1197 		        if ($Trg=~/^\s*(\S+)(\.lib)$/io) {
       
  1198 			        if ($1!~/$RVCTVersion/i) {
       
  1199 				        $Trg=$1.$RVCTVersion.".lib";
       
  1200 				}
       
  1201 			}
       
  1202 			if ($BaseTrg!~/$RVCTVersion/i) {
       
  1203 			        $BaseTrg .= $RVCTVersion;
       
  1204 			}
       
  1205 		}
       
  1206 	}
       
  1207 
       
  1208 	my $TrgPath=&main::TrgPath;
       
  1209 	my $TrgType=&main::TrgType;
       
  1210 	my $epocroot=&main::Path_Drive . &main::EPOCPath;
       
  1211 	$epocroot =~ s/EPOC32\\$//i;
       
  1212 	my $UIDFile;
       
  1213 
       
  1214 	$ExtraFilesPath = &main::MakeFilePath;
       
  1215 
       
  1216 	if ($Bld =~ /DEB/) {
       
  1217 		@LibList=&main::DebugLibList;
       
  1218 	} else {
       
  1219 		@LibList=&main::LibList;
       
  1220 	}
       
  1221 	my $xmlTarget;
       
  1222 	if ($ABI =~ /BPABI/)
       
  1223 	{
       
  1224 		$ABI = "GCCE";
       
  1225 	}
       
  1226 	
       
  1227 	if ($Plat eq "GCCE" || $CustGCCE || $ABIV2) {
       
  1228 	
       
  1229 		if ($CW_major_version < 3.1) {
       
  1230 			die "FATAL ERROR: Target $Plat requires CodeWarrior for Symbian release 3.1 at minimum.\n";
       
  1231 		}
       
  1232 	}
       
  1233 	
       
  1234 	if ($ABIV2 && ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2))
       
  1235 	{
       
  1236 		die "FATAL ERROR: Target ARMV5_ABIV2 requires RVCT version 2.2 and greater. Detected RVCT $RVCTMajorVersion.$RVCTMinorVersion.\n";
       
  1237 	}
       
  1238 	
       
  1239 	if (($RVCTMajorVersion == 2 && $RVCTMinorVersion >= 2) && $CW_major_version < 3.1 && $ABIV2)
       
  1240 	{
       
  1241 		die "FATAL ERROR: Detected RVCT Version $RVCTMajorVersion.$RVCTMinorVersion and CodeWarrior version $CW_major_version. RVCT 2.2 and greater requies CodeWarrior version 3.1 at minimum.\n";
       
  1242 	}
       
  1243 	
       
  1244     $xmlTarget = findTarget($BaseName, "$Plat $Bld", "$ABI $Bld");
       
  1245 		
       
  1246 	return if (!defined($xmlTarget));
       
  1247 	
       
  1248 	my $targetname = $xmlTarget->getAttribute("NAME");
       
  1249 
       
  1250 	my $UnderlyingABI=PMUnderlyingABI($ABI);
       
  1251 	my @ChopRTWSysIncPaths=&main::Path_Chop(&main::Path_RltToWork(&main::SysIncPaths));
       
  1252 	my @ChopRTWUserIncPaths=&main::Path_Chop(&main::Path_RltToWork(&main::UserIncPaths));
       
  1253 	my $EPOCPath=&main::EPOCPath;
       
  1254 	my $LinkAs=&main::LinkAs;
       
  1255 	my $LibPath=&main::LibPath;
       
  1256 	my @UidList=&main::UidList;	
       
  1257 	my $WarningLevelGCC=&main::CompilerOption("GCC");
       
  1258 	my $ExportLibrary=&main::ExportLibrary;
       
  1259 	my $NoExportLibrary=&main::NoExportLibrary;
       
  1260 	my $SystemTrg = SystemTarget();
       
  1261 	my %Version = &main::Version();
       
  1262 	my $ExtraExportLibrary;
       
  1263 	my $PrimaryExportLibrary = $ExportLibrary;
       
  1264 	unless ($Version{explicit}) {
       
  1265 		$ExtraExportLibrary = $ExportLibrary;
       
  1266 		$ExtraExportLibrary =~ s/\{(\d|a|b|c|d|e|f){8}\}//i;
       
  1267 		$PrimaryExportLibrary = $ExtraExportLibrary;
       
  1268 	}
       
  1269 
       
  1270 	my $ChopBldPath=&main::Path_Chop(&main::BldPath);
       
  1271 	my $EPOCIncPath=&main::EPOCIncPath;
       
  1272 	my $ChopRelPath=&main::Path_Chop(&main::RelPath);
       
  1273 	my $RelPath=&main::RelPath;
       
  1274 	my $StatLinkPath=&main::StatLinkPath;
       
  1275 	my $ParentPlat;
       
  1276 	
       
  1277 # 	Check if a platform is customization, if yes find the parent platform.
       
  1278 	my $IsPlatCustomization=IsCustomization($Plat);
       
  1279 	if ($IsPlatCustomization) {
       
  1280 		$ParentPlat = Plat_Customizes($Plat);
       
  1281 	}
       
  1282 	
       
  1283 	my @RTLibList;
       
  1284 	if ($ABIV1) {
       
  1285 	    @RTLibList = ('dfpaeabi.lib', "dfprvct${RVCTVersion}.lib", 'drtaeabi.lib', 'drtaeabi.lib(VtblExports.o)');
       
  1286 	    if ($RVCTMajorVersion == 2 && $RVCTMinorVersion >= 2) {
       
  1287 		# The scppnwdl.lib should come before drtrvct2_2.lib
       
  1288 		push @RTLibList, "scppnwdl.lib";
       
  1289 		push @RTLibList, "drtrvct${RVCTVersion}.lib";
       
  1290 	    }
       
  1291 	    else
       
  1292 	    {
       
  1293 		push @RTLibList, "dfprvct${RVCTVersion}-thunk.lib";
       
  1294 		push @RTLibList, "drtrvct${RVCTVersion}.lib";
       
  1295 	    }    
       
  1296 	}
       
  1297 	elsif ($ABIV2)
       
  1298 	{
       
  1299 		@RTLibList = ('drtaeabi.dso', 'dfpaeabi.dso', "dfprvct${RVCTVersion}.dso");
       
  1300 	    if ($RVCTMajorVersion == 2 && $RVCTMinorVersion >= 2) {
       
  1301 		# The scppnwdl.lib should come before drtrvct2_2.lib
       
  1302 		push @RTLibList, "scppnwdl.dso";
       
  1303 		push @RTLibList, "drtrvct${RVCTVersion}.dso";
       
  1304 	    }
       
  1305 	}
       
  1306 	
       
  1307 	my @compatibleDOCUMENTExtensions = ("cfg", "h", "hrh", "iby", "inf", "ini", "loc", "mmpi", "policy", "ra", "rh", "rls", "rss", "script", "txt");
       
  1308 	my @DocList = &main::DocList;
       
  1309 	@addedFiles=();
       
  1310 
       
  1311 
       
  1312 #	set up LinkAs
       
  1313 	$UidList[2]=~/^0x(.*)$/o;
       
  1314 	if ($1 ne '00000000') { # have to make sure than series of noughts in brackets doesn't appear in name for null uids
       
  1315 		$LinkAs=join '', &main::Path_Split('Base',$LinkAs),"[$1]",&main::Path_Split('Ext',$LinkAs);
       
  1316 	}
       
  1317 
       
  1318 #	set up dlltool flag hash
       
  1319 	my %ABIDlltool=(
       
  1320 		ARMI=>'-m arm_interwork',
       
  1321 		ARM4=>'-m arm',
       
  1322 		THUMB=>'-m thumb'
       
  1323 	);
       
  1324 
       
  1325 #	work out the flags for various platforms
       
  1326 	if ($ABI eq 'ARMI') {
       
  1327 		$PlatOpt{Gcc}='-march=armv4t -mthumb-interwork';
       
  1328 		$PlatOpt{Dlltool}=$ABIDlltool{ARMI};
       
  1329 	}
       
  1330 	elsif ($ABI eq 'ARM4T') {
       
  1331 		if (&main::BuildAsARM) {
       
  1332 			$PlatOpt{Gcc}='-march=armv4t -mthumb-interwork';
       
  1333 			$PlatOpt{Dlltool}=$ABIDlltool{ARMI};
       
  1334 		}
       
  1335 		elsif ($SystemTrg) {
       
  1336 			$PlatOpt{Gcc}='-march=armv4';
       
  1337 #			allow thumb for ARM4 ABI where necessary
       
  1338 			unless (&main::PlatABI eq 'ARM4') {
       
  1339 				$PlatOpt{Gcc}.='t';
       
  1340 			}
       
  1341 			$PlatOpt{Dlltool}=$ABIDlltool{ARM4};
       
  1342 		}
       
  1343 		else {
       
  1344 			$PlatOpt{Gcc}='-mthumb-interwork -D__MARM_THUMB__';
       
  1345 			$PlatOpt{Dlltool}=$ABIDlltool{THUMB};
       
  1346 		}
       
  1347 	}
       
  1348 	elsif ($ABI eq 'ARM4') {
       
  1349 		$PlatOpt{Gcc}='-march=armv4';
       
  1350 #		allow thumb for ARM4 ABI where necessary
       
  1351 		unless (&main::PlatABI eq 'ARM4') {
       
  1352 			$PlatOpt{Gcc}.='t';
       
  1353 		}
       
  1354 		$PlatOpt{Dlltool}=$ABIDlltool{ARM4};
       
  1355 	}
       
  1356 	elsif ($ABI eq 'THUMB') {
       
  1357 		$PlatOpt{Gcc}='-mthumb-interwork';
       
  1358 		$PlatOpt{Dlltool}=$ABIDlltool{THUMB};
       
  1359 	}
       
  1360 	
       
  1361 	elsif ($Plat ne 'WINSCW' && $Plat ne 'ARMV5' && !$IsPlatCustomization && $Plat ne 'GCCE' && $Plat ne 'ARMV5_ABIV2' && $Plat ne 'ARMV5_ABIV1') { 
       
  1362 		&main::FatalError("Platform module - ABI \"$ABI\" unrecognised");
       
  1363 	}
       
  1364 	
       
  1365 	if ($Plat ne 'WINSCW') {
       
  1366 		@CompatibleABIs=@{$CompatibleABIs{$UnderlyingABI}};
       
  1367 	}
       
  1368 
       
  1369 #	set up CompatibleABI lib path hash
       
  1370 	foreach (@CompatibleABIs) {
       
  1371 		$ABILibPath{$_}=&main::Path_Strip("$LibPath..\\..\\$_\\");
       
  1372 	}
       
  1373 
       
  1374 	$Dlltool=$ToolPrefix.'dlltool.exe';
       
  1375 	$Archive=$ToolPrefix.'ar.exe';
       
  1376 	$Link=$ToolPrefix.'ld.exe';
       
  1377 	$Objcopy=$ToolPrefix.'objcopy.exe';
       
  1378 
       
  1379 	my $WarningLevelCW=&main::CompilerOption("CW");
       
  1380 
       
  1381 	$xmlFileList = newList($xmlTarget,"FILELIST",1);
       
  1382 	$xmlFileList->addText("\n");
       
  1383 
       
  1384 	$xmlLinkOrder = newList($xmlTarget,"LINKORDER",1);
       
  1385 	$xmlLinkOrder->addText("\n");
       
  1386 
       
  1387 	# Create temporary sublists, which will be
       
  1388 	# removed during finaliseProject
       
  1389 
       
  1390 	$xmlSourceGroup = newList($xmlTarget,"SOURCEGROUP",0);
       
  1391 	$xmlSourceGroup->setAttribute("TARGET", $targetname);
       
  1392 	$xmlSourceGroup->addText("\n");
       
  1393 
       
  1394 	$xmlHeadersGroup = newList($xmlTarget,"HEADERSGROUP",0);
       
  1395 	$xmlHeadersGroup->setAttribute("TARGET", $targetname);
       
  1396 	$xmlHeadersGroup->addText("\n");
       
  1397 
       
  1398 	$xmlRootGroup = newList($xmlTarget,"ROOTGROUP",0);
       
  1399 	$xmlRootGroup->setAttribute("TARGET", $targetname);
       
  1400 	$xmlRootGroup->addText("\n");
       
  1401 		
       
  1402 	$xmlLinkGroup = newList($xmlTarget,"LINKGROUP",0);
       
  1403 	$xmlLinkGroup->setAttribute("TARGET", $targetname);
       
  1404 	$xmlLinkGroup->addText("\n");
       
  1405 
       
  1406 	$xmlLibGroup = newList($xmlTarget,"LIBGROUP",0);
       
  1407 	$xmlLibGroup->setAttribute("TARGET", $targetname);
       
  1408 	$xmlLibGroup->setAttribute("PLAT", $Plat);
       
  1409 	$xmlLibGroup->addText("\n");
       
  1410 
       
  1411 	$xmlResourcesGroup = newList($xmlTarget,"RESOURCESGROUP",0);
       
  1412 	$xmlResourcesGroup->setAttribute("TARGET", $targetname);
       
  1413 	$xmlResourcesGroup->addText("\n");
       
  1414 
       
  1415 	$xmlDocumentsGroup = newList($xmlTarget,"DOCUMENTSGROUP",0);
       
  1416 	$xmlDocumentsGroup->setAttribute("TARGET", $targetname);
       
  1417 	$xmlDocumentsGroup->addText("\n");
       
  1418 
       
  1419 	my $debug="";
       
  1420 	$debug="Debug" if ($Bld =~ /DEB$/);
       
  1421 
       
  1422 	my @RuntimeLibs = ();	# add platform-specific runtime libraries here
       
  1423 	if (&main::PlatCompiler eq "GCC32")
       
  1424 		{
       
  1425 		if ($BasicTrgType=~/^DLL$/o) 
       
  1426 			{ # Add the DLL stub library
       
  1427 			push @RuntimeLibs, "EDLLSTUB.LIB";
       
  1428 			}
       
  1429 		if ($BasicTrgType=~/^(DLL|EXE)/o) 
       
  1430 			{ # Add the GCC helper fns
       
  1431 			push @RuntimeLibs, "EGCC.LIB";
       
  1432 			}
       
  1433 		}
       
  1434 	
       
  1435 	if ($Plat eq "GCCE" || $CustGCCE)
       
  1436 		{
       
  1437 			push @RuntimeLibs, "usrt2_2.lib";    # UDEB/UREL Specific
       
  1438 			push @RuntimeLibs, "dfpaeabi.dso";
       
  1439 			push @RuntimeLibs, "dfprvct2_2.dso";
       
  1440 			push @RuntimeLibs, "drtaeabi.dso"; 
       
  1441 			push @RuntimeLibs, "scppnwdl.dso"; 
       
  1442 			push @RuntimeLibs, "drtrvct2_2.dso";
       
  1443 			if ($BasicTrgType=~/^DLL$/o) { # Add the DLL stub library
       
  1444 				push @RuntimeLibs, "EDLLSTUB.LIB";   # UDEB/UREL Specific
       
  1445 				}
       
  1446 		}
       
  1447 
       
  1448 	addFile(&main::Path_Split('File',$MmpFile), "Text", "", "", "Root");
       
  1449 
       
  1450 	# Create the uid.cpp file	
       
  1451 	if ($Plat eq "WINSCW" && $BasicTrgType=~/^(EXE|DLL)$/oi)
       
  1452 		{
       
  1453 		my @UidList=&main::UidList;
       
  1454 		
       
  1455 		# create the UID source file
       
  1456 		my $priority = "EPriorityForeground";
       
  1457 		if (&main::ProcessPriority) {
       
  1458 			$priority="EPriority".&main::ProcessPriority;
       
  1459 		}
       
  1460 
       
  1461 		my $UidText=join(
       
  1462 			"\n",
       
  1463 			'// Makmake-generated uid source file',
       
  1464 			'#include <e32cmn.h>',
       
  1465 			'#pragma data_seg(".SYMBIAN")',
       
  1466 			'__EMULATOR_IMAGE_HEADER2('
       
  1467 		);
       
  1468 		foreach (@UidList) {
       
  1469 			$UidText.="$_,";
       
  1470 		}
       
  1471 		my $vstr = "0x".&Genutl_VersionToHexString(&main::Version);
       
  1472 		my $vid = &main::VendorId;
       
  1473 		if(!$vid) { $vid="0"; }
       
  1474 		$UidText.="$priority,".(&main::CapabilityFlags)[0]."u,".(&main::CapabilityFlags)[1]."u,".&main::SecureId.",".$vid.",$vstr,";	# second capability word always 0 for now
       
  1475 		if (&main::AllowDllData) {
       
  1476 			$UidText.="1,";
       
  1477 		} else {
       
  1478 			$UidText.="0,";
       
  1479 		}
       
  1480 		chop $UidText;
       
  1481 		$UidText.=")\n";
       
  1482 		$UidText.="#pragma data_seg()\n";
       
  1483 
       
  1484 		$UIDFile = $BaseTrg.'_UID_.cpp';
       
  1485 		&main::CreateExtraFile("${ExtraFilesPath}$UIDFile", $UidText);
       
  1486 		}
       
  1487 
       
  1488 
       
  1489 	if (-e $DefFile)
       
  1490 		{
       
  1491 		addFile(&main::Path_Split('File',$DefFile), "Text", "", &main::DefFileType."\\");
       
  1492 		}
       
  1493 
       
  1494 	# Add resources: rsc files, mbm files and aif files
       
  1495 
       
  1496 	my $mmpdir = &main::Path_Split('Path',$MmpFile);
       
  1497 	$changedsettings{"SymbianResourcesMMPFileLocation"} = "{0}$mmpdir";
       
  1498 	my $ResourcesText="";
       
  1499 	my @ResourceDownloadList=();
       
  1500 	
       
  1501 	# --- MBM files
       
  1502 	
       
  1503 	my $BitMapStructRef = &main::BitMapStructRef();
       
  1504 	my $BitMapRef;
       
  1505 	
       
  1506 	foreach my $BitMapRef (@$BitMapStructRef) {
       
  1507 		my $trgfile = $$BitMapRef{Trg};
       
  1508 # change - only use colour resource files
       
  1509 		next if ($trgfile =~ /\.MBW$/i);	# ignore greyscale MBM files
       
  1510 		$trgfile =~ s/\.MCL$/.MBM/;			# convert MCL to MBM for immediate use
       
  1511 		my $entry = "  <mbm targetfile = \"$trgfile\"";
       
  1512 		$entry .= " targetpath = \"".&main::Path_Chop($$BitMapRef{TrgPath})."\"";
       
  1513 		push @ResourceDownloadList, $$BitMapRef{TrgPath}.$trgfile;
       
  1514 		if (defined $$BitMapRef{Hdr})
       
  1515 			{
       
  1516 			$entry .= " header = \"true\"";
       
  1517 			}
       
  1518 		else
       
  1519 			{
       
  1520 			$entry .= " header = \"false\"";
       
  1521 			}
       
  1522 		$entry .= ">\n";
       
  1523 		foreach my $SrcRef (@{$$BitMapRef{Source}}) {
       
  1524 			$entry .= "    <bmp bpp = \"$$SrcRef{ClDepth}\"";
       
  1525 			my $bmpfile = &main::Path_Split('File',$$SrcRef{Src});
       
  1526 			my $bmppath = &main::Path_Split('Path',$$SrcRef{Src});
       
  1527 			my $sourcepath = &main::Path_Chop(&main::Path_MakeRltToBase($mmpdir,$bmppath));
       
  1528 			$entry .= " sourcepath = \"$sourcepath\"";
       
  1529 			$entry .= " sourcefile = \"$bmpfile\"/>\n";
       
  1530 		}
       
  1531 		$ResourcesText .= $entry . "  </mbm>\n";
       
  1532 	}
       
  1533 	
       
  1534 	# --- AIF files
       
  1535 
       
  1536 	my $AifStructRef = &main::AifStructRef();
       
  1537 	my $AifRef;
       
  1538 
       
  1539 	foreach $AifRef (@$AifStructRef) {
       
  1540 # regression change - workaround lack of AIF directory
       
  1541 		my $trgpath=&main::TrgPath;
       
  1542 		my $trgfile=&main::Path_Split('File',$$AifRef{Trg});
       
  1543 		my $path=&main::Path_Split('Path',"$trgpath$$AifRef{Trg}");
       
  1544 		$path=&main::Path_Chop($path);  
       
  1545 # change - only use colour resource files
       
  1546 		next if ($trgfile =~ /\.ABW$/i);	# ignore greyscale AIF files
       
  1547 		$trgfile =~ s/\.ACL$/.AIF/;			# convert ACL to AIF for immediate use
       
  1548  		my $rssfile = &main::Path_Split('File',$$AifRef{Source});
       
  1549  		my $rsspath = &main::Path_Split('Path',$$AifRef{Source});
       
  1550  		my $sourcepath=&main::Path_Chop(&main::Path_MakeRltToBase($mmpdir,$rsspath));
       
  1551  		my $entry = "  <aif sourcefile = \"$rssfile\"";
       
  1552    		$entry .= " sourcepath = \"$sourcepath\"";
       
  1553    		$entry .= " targetfile = \"$trgfile\" targetpath = \"$path\">\n";
       
  1554    		push @ResourceDownloadList, "$path\\$trgfile";
       
  1555  		foreach my $BitmapRef (@{$$AifRef{BitMaps}}) {
       
  1556  			$entry .= "    <bmp bpp = \"$$BitmapRef{ClDepth}\"";
       
  1557  			my $bmpfile = &main::Path_Split('File',$$BitmapRef{Src});
       
  1558  			my $bmppath = &main::Path_Split('Path',$$BitmapRef{Src});
       
  1559  			$sourcepath = &main::Path_Chop(&main::Path_MakeRltToBase($mmpdir,$bmppath));
       
  1560  			$entry .= " sourcepath = \"$sourcepath\"";
       
  1561  			$entry .= " sourcefile = \"$bmpfile\"/>\n";
       
  1562 		}
       
  1563    		$ResourcesText .= $entry . "  </aif>\n";
       
  1564 
       
  1565    	}
       
  1566 
       
  1567 	
       
  1568 	# --- RSC files, which must come after .MBM files since they may use the .MBG header files
       
  1569 	
       
  1570 	my $ResourceStructRef=&main::ResourceStructRef;
       
  1571 	my @resourcefiles;
       
  1572 	my %resourcetargets;
       
  1573 
       
  1574 	# NOTE: An <rsc/> block is now created for each START RESOURCE blocks LANG entries.  This
       
  1575 	# shouldn't be necessary as <rsc/> blocks support multiple <language/> tags, and the generation
       
  1576 	# of separate localised binaries should be dealt with by the Symbian Resources IDE plugin.
       
  1577 	# However, a defect in the plugin's processing of <rsc/> "targetfile" attributes means that is
       
  1578 	# doesn't correctly generate separate localised binaries with per-LANG extensions.
       
  1579 
       
  1580 	my %headerProcessed;
       
  1581 
       
  1582 	foreach my $ResourceRef (@$ResourceStructRef) {
       
  1583 		my $fullsource=$$ResourceRef{Source};
       
  1584 		my $rssfile=&main::Path_Split('File', $fullsource);
       
  1585 		my $rsspath=&main::Path_Split('Path', $fullsource);
       
  1586 		my $entry = "  <rsc sourcefile = \"$rssfile\"";
       
  1587 		$entry .= " targetpath = \"".&main::Path_Chop($$ResourceRef{TrgPath})."\"";
       
  1588 		
       
  1589 		#############################################################
       
  1590 		# if CW version is 3.1 or greater, add TARGET file if present
       
  1591 		# tkelly 4-May-05
       
  1592 		if ($CW_major_version >= 3.1)
       
  1593 		{
       
  1594 			my $trgfile=&main::Path_Split('File',$$ResourceRef{Trg}); 
       
  1595 			$entry .= " targetfile = \"$trgfile\"\n"; #tk
       
  1596 		}
       
  1597 		##############################################################
       
  1598 		if ((defined $$ResourceRef{Hdr}) && (!$headerProcessed{$fullsource}))
       
  1599 			{
       
  1600 			$entry .= " header = \"true\"";
       
  1601 			$headerProcessed{$fullsource} = 1;
       
  1602 			}
       
  1603 		else
       
  1604 			{
       
  1605 			$entry .= " header = \"false\"";
       
  1606 			}
       
  1607 		my $sourcepath=&main::Path_Chop(&main::Path_MakeRltToBase($mmpdir,$rsspath));
       
  1608 		$entry .= " sourcepath = \"$sourcepath\">\n";
       
  1609 		# ignore the UidList for now..
       
  1610 		$resourcetargets{$fullsource} = $$ResourceRef{TrgPath}.&main::Path_Split('Base', $rssfile);
       
  1611 
       
  1612 		$entry .= "    <language id = \"$$ResourceRef{Lang}\"/>\n";
       
  1613 		push @resourcefiles, $entry;
       
  1614 		push @ResourceDownloadList, $resourcetargets{$fullsource}.".R".$$ResourceRef{Lang};
       
  1615 	}
       
  1616 
       
  1617  	foreach my $resourceEntry (@resourcefiles) {	
       
  1618  			$ResourcesText .= $resourceEntry . "  </rsc>\n";
       
  1619  			}
       
  1620 
       
  1621 	# --- If required, generate .resources file per platform
       
  1622 	
       
  1623 	if ($ResourcesText ne "")
       
  1624 		{
       
  1625 		my $resourcesfile = "$BaseTrg$Plat.resources";
       
  1626 		&main::CreateExtraFile("${ExtraFilesPath}$resourcesfile", "<resources>\n$ResourcesText</resources>\n");
       
  1627 		addFile($resourcesfile, "Text", "", "", "Resources");
       
  1628 		}
       
  1629 		
       
  1630 	# Build the rest of the file list
       
  1631 
       
  1632 	if ($BasicTrgType!~/^LIB$/o)
       
  1633 		{
       
  1634 		addFile($FirstLib, "Library", $debug, "$Bld\\");	# static library, build-specific
       
  1635 		}
       
  1636 	
       
  1637 	my $file;
       
  1638 	foreach $file (@SrcList)
       
  1639 		{
       
  1640 		# ensure the case of the extension is what GCC expects
       
  1641 		$file =~ s/\.CPP$/.cpp/i;
       
  1642 		$file =~ s/\.C$/.c/i;
       
  1643 		$file =~ s/\.s$/.S/i;
       
  1644 		my $srcfile=&main::Path_Split('File',$file);
       
  1645 		addFile($srcfile, "Text", $debug, "");
       
  1646 		}
       
  1647 
       
  1648 	# If required, add the uid.cpp file so that it appears after all other source files in the link order
       
  1649 	if (defined $UIDFile)
       
  1650 		{
       
  1651 		addFile($UIDFile, "Text", "", "");
       
  1652 		}
       
  1653 	
       
  1654 	if ($Plat ne "GCCE" && !$CustGCCE)
       
  1655 	{
       
  1656 	# linking with GCCE, Runtime libs need to be at the end to match with make, otherwise evalid can fail.
       
  1657 	foreach $file (@RuntimeLibs)
       
  1658 		{
       
  1659 		next if ( $file eq $FirstLib );		#skip if file equals FirstLib.
       
  1660 		addFile($file, "Library", $debug, "$Bld\\"); # static library, build specific
       
  1661 		}
       
  1662 	}
       
  1663 				
       
  1664 	foreach $file (@StatLibList)
       
  1665 		{
       
  1666 		next if ( $file eq $FirstLib );		#skip if file equals FirstLib.
       
  1667 		addFile($file, "Library", $debug, "$Bld\\"); # static library, build specific
       
  1668 		}
       
  1669 	foreach $file (@ASSPLibList, @LibList)
       
  1670 		{
       
  1671 		next if ( $file eq $FirstLib );		#skip if file equals FirstLib.
       
  1672 		if ($Plat eq "GCCE" or $ABIV2 or $CustGCCE) {
       
  1673 			$file =~ s/\.LIB$/.DSO/;
       
  1674 			$file =~ s/\.lib$/.dso/;
       
  1675 			}
       
  1676 		addFile($file, "Library", $debug, "");
       
  1677 		}
       
  1678 		
       
  1679 	if ($Plat eq "GCCE" || $CustGCCE)
       
  1680 	{
       
  1681 		foreach $file (@RuntimeLibs)
       
  1682 		{
       
  1683 			next if ( $file eq $FirstLib );		#skip if file equals FirstLib.
       
  1684 			
       
  1685 			#change to prevent multiple libs being listed when they are shared between targets.
       
  1686 			if ($file eq "usrt2_2.lib" || $file eq "EDLLSTUB.LIB") {
       
  1687 				addFile($file, "Library", $debug, "$Bld\\"); # static library, build specific
       
  1688 			}
       
  1689 			else {
       
  1690 				addFile($file, "Library", $debug, ""); # static library, build non-specific
       
  1691 			}
       
  1692 		}
       
  1693 	}
       
  1694 		
       
  1695 	if ($Plat eq "WINSCW")
       
  1696 		{
       
  1697 		my $defaults = $ENV{'MWSym2LibraryFiles'};
       
  1698 		# look out for paths?
       
  1699 		foreach $file (@Win32LibList)
       
  1700 			{
       
  1701 			# skip default libs and FirstLib
       
  1702 			next if ( ($defaults =~ /;$file/) || ($file eq $FirstLib) );
       
  1703 			addFile($file, "Library", $debug, "");
       
  1704 			}
       
  1705 		}
       
  1706 
       
  1707 	
       
  1708 	# Update the project settings
       
  1709 
       
  1710 	$changedsettings{"UserSourceTrees"} = "{}";
       
  1711 	$changedsettings{"UserSearchPaths"} = "{}";
       
  1712 	$changedsettings{"SystemSearchPaths"} = "{}";
       
  1713 	$changedsettings{"Targetname"} = $targetname;
       
  1714 
       
  1715 	my $outputdir = $RelPath;
       
  1716 	if ($Plat eq "WINSCW")
       
  1717 		{
       
  1718 		my $trgpath = &main::TrgPath;
       
  1719 		&Winutl_AdjustTargetPath(\$trgpath);
       
  1720 		$outputdir .= $trgpath;
       
  1721 		}
       
  1722 	$changedsettings{"OutputDirectory"} = "{1}".&main::Path_Chop($outputdir);
       
  1723 	$changedsettings{"SymbianInstallationContentSearchLocation"} = "{0}".&main::Path_Chop($RelPath);
       
  1724 
       
  1725 	$changedsettings{"SymbianResourcesHeaderFileOutputLocation"} = "{0}".&main::Path_Chop(&main::EPOCIncPath());
       
  1726 	if ($Plat eq "WINSCW")
       
  1727 		{
       
  1728 		$changedsettings{"SymbianResourcesBinaryOutputLocation"} = "{0}".&main::Path_Chop($RelPath);
       
  1729 		}
       
  1730 	else
       
  1731 		{
       
  1732 		$changedsettings{"SymbianResourcesBinaryOutputLocation"} = "{0}".&main::Path_Chop(&main::EPOCDataPath());
       
  1733 		}
       
  1734 		
       
  1735 	if ($Plat eq "WINSCW")
       
  1736 		{
       
  1737 		if ($TrgType eq "EXE")
       
  1738 			{	
       
  1739 			# IDE would do the right thing, but we might as well make sure...
       
  1740 			$changedsettings{"MWRuntimeSettings_HostApplication"} = "{0}$outputdir$Trg";
       
  1741 			}
       
  1742 		else
       
  1743 			{
       
  1744 			$changedsettings{"MWRuntimeSettings_HostApplication"} = "{0}${RelPath}epoc.exe";
       
  1745 			}
       
  1746 		}
       
  1747 
       
  1748 
       
  1749 	$changedsettings{"SymbianEpocToolsPath"} = "{0}${epocroot}";
       
  1750 
       
  1751 	if ($Plat ne "WINSCW")
       
  1752 		{
       
  1753 		my $downloadpath = &main::TrgPath;
       
  1754 		if (&main::EPOCSecurePlatform && $downloadpath !~ /^Z\\sys\\bin\\/)
       
  1755 			{
       
  1756 			my @hrhMacros = &Variant_GetMacroList;
       
  1757 			if (grep /^SYMBIAN_IGNORE_BIN_TARGETPATH\s*$/, @hrhMacros)
       
  1758 				{
       
  1759 				$downloadpath = "Z\\sys\\bin\\";
       
  1760 				}
       
  1761 			}
       
  1762 		$downloadpath =~ s/^Z\\/C:\\/i;
       
  1763 		$changedsettings{"DownloadPath"} = $downloadpath;
       
  1764 		$changedsettings{"FileList"} = "{}";
       
  1765 		}
       
  1766 
       
  1767 	my @MacroList;
       
  1768 
       
  1769 	@MacroList = &main::MacroList();			
       
  1770 		
       
  1771 	push @MacroList, "__${Plat}__" if ($Plat ne $ABI);
       
  1772 	push @MacroList, "__SUPPORT_CPP_EXCEPTIONS__" if ($Plat eq "WINSCW");
       
  1773 	push @MacroList, "__SUPPORT_CPP_EXCEPTIONS__" if (($Plat eq "ARMV5") || ($Plat eq "ARMV5_ABIV2") || ($Plat eq "ARMV5_ABIV1") || ($Plat eq "GCCE") || $IsPlatCustomization);
       
  1774 
       
  1775 	# Symbian Compiler Panel
       
  1776 			
       
  1777 	my $compiler="";
       
  1778 	my $compilerargs="";
       
  1779 	my $macros="";
       
  1780 
       
  1781 	if ((($Plat eq "ARMV5") || ($Plat eq "ARMV5_ABIV2") || ($Plat eq "ARMV5_ABIV1") || ($Plat eq "GCCE") || $IsPlatCustomization) && $VariantFile)
       
  1782 		{
       
  1783 		push @MacroList, '__PRODUCT_INCLUDE__=\\"'.&main::Path_Split('File',$VariantFile).'\\"' if $VariantFile;
       
  1784 		}
       
  1785 
       
  1786 	foreach (@MacroList)
       
  1787 		{
       
  1788 		$_ =~ s/\s+$//;
       
  1789 		$_ =~ s/^\s+//;
       
  1790 		$macros .= "$_,";
       
  1791 		}
       
  1792 
       
  1793 ###############################
       
  1794 # WINSCW compilation settings #
       
  1795 ###############################
       
  1796 
       
  1797 	if ($Plat eq "WINSCW")
       
  1798 		{
       
  1799 		$compiler = "WINSCW";
       
  1800 		$compilerargs .= "-wchar_t off -align 4 -warnings on -w nohidevirtual, nounusedexpr -msgstyle gcc -enum int -str pool ";
       
  1801 		$compilerargs .= "-exc ms ";
       
  1802 		$compilerargs .= "-trigraphs on ";
       
  1803 
       
  1804 		if ($Bld =~ /DEB/)
       
  1805 			{
       
  1806 			$compilerargs .= "-O0 ";
       
  1807 
       
  1808 			# euser change to apply inlining on the _NAKED functions
       
  1809 			if ($BaseTrg !~ /^EUSER$/oi)
       
  1810 				{
       
  1811 				$compilerargs .= "-inline off ";
       
  1812 				}
       
  1813 			}
       
  1814 		else
       
  1815 			{
       
  1816 			$compilerargs .= "-O4,s ";
       
  1817 			}
       
  1818 			
       
  1819 		if ($Win32StdHeaders || $Win32Resrc ) 
       
  1820 			{
       
  1821 			$macros .= "WIN32,_WINDOWS,";
       
  1822 			# Callisto defect workaround
       
  1823 			# NOTE: persisting with this for consistency
       
  1824 			$compilerargs .= "-stdinc ";
       
  1825 			}
       
  1826 		else
       
  1827 			{
       
  1828 			$compilerargs .= "-nostdinc ";
       
  1829 			}
       
  1830 				
       
  1831 		$compilerargs .= &main::CompilerOption("CW");
       
  1832 		$changedsettings{"Macros"} = $macros;
       
  1833 		if ($VariantFile)
       
  1834 			{
       
  1835 			$changedsettings{"PrefixFile"} = &main::Path_Split('File',$VariantFile);
       
  1836 			}			
       
  1837 		}
       
  1838 
       
  1839 #############################
       
  1840 # RVCT compilation settings #
       
  1841 #############################
       
  1842 		
       
  1843 	elsif ((($Plat eq "ARMV5") || ($Plat eq "ARMV5_ABIV2") || ($Plat eq "ARMV5_ABIV1") || $ABIV1 || $ABIV2) && ($CW_major_version >= 3)) #|| $IsPlatCustomization
       
  1844 		{
       
  1845 		
       
  1846 		if ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2) {
       
  1847 			$changedsettings{"CompilerXMLDescriptor"} = "ARM RVCT";
       
  1848 		}
       
  1849 		else {
       
  1850 			if(($CW_major_version == 3))
       
  1851 			{ 
       
  1852 				$changedsettings{"CompilerXMLDescriptor"} = "ARM RVCT";
       
  1853 			}
       
  1854 			else
       
  1855 			{
       
  1856 				# RVCT 2.2
       
  1857 				$changedsettings{"CompilerXMLDescriptor"} = "ARM RVCT2_2";
       
  1858 			}
       
  1859 		}	
       
  1860 		if ($Bld =~ /REL$/)
       
  1861 			{
       
  1862 				$compilerargs .= $configdata{"REL_OPTIMISATION"}." ".$configdata{"RUNTIME_SYMBOL_VISIBILITY_OPTION"}.$CCUREL;		
       
  1863 			}
       
  1864 		else
       
  1865 			{
       
  1866 			unless (&main::SrcDbg)
       
  1867 				{
       
  1868 					$compilerargs .= $configdata{"DEBUG_OPTIMISATION"}." ".$configdata{"RUNTIME_SYMBOL_VISIBILITY_OPTION"}.$CCUDEB;		
       
  1869 				}
       
  1870 			}
       
  1871 		$changedsettings{"PrefixFile"} = &main::Path_Split('File',$PrefixFile);
       
  1872 		}
       
  1873 
       
  1874 ############################
       
  1875 # GCC compilation settings #
       
  1876 ############################
       
  1877 		
       
  1878 	elsif ($Plat eq "ARM4")
       
  1879 		{
       
  1880 		$compiler = "ARM";
       
  1881 			
       
  1882 		if ($Bld =~ /REL$/)
       
  1883 			{
       
  1884 			$compilerargs .= "-s -fomit-frame-pointer -O "
       
  1885 			}
       
  1886 		else
       
  1887 			{
       
  1888 			unless (&main::SrcDbg)
       
  1889 				{
       
  1890 				$compilerargs .= "-O ";
       
  1891 				}
       
  1892 			}
       
  1893 		
       
  1894 		if ($ABI eq "ARMI")
       
  1895 			{
       
  1896 			$compilerargs .= "-march=armv4t -mthumb-interwork";
       
  1897 			}
       
  1898 		elsif ($ABI eq "ARM4T")
       
  1899 			{
       
  1900 			if (&main::BuildAsARM)
       
  1901 				{
       
  1902 				$compilerargs .= "-march=armv4t -mthumb-interwork";
       
  1903 				}
       
  1904 			elsif ($SystemTrg)
       
  1905 				{
       
  1906 				$compilerargs .= "-march=armv4";
       
  1907 
       
  1908 				unless (&main::PlatABI eq "ARM4")
       
  1909 					{
       
  1910 					$compilerargs .= "t";
       
  1911 					}
       
  1912 				}
       
  1913 			else
       
  1914 				{
       
  1915 				$compiler = "THUMB";
       
  1916 				$compilerargs .= "-mthumb-interwork";
       
  1917 				$macros .= "__MARM_THUMB__,";
       
  1918 				}
       
  1919 			}
       
  1920 		elsif ($ABI eq "ARM4")
       
  1921 			{
       
  1922 			$compilerargs .= "-march=armv4";
       
  1923 
       
  1924 			unless (&main::PlatABI eq "ARM4")
       
  1925 				{
       
  1926 				$compilerargs .= "t";
       
  1927 				}
       
  1928 			}
       
  1929 		elsif ($ABI eq "THUMB")
       
  1930 			{
       
  1931 			$compiler = "THUMB";
       
  1932 			$compilerargs .= "-mthumb-interwork";
       
  1933 			}
       
  1934 	
       
  1935 		if ($VariantFile)
       
  1936 			{
       
  1937 			$changedsettings{"PrefixFile"} = &main::Path_Split('File',$VariantFile);
       
  1938 			}
       
  1939 		}
       
  1940 
       
  1941 ############################
       
  1942 # GCCE BPABI compilation settings #
       
  1943 ############################
       
  1944 
       
  1945 		
       
  1946 	elsif ((($Plat eq "GCCE") || $CustGCCE)) # || $IsPlatCustomization) && ($CW_major_version >= 3)) 
       
  1947 		{
       
  1948 		$compiler = "ARM GCCE";
       
  1949 		#Change setting CompilerXMLDescriptor is only good for CW 3.0 and greater.
       
  1950 		$changedsettings{"CompilerXMLDescriptor"} = "ARM GCCE";	
       
  1951 		
       
  1952 		if ($Bld =~ /REL$/)
       
  1953 		{
       
  1954 			$compilerargs .= $configdata{"REL_OPTIMISATION"}." ".$configdata{"RUNTIME_SYMBOL_VISIBILITY_OPTION"}.$CCUREL;
       
  1955 		}
       
  1956 		else
       
  1957 		{
       
  1958 			unless (&main::SrcDbg)
       
  1959 			{
       
  1960 				$compilerargs .= $configdata{"DEBUG_OPTIMISATION"}." ".$configdata{"RUNTIME_SYMBOL_VISIBILITY_OPTION"}.$CCUDEB
       
  1961 			}
       
  1962 		}
       
  1963 		$changedsettings{"PrefixFile"} = &main::Path_Split('File',$PrefixFile);
       
  1964 		}
       
  1965 ####################
       
  1966 # General settings #
       
  1967 ####################
       
  1968 
       
  1969 	$macros =~ s/,$//;
       
  1970 	$compilerargs =~ s/ $//;
       
  1971 
       
  1972 	$changedsettings{"Compiler"} = $compiler; # in CW 3.0, "Compiler" no longer exists. This line has no effect on those versions
       
  1973 	$changedsettings{"Arguments"} = $compilerargs;
       
  1974 
       
  1975 	# Symbian Linker Panel
       
  1976 	$changedsettings{"LinkOutputFile"} = $Trg;
       
  1977 	
       
  1978 	if ($Plat eq "GCCE" || $CustGCCE || $ABIV2) {
       
  1979 		$changedsettings{"SymbianImportLibrary"} = $ExportLibrary.'.dso';
       
  1980 	}
       
  1981 	else {
       
  1982 		$changedsettings{"SymbianImportLibrary"} = $ExportLibrary.'.lib';
       
  1983 	}
       
  1984 	
       
  1985 	# Template defaults for canDebug/canRun are both "true"
       
  1986 	if ($Bld =~ /REL/)
       
  1987 		{
       
  1988 		$changedsettings{"canDebug"} = "false";
       
  1989 		}
       
  1990 
       
  1991 	if ($Plat eq "WINSCW")
       
  1992 		{
       
  1993 		if ($TrgType ne "APP" && $TrgType ne "EXE" && $TrgType ne "EXEDLL" && $TrgType ne "EPOCEXE")
       
  1994 			{
       
  1995 			$changedsettings{"canDebug"} = "false";
       
  1996 			$changedsettings{"canRun"} = "false";
       
  1997 			}
       
  1998 		}
       
  1999 	else
       
  2000 		{
       
  2001 		$changedsettings{"canRun"} = "false";
       
  2002 
       
  2003 		if ($TrgType eq "LIB" || $TrgType eq "KLIB")
       
  2004 			{
       
  2005 			$changedsettings{"canDebug"} = "false";
       
  2006 			}
       
  2007 		}
       
  2008 		
       
  2009 		
       
  2010 	$xmlLinkDescriptorDoc = $xmlParser->parsefile ($FindBin::Bin."\\$linkDescriptorTemplate");
       
  2011 	$xmlLinkDescriptorCommandParent = $xmlLinkDescriptorDoc->getElementsByTagName("array",1)->item(0);
       
  2012 
       
  2013 	if ($CW_major_version >= 3)
       
  2014 		{
       
  2015 		$xmlLinkDescriptorSymbolParent = $xmlLinkDescriptorDoc->getElementsByTagName("array",1)->item(1);
       
  2016 		$xmlLinkDescriptorDumpFileParent = $xmlLinkDescriptorDoc->getElementsByTagName("array",1)->item(2);
       
  2017 		}
       
  2018 	
       
  2019 	my $linkDescriptorFile = "$BaseTrg$Plat$Bld.cwlink";
       
  2020 
       
  2021 	my $copyCommand = 'perl.exe -S ecopyfile.pl ';
       
  2022 	my $deleteCommand = 'cmd.exe /C del ';
       
  2023 
       
  2024 	my $tempFilenameRoot = '${var:IMPORT_LIBRARY_NO_EXT}';
       
  2025 
       
  2026 	if ($CW_major_version < 3)
       
  2027 		{
       
  2028 		$tempFilenameRoot = $ExportLibrary;
       
  2029 		}	
       
  2030 
       
  2031 	my $exportUnfrozenWarningMessage = 'Created "${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).'${var:IMPORT_LIBRARY}" '.
       
  2032 										'from "${target.data}\\'.$tempFilenameRoot.'.def" as EXPORTUNFROZEN specified.';
       
  2033 
       
  2034 
       
  2035 
       
  2036 ############################################
       
  2037 # WINSCW library generation and link stage #
       
  2038 ############################################
       
  2039 
       
  2040 	if ($Plat eq "WINSCW")
       
  2041 		{
       
  2042 		# Generate library
       
  2043 		if ($DefFile and !$NoExportLibrary)
       
  2044 			{
       
  2045 			unless (&main::ExportUnfrozen)
       
  2046 				{
       
  2047 					my $LibLinkAs = ($BasicTrgType=~/^IMPLIB$/io) ? $LinkAs : $Trg;
       
  2048 
       
  2049 					$linkCommand = 'perl.exe -S prepdef.pl "${var:DEF_FILE}" "${target.data}\\'.$tempFilenameRoot.'.prep.def"';
       
  2050 					addLinkDescriptorCommand ($linkCommand);
       
  2051 
       
  2052 					$linkCommand = 'mwldsym2.exe "${target.data}\\'.$tempFilenameRoot.'.prep.def" -importlib -o "'.
       
  2053 									'${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).'${var:IMPORT_LIBRARY}" -addcommand "out:'.$LibLinkAs.'" -warnings off';
       
  2054 					addLinkDescriptorCommand ($linkCommand);
       
  2055 				}
       
  2056 			}
       
  2057 
       
  2058 		if ((2.8 == $CW_major_version) && (0 == $CW_minor_version))
       
  2059 			{
       
  2060 			# For OEM2.8, create a file containing all objects required in the link.  This is used in all
       
  2061 			# calls to mwldsym2 in order to avoid exceeding the Windows command line
       
  2062 			# length in projects containing a large amount of source files
       
  2063 			$linkCommand ='cmd.exe /C echo ${var:LINK_OBJS}>"${target.data}\${output.file.root}.lst"';
       
  2064 			addLinkDescriptorCommand ($linkCommand);
       
  2065 			}
       
  2066 			
       
  2067 		my $stage1linkflags = "";
       
  2068 		my $linkflags = "";
       
  2069 		my $commonLinkFlags = '-msgstyle gcc -stdlib';
       
  2070 		my $libPath = "epoc32\\release\\winscw\\".lc $Bld;
       
  2071 		if ($SystemTrg){
       
  2072 			$commonLinkFlags .=" ${libPath}\\scppnwdl_kern.lib";
       
  2073 		}
       
  2074 		else{
       
  2075 			$commonLinkFlags .=" ${libPath}\\scppnwdl.lib";
       
  2076 		}
       
  2077 		if ($BasicTrgType=~/^(EXE|DLL)$/o) {
       
  2078 					$commonLinkFlags .= ' ${var:FIRST_LIB} '
       
  2079 			}
       
  2080 
       
  2081 		foreach my $lib (@Win32LibList)
       
  2082 			{
       
  2083 			my $win32lib = $lib;
       
  2084 			$win32lib = "-l$win32lib" unless ($win32lib =~ /\\/);
       
  2085 			$commonLinkFlags .= " ". lc $win32lib;
       
  2086 			}
       
  2087 
       
  2088 		if ($BasicTrgType =~ /^DLL$/o || $TrgType =~ /^EXEXP$/o)
       
  2089 			{
       
  2090 			if ($BaseAddress ne "")
       
  2091 				{
       
  2092 				$commonLinkFlags .= " -imagebase $BaseAddress";
       
  2093 				}
       
  2094 			
       
  2095 			$commonLinkFlags .= ' -noentry -shared';
       
  2096 			}
       
  2097 		elsif ($BasicTrgType =~ /^EXE$/o)
       
  2098 			{
       
  2099 			$commonLinkFlags .= ' -m "?_E32Bootstrap@@YGXXZ"';
       
  2100 			}
       
  2101 
       
  2102 		$commonLinkFlags .= ' -subsystem windows';
       
  2103 
       
  2104 		if (&main::HeapSize)
       
  2105 			{
       
  2106 			my %HeapSize = &main::HeapSize;
       
  2107 			$commonLinkFlags .= ' -heapreserve='.RoundUp1k($HeapSize{Max}).' -heapcommit='.RoundUp1k($HeapSize{Min}); 
       
  2108 			}
       
  2109 
       
  2110 		if ($BasicTrgType =~ /^(DLL|EXE)$/o)
       
  2111 			{
       
  2112 			if ($Bld =~ /DEB$/o)
       
  2113 				{
       
  2114 				$commonLinkFlags .= ' -g';
       
  2115 				}
       
  2116 			}
       
  2117 			
       
  2118 		my $EntrySymbol='';
       
  2119 		if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o)
       
  2120 			{
       
  2121 			my $Include="";
       
  2122 			if ($BasicTrgType=~/^DLL$/o)
       
  2123 				{
       
  2124 				$Include="-m __E32Dll";
       
  2125 				$EntrySymbol='__E32Dll';
       
  2126 				}
       
  2127 			else
       
  2128 				{
       
  2129 				$Include="-m __E32Startup";
       
  2130 				$EntrySymbol='__E32Startup';
       
  2131 				}
       
  2132 				
       
  2133 			$stage1linkflags = $commonLinkFlags.' ${var:LIBS}'.
       
  2134 				' -o "${target.data}\\${output.file.name}"'. 
       
  2135 				' -export dllexport '.
       
  2136 				$Include.
       
  2137 				' -nocompactimportlib'. 
       
  2138 				' -implib "${target.data}\\${var:IMPORT_LIBRARY}"'.
       
  2139 				' -addcommand "out:${output.file.name}"'.
       
  2140 				' -warnings off';
       
  2141 			}
       
  2142 				
       
  2143 		my $AbsentSubst = "";
       
  2144 		if ($EntrySymbol)
       
  2145 			{
       
  2146 			$AbsentSubst = " -absent $EntrySymbol";
       
  2147 			}
       
  2148 
       
  2149 		$linkflags = $commonLinkFlags.' ${var:LIBS}'.
       
  2150 			' -o "${output}\\${output.file.name}"';
       
  2151 			
       
  2152 		if ($Bld=~/REL$/o && $BasicTrgType!~/^LIB$/o)
       
  2153 			{
       
  2154 			# Generate map file for release build executables
       
  2155 			$linkflags .= ' -map "${output}\\${output.file.name}.map"';
       
  2156 			}
       
  2157 		
       
  2158 		if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o)
       
  2159 			{
       
  2160 			$linkflags .= ' -f "${target.data}\\'.$tempFilenameRoot.'.def"';
       
  2161 			
       
  2162 			if (&main::ExportUnfrozen)
       
  2163 				{
       
  2164 				$linkflags .= ' -implib "${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).'${var:IMPORT_LIBRARY}"'.
       
  2165 					' -addcommand "out:${output.file.name}" -warnings off';
       
  2166 				}
       
  2167 			else
       
  2168 				{
       
  2169 				$linkflags .= ' -noimplib ';
       
  2170 				}
       
  2171 			}
       
  2172 			else
       
  2173 			{
       
  2174 			$linkflags .= ' -noimplib ';
       
  2175 			}
       
  2176 
       
  2177 		if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o)
       
  2178 			{
       
  2179 			if (($CW_major_version >= 3) ||
       
  2180 				((2.8 == $CW_major_version) && ($CW_minor_version >= 1)))
       
  2181 				{
       
  2182 				# For OEM2.8.1 onwards, make use of ${var:LINK_OBJS_NO_PATH} in order to reduce link
       
  2183 				# command line lengths
       
  2184 				$linkCommand = 'mwldsym2.exe '.$stage1linkflags.' ${var:COMMON_LINK_FLAGS} -l "${target.data}\\ObjectCode" -search ${var:LINK_OBJS_NO_PATH}';				
       
  2185 				}
       
  2186 			else
       
  2187 				{
       
  2188 				$linkCommand = 'mwldsym2.exe '.$stage1linkflags.' ${var:COMMON_LINK_FLAGS} @"${target.data}\${output.file.root}.lst"';
       
  2189 				}
       
  2190 
       
  2191 			addLinkDescriptorCommand ($linkCommand, undef, undef, undef, $FirstLib);
       
  2192 				
       
  2193 			$linkCommand = $deleteCommand.'"${target.data}\\${output.file.name}"';
       
  2194 			addLinkDescriptorCommand ($linkCommand);
       
  2195 
       
  2196 			my $show_options = 'names,unmangled,verbose';
       
  2197 			$linkCommand = 'mwldsym2.exe -S -show only,'.$show_options.' -o "${target.data}\\'.$tempFilenameRoot.'.inf" "${target.data}\\${var:IMPORT_LIBRARY}"';
       
  2198 			addLinkDescriptorCommand ($linkCommand);
       
  2199 
       
  2200 			$linkCommand = 'perl.exe -S makedef.pl '.$AbsentSubst.' -Inffile "${target.data}\\'.$tempFilenameRoot.'.inf"';
       
  2201 			if (-e $DefFile)
       
  2202 				{
       
  2203 				$linkCommand .= ' -Frzfile "'.$DefFile.'"';
       
  2204 				}
       
  2205 				
       
  2206 			my $Export;
       
  2207 			my $Ordinal=1;
       
  2208 			foreach $Export (&main::Exports)
       
  2209 				{
       
  2210 				$linkCommand .= " -$Ordinal $Export";
       
  2211 				$Ordinal++;
       
  2212 				}					
       
  2213 
       
  2214 			$linkCommand .= ' "${target.data}\\'.$tempFilenameRoot.'.def"';					
       
  2215 			addLinkDescriptorCommand ($linkCommand);
       
  2216 			
       
  2217 			$linkCommand = $deleteCommand.'"${target.data}\\'.$tempFilenameRoot.'.inf"';
       
  2218 			addLinkDescriptorCommand ($linkCommand);
       
  2219 			
       
  2220 			$linkCommand = $deleteCommand.'"${target.data}\\${var:IMPORT_LIBRARY}"';
       
  2221 			addLinkDescriptorCommand ($linkCommand);
       
  2222 			}
       
  2223 
       
  2224 		$linkCommand = "mwldsym2.exe ";
       
  2225 
       
  2226 		if ($BasicTrgType =~/^LIB$/o)
       
  2227 			{
       
  2228 			$linkCommand .= '-library ';
       
  2229 			}
       
  2230 
       
  2231 		if (($CW_major_version >= 3) ||
       
  2232 			((2.8 == $CW_major_version) && ($CW_minor_version >= 1)))
       
  2233 			{
       
  2234 			# For OEM2.8.1 onwards, make use of ${var:LINK_OBJS_NO_PATH} in order to reduce link
       
  2235 			# command line lengths
       
  2236 			$linkCommand .= $linkflags.' ${var:COMMON_LINK_FLAGS} -l "${target.data}\\ObjectCode" -search ${var:LINK_OBJS_NO_PATH}';	
       
  2237 			}
       
  2238 		else
       
  2239 			{
       
  2240 			$linkCommand .= $linkflags.'${var:COMMON_LINK_FLAGS} @"${target.data}\${output.file.root}.lst"';				
       
  2241 			}
       
  2242 
       
  2243 		my $warningMessage;
       
  2244 		
       
  2245 		if (&main::ExportUnfrozen)
       
  2246 			{
       
  2247 			$warningMessage = $exportUnfrozenWarningMessage;
       
  2248 			}
       
  2249 
       
  2250 		if ($BasicTrgType =~/^LIB$/o)
       
  2251 			{				
       
  2252 			addLinkDescriptorCommand ($linkCommand, undef, undef, undef, undef, $warningMessage);
       
  2253 			}
       
  2254 		else
       
  2255 			{
       
  2256 			addLinkDescriptorCommand ($linkCommand, undef, undef, undef, $FirstLib, $warningMessage);
       
  2257 			}
       
  2258 
       
  2259 		if (&Winutl_CopyForStaticLinkage)
       
  2260 			{
       
  2261 			$linkCommand = $copyCommand.
       
  2262 							'"${output}\\${output.file.name}" '.
       
  2263 							'"${var:KIT_EPOCROOT}'.kitRelativePath($RelPath).'${output.file.name}"';
       
  2264 			addLinkDescriptorCommand ($linkCommand, "false", "false");
       
  2265 			}
       
  2266 		}
       
  2267 
       
  2268 ##########################################
       
  2269 # RVCT library generation and link stage #
       
  2270 ##########################################
       
  2271 
       
  2272 	elsif ($ABIV1 && ($CW_major_version >= 3)) 
       
  2273 		{
       
  2274 		my $InterWorking = ($ABI eq 'ARMV4') ? "" : "--inter";
       
  2275 			
       
  2276 		# Generate library
       
  2277 
       
  2278 		if ($DefFile and !$NoExportLibrary)
       
  2279 			{
       
  2280 			unless (&main::ExportUnfrozen)
       
  2281 				{
       
  2282 				$linkCommand = 'perl.exe -S prepdef.pl "${var:DEF_FILE}" "${target.data}\\'.$tempFilenameRoot.'.prep.def"';
       
  2283 				addLinkDescriptorCommand ($linkCommand);
       
  2284 
       
  2285 				$linkCommand = 'def2dll.bat --path="${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).'\\" --bldpath="${target.data}" --import='.$tempFilenameRoot.' '.
       
  2286 					'--deffile="${target.data}\\'.$tempFilenameRoot.'.prep.def" --linkAs='.$LinkAs.' '.$InterWorking;
       
  2287 				addLinkDescriptorCommand ($linkCommand);
       
  2288 
       
  2289 				if ($ExtraExportLibrary)
       
  2290 					{
       
  2291 					$linkCommand = $copyCommand.'"${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).'${var:IMPORT_LIBRARY}" '.
       
  2292 									'"${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).$ExtraExportLibrary.'.lib"';
       
  2293 					addLinkDescriptorCommand ($linkCommand,"false", "false");
       
  2294 					}
       
  2295 				}
       
  2296 			}
       
  2297 
       
  2298 		return if ($BasicTrgType=~/^IMPLIB$/io);
       
  2299 		
       
  2300 
       
  2301 		# Create custom symbols only required in RVCT builds
       
  2302 		my $implibs_no_path_vtblexport = "";
       
  2303 
       
  2304 		foreach my $lib (@LibList)
       
  2305 			{
       
  2306 			$implibs_no_path_vtblexport.="$lib(VtblExports.o) ";
       
  2307 			}
       
  2308 
       
  2309 		addLinkDescriptorSymbol ('${var:IMPLIBS_NO_PATH_VTBLEXPORT}', $implibs_no_path_vtblexport);
       
  2310 
       
  2311 		my $AbsentSubst = '';
       
  2312 		my $EntrySymbol;
       
  2313 		my $Link = '';
       
  2314 
       
  2315 		if ($BasicTrgType=~/^DLL$/o) {
       
  2316 			$EntrySymbol = '_E32Dll';
       
  2317 		}
       
  2318 		elsif ($BasicTrgType=~/^EXE$/o) {
       
  2319 			$EntrySymbol = '_E32Startup';
       
  2320 		}
       
  2321 		if ($EntrySymbol) {
       
  2322 			$AbsentSubst = " -absent $EntrySymbol";
       
  2323 		}
       
  2324 
       
  2325 		$Link = 'armlink '.$oP.'diag_suppress 6331,6780'.$linkeropts.' ';
       
  2326 
       
  2327 		if ($Bld =~ /DEB$/o)
       
  2328 			{
       
  2329 			$Link .= ' '.$oP.'debug';
       
  2330 			}
       
  2331 
       
  2332 
       
  2333 	    # TARGET *.IN
       
  2334 	    #------------
       
  2335 
       
  2336 		# Create "via" file containing all link objects in order to reduce link
       
  2337 		# command line length
       
  2338 		addLinkDescriptorDumpFile ('${var:LINK_OBJS}', '${target.data}\\${output.file.root}_'.$Bld.'_objects.via');
       
  2339 		
       
  2340 		if ($BasicTrgType!~/^LIB$/o) {
       
  2341 			$linkCommand = $Link .' '.$oP.'partial -o ${var:COMMON_LINK_FLAGS} "${target.data}\\${output.file.root}.in" '.$oP.'via "${target.data}\\${output.file.root}_'.$Bld.'_objects.via"';
       
  2342 			addLinkDescriptorCommand ($linkCommand);
       
  2343 		}
       
  2344 
       
  2345 		# Perform link
       
  2346 
       
  2347 	    if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  2348 	#		reorder the .DEF file taking frozen exports into account if there are any
       
  2349 
       
  2350 			$linkCommand = 'perl -S elf2inf.pl -o "${target.data}\\'.$tempFilenameRoot.'.inf" "${target.data}\\${output.file.root}.in"';
       
  2351 			addLinkDescriptorCommand ($linkCommand);
       
  2352 
       
  2353 			$linkCommand = 'perl -S makedef.pl '.$AbsentSubst.' -Inf "${target.data}\\'.$tempFilenameRoot.'.inf"';
       
  2354 
       
  2355 	    	if (!$DefFile || $NoExportLibrary) {    			
       
  2356 	    		$linkCommand .= ' -ignore_unfrozen_noncallable ';
       
  2357 	    	}
       
  2358 		if (SysTrg()) {
       
  2359 	    		$linkCommand .= ' -SystemTargetType ';
       
  2360 	    	}		
       
  2361 		
       
  2362 		    if (-e $DefFile) {	# effectively "if project frozen ..."
       
  2363 		        $linkCommand .= " -Frzfile \"".'${var:DEF_FILE}'."\"";
       
  2364 		    }
       
  2365 		    # freeze ordinals, a maximum of 2, for polymorphic dlls
       
  2366 		    my $Ordinal;
       
  2367 		    my $Num=1;
       
  2368 		    foreach $Ordinal (&main::Exports) {
       
  2369 		    	$linkCommand .= " -$Num $Ordinal";
       
  2370 			    $Num++;
       
  2371 		    }
       
  2372 
       
  2373 		    $linkCommand.= ' "${target.data}\\'.$tempFilenameRoot.'.def"';
       
  2374 		    addLinkDescriptorCommand ($linkCommand);
       
  2375     
       
  2376 		    my $theDefFile = '"${target.data}\\'.$tempFilenameRoot.'.def"';
       
  2377 		    $theDefFile = '"${var:DEF_FILE}"' if (-e $DefFile && !&main::ExportUnfrozen);
       
  2378 
       
  2379 			$linkCommand = 'def2dll.bat'.$AbsentSubst.' --path="${target.data}" --bldpath="${target.data}" --export='.$tempFilenameRoot.' --deffile='.$theDefFile.' --linkAs='.$LinkAs.' '.$InterWorking;
       
  2380 			addLinkDescriptorCommand ($linkCommand);
       
  2381 	    }
       
  2382 
       
  2383         if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  2384 #		generate an export object from the ordered .DEF file
       
  2385 		if (&main::ExportUnfrozen) {
       
  2386 			$linkCommand = 'def2dll.bat --path="${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).'\\" --bldpath="${target.data}" --import='.$tempFilenameRoot.
       
  2387 				' --deffile="${target.data}\\'.$tempFilenameRoot.'.def" --linkAs='.$LinkAs.' '.$InterWorking;
       
  2388 		    addLinkDescriptorCommand ($linkCommand, undef, undef, undef, undef, $exportUnfrozenWarningMessage);
       
  2389 			}
       
  2390         }
       
  2391 
       
  2392 #       get rid of any -symbols produced .map file
       
  2393         if ($BasicTrgType=~/^(DLL|EXE)/o) {
       
  2394 			$linkCommand = $deleteCommand.'"${output}\\${output.file.name}.map"';
       
  2395 			addLinkDescriptorCommand ($linkCommand, "false", "false", undef, undef, undef, undef, (0,1));
       
  2396 		}
       
  2397 
       
  2398         if ($BasicTrgType=~/^(DLL|EXE)/o) {
       
  2399 	        my $datalinkbase = "0x400000";
       
  2400 	        $datalinkbase = &main::DataLinkAddress if (&main::DataLinkAddress);
       
  2401 		
       
  2402 	        $linkCommand = "$Link ".$oP.'shl '.$oP.'reloc '.$oP.'split '.$oP."rw-base $datalinkbase ".$oP.'noscanlib '."$PlatOpt{Ld}";
       
  2403 	        
       
  2404 	        if ($BasicTrgType=~/^DLL$/o) {
       
  2405 	            # get the right object file for the entry point
       
  2406 	            my $ObjFile = "UC_DLL_.o";
       
  2407 	            if ($FirstLib =~ /EDEV/i) {
       
  2408 		            $ObjFile = "D_ENTRY_.o";
       
  2409 	            }
       
  2410 	            if ($FirstLib =~ /EKLL/i) {
       
  2411 		            $ObjFile = "L_ENTRY_.o";
       
  2412 	            }
       
  2413 	            if ($FirstLib =~ /EEXT/i) {
       
  2414 		            $ObjFile = "X_ENTRY_.o";
       
  2415 	            }
       
  2416 	            if ($FirstLib =~ /EVAR/i) {
       
  2417 		            $ObjFile = "V_ENTRY_.o";
       
  2418 	            }
       
  2419 
       
  2420 #		    If platform is a customization, take libs from parent directory.		   
       
  2421 			$linkCommand .= $oP.'entry _E32Dll "'.$FirstLib.'('.$ObjFile.')"';
       
  2422 		    if($IsCustomDll)
       
  2423 		    {
       
  2424 				$linkCommand .=	' "${target.data}\\'.$tempFilenameRoot.'.exp"';
       
  2425 			}
       
  2426 		    
       
  2427 	        } elsif ($BasicTrgType=~/^EXE$/o || $TrgType=~/^EXEXP$/o) {
       
  2428 			    # get the right object file for the entry point
       
  2429 			    my $ObjFile = "UC_EXE_.o" ;
       
  2430 			    if ($FirstLib =~ /KC_EXE/i) {
       
  2431 					$ObjFile = "K_ENTRY_.o";
       
  2432 			    }
       
  2433 
       
  2434 			if($IsPlatCustomization) 
       
  2435 			{
       
  2436 				$linkCommand .= $oP.'entry _E32Startup "'.$FirstLib.'('.$ObjFile.')"';
       
  2437 			} 
       
  2438 			else
       
  2439 			{
       
  2440 			    	$linkCommand .= $oP.'entry _E32Startup "'.$FirstLib.'('.$ObjFile.')"';
       
  2441 			}
       
  2442 		    
       
  2443 			    if ($TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  2444 					$linkCommand .= ' "${target.data}\\'.$tempFilenameRoot.'.exp"';
       
  2445 				}
       
  2446 			}
       
  2447 
       
  2448 			$linkCommand .= ' -o "${target.data}\\${output.file.name}"';
       
  2449 
       
  2450 			$linkCommand .= ' '.$oP.'symbols '.$oP.'list "${output}\\${output.file.name}.map"';
       
  2451 			$linkCommand .= ' "${target.data}\\${output.file.root}.in"';
       
  2452 
       
  2453 
       
  2454 			if ($BasicTrgType=~/^DLL$/o) { # Add the DLL stub library
       
  2455 				if($IsPlatCustomization) 
       
  2456 				{
       
  2457 				if ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2) {
       
  2458 				   $linkCommand .= ' "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\ARMV5\\'.$Bld.'\EDLLSTUB'.$RVCTVersion.'.LIB"';
       
  2459 				}
       
  2460 				else {
       
  2461 				   $linkCommand .= ' "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\ARMV5\\'.$Bld.'\EDLLSTUB.LIB"';
       
  2462 				}
       
  2463 				}
       
  2464 				else
       
  2465 				{
       
  2466 				if ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2) {
       
  2467 				   $linkCommand .= ' "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\ARMV5\\'.$Bld.'\EDLLSTUB'.$RVCTVersion.'.LIB"';
       
  2468 				}
       
  2469 				else {
       
  2470 				   $linkCommand .= ' "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\ARMV5\\'.$Bld.'\EDLLSTUB.LIB"';
       
  2471 				}
       
  2472 				}
       
  2473 			}
       
  2474 
       
  2475 			$linkCommand .= ' ${var:LIBS}';
       
  2476 			
       
  2477 			
       
  2478 			my $runtimeLibs = "";
       
  2479 			my $StaticRTLib = "usrt".$RVCTVersion;
       
  2480 			
       
  2481 			# use ksrt for system code and for user ARM code
       
  2482 			$StaticRTLib = "ksrt".$RVCTVersion if ($SystemTrg);
       
  2483 			$runtimeLibs .= $StaticRTLib.".lib" unless ($Trg =~ /(U|K)SRT/i || ($BasicTrgType=~/^LIB$/o));
       
  2484 		
       
  2485 			unless ($ArmRT || ($BasicTrgType=~/^LIB$/o)) {
       
  2486 				my $TargLib = "$ExportLibrary.lib";
       
  2487 				$TargLib =~ s/\{(\d|a|b|c|d|e|f){8}\}//i;
       
  2488 				unless ($SystemTrg) {
       
  2489 					foreach (@RTLibList) {
       
  2490 						$runtimeLibs .= " ".$_ unless ($_ =~ /$TargLib/i);
       
  2491 					}
       
  2492 			    }
       
  2493 			}
       
  2494 
       
  2495 			foreach (@ArmLibList)
       
  2496 				{
       
  2497 				$runtimeLibs.= " ".$_;
       
  2498 				}
       
  2499 			
       
  2500 			addLinkDescriptorSymbol ('${var:RUNTIME_LIBS}', $runtimeLibs);
       
  2501 				
       
  2502 			if($IsPlatCustomization) 
       
  2503 			{
       
  2504 			     $linkCommand .= ' --userlibpath "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\\'.$ParentPlat.'\\'.$Bld.'","${var:KIT_EPOCROOT}\\EPOC32\RELEASE\\'.$ParentPlat.'\LIB" ${var:RUNTIME_LIBS} ${var:IMPLIBS_NO_PATH_VTBLEXPORT}';
       
  2505 			}
       
  2506 			else
       
  2507 				{
       
  2508 				addLinkDescriptorSymbol ('${var:RUNTIME_LIBS}', 'usrt'.$RVCTVersion.'.lib dfpaeabi.lib dfprvct'.$RVCTVersion.'.lib dfprvct'.$RVCTVersion.'-thunk.lib drtaeabi.lib drtaeabi.lib(VtblExports.o) drtrvct'.$RVCTVersion.'.lib');
       
  2509 				}
       
  2510 				
       
  2511 			$linkCommand .= ' --userlibpath "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\ARMV5\\'.$Bld.'","${var:KIT_EPOCROOT}\\EPOC32\RELEASE\ARMV5\LIB" ${var:RUNTIME_LIBS} ${var:IMPLIBS_NO_PATH_VTBLEXPORT}';
       
  2512 			
       
  2513 			addLinkDescriptorCommand ($linkCommand, undef, undef, undef, $FirstLib);
       
  2514 
       
  2515 	    	if ($Bld=~/^U?DEB$/o) {
       
  2516 			$linkCommand = $copyCommand. ' "${target.data}\\${output.file.name}" "${output}\\${output.file.root}.sym"'; 
       
  2517 			addLinkDescriptorCommand ($linkCommand, "false", "false");
       
  2518 	    	}
       
  2519 	
       
  2520 			$linkCommand = 'elftran -version '. &Genutl_VersionToUserString(%Version).' -sid '. &main::SecureId(); 
       
  2521 			if (&main::CompressTarget) {
       
  2522 				$linkCommand .= ' -nocompress ';
       
  2523 			}
       
  2524 			# change - exexps are allowed data, but they look like dlls to elftran....
       
  2525 			if (&main::AllowDllData || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  2526 				$linkCommand.=' -allow';
       
  2527 			}
       
  2528 			if (not &main::CallDllEntryPoints ) {
       
  2529 				$linkCommand.=' -nocall';
       
  2530 			}
       
  2531 			if (&main::DataLinkAddress) {
       
  2532 				$linkCommand.=' -datalinkaddress '.&main::DataLinkAddress;
       
  2533 			}
       
  2534 			if (&main::FixedProcess) {
       
  2535 				$linkCommand.=' -fixed';
       
  2536 			}
       
  2537 			if (&main::HeapSize) {
       
  2538 				my %HeapSize=&main::HeapSize;
       
  2539 				$linkCommand.=' -heap '.$HeapSize{Min}.' '.$HeapSize{Max};
       
  2540 			}
       
  2541 			if (&main::ProcessPriority) {
       
  2542 				$linkCommand.=' -priority '.&main::ProcessPriority;
       
  2543 			}
       
  2544 			if (&main::StackSize) {
       
  2545 				$linkCommand.=' -stack '.&main::StackSize;
       
  2546 			}
       
  2547 
       
  2548 			my $i=1;
       
  2549 			foreach (@UidList) {
       
  2550 				$linkCommand.=" -uid$i $_";
       
  2551 				$i++;
       
  2552 			}
       
  2553 			if(&main::VendorId) {
       
  2554 				$linkCommand.=' -vid '.&main::VendorId;
       
  2555 			}
       
  2556 
       
  2557 			$linkCommand.=' -fpu '.$floatingpointmodel;
       
  2558 
       
  2559 			$linkCommand.=' -capability '.&main::Capability. ' "${target.data}\\${output.file.name}" "${output}\\${output.file.name}"';
       
  2560 		
       
  2561 			addLinkDescriptorCommand ($linkCommand, "false");
       
  2562         	}
       
  2563         elsif ($BasicTrgType=~/^LIB$/o) {
       
  2564 			$linkCommand = 'armar '.$oP.'create "${output}\\${output.file.name}" '.$oP.'via "${target.data}\\${output.file.root}_'.$Bld.'_objects.via"'.' '.$archiveropts;
       
  2565 			addLinkDescriptorCommand ($linkCommand);
       
  2566 			}
       
  2567 		}
       
  2568 
       
  2569 ##############################################
       
  2570 # BPABI library generation and link stage    #
       
  2571 # Assumes use of RVCT 2.2					 #
       
  2572 ##############################################
       
  2573 
       
  2574 	elsif ($ABIV2 && ($CW_major_version >= 3.1)) {
       
  2575 		
       
  2576 		# prolly don't need this...
       
  2577 		my $InterWorking = ($ABI eq 'ARMV4') ? "" : "--inter";
       
  2578 			
       
  2579 		return if ($BasicTrgType=~/^IMPLIB$/io);
       
  2580 		
       
  2581 		if ($BasicTrgType=~/^LIB$/o) {
       
  2582 			$linkCommand = 'armar --create ${output}\\${output.file.name} ${var:LINK_OBJS} ${var:LIBS}'.' '.$archiveropts;
       
  2583 	        addLinkDescriptorCommand ($linkCommand);
       
  2584          }
       
  2585 		else
       
  2586 		{
       
  2587 		my $AbsentSubst = '';
       
  2588 		my $EntrySymbol;
       
  2589 		my $Link = '';
       
  2590 
       
  2591 		if ($BasicTrgType=~/^DLL$/o) {
       
  2592 			$EntrySymbol = '_E32Dll';
       
  2593 		}
       
  2594 		elsif ($BasicTrgType=~/^EXE$/o) {
       
  2595 			$EntrySymbol = '_E32Startup';
       
  2596 		}
       
  2597 		if ($EntrySymbol) {
       
  2598 			$AbsentSubst = " -absent $EntrySymbol";
       
  2599 		}
       
  2600 
       
  2601 		$Link = 'armlink '.$oP.'diag_suppress 6331,6780'.$linkeropts.' ';
       
  2602 
       
  2603 		if ($Bld =~ /DEB$/o)
       
  2604 			{
       
  2605 			$Link .= ' '.$oP.'debug';
       
  2606 			}
       
  2607 
       
  2608 
       
  2609 	    # TARGET *.IN
       
  2610 	    #------------
       
  2611 
       
  2612 		# Create "via" file containing all link objects in order to reduce link
       
  2613 		# command line length
       
  2614 		addLinkDescriptorDumpFile ('${var:LINK_OBJS}', '${target.data}\\${output.file.root}_'.$Bld.'_objects.via');
       
  2615 		
       
  2616 		if ($BasicTrgType!~/^LIB$/o) {
       
  2617 			$linkCommand = $Link .' '.$oP.'partial -o ${var:COMMON_LINK_FLAGS} "${target.data}\\${output.file.root}.in" '.$oP.'via "${target.data}\\${output.file.root}_'.$Bld.'_objects.via"';
       
  2618 
       
  2619 		}
       
  2620 
       
  2621 
       
  2622 #       get rid of any -symbols produced .map file
       
  2623         if ($BasicTrgType=~/^(DLL|EXE)/o) {
       
  2624 			$linkCommand = $deleteCommand.'"${output}\\${output.file.name}.map"';
       
  2625 			addLinkDescriptorCommand ($linkCommand, "false", "false", undef, undef, undef, undef, (0,1));
       
  2626 		}
       
  2627 
       
  2628         if ($BasicTrgType=~/^(DLL|EXE)/o) {
       
  2629 	        my $datalinkbase = "0x400000";
       
  2630 			my $librarylist;
       
  2631 			my $expr;
       
  2632 			@ToolChainLibList = &GetLibList;
       
  2633 
       
  2634 			foreach $expr (@ToolChainLibList) {
       
  2635 				$librarylist .= $expr.' ';
       
  2636 			}
       
  2637 	        
       
  2638   	        $datalinkbase = &main::DataLinkAddress if (&main::DataLinkAddress);
       
  2639 	        $linkCommand = "$Link ".$oP.'bpabi '.$oP.'reloc '.$oP.'split '.$oP.'no_scanlib '.$oP.'datacompressor=off '.$oP."rw-base $datalinkbase "."$PlatOpt{Ld}";
       
  2640 			$linkCommand .= ' --dll --symver_soname --soname '.$LinkAs.' ';
       
  2641 			
       
  2642 			
       
  2643 	        if ($BasicTrgType=~/^DLL$/o) {
       
  2644 	            # get the right object file for the entry point
       
  2645 	            my $ObjFile = "UC_DLL_.o";
       
  2646 	            if ($FirstLib =~ /EDEV/i) {
       
  2647 		            $ObjFile = "D_ENTRY_.o";
       
  2648 	            }
       
  2649 	            if ($FirstLib =~ /EKLL/i) {
       
  2650 		            $ObjFile = "L_ENTRY_.o";
       
  2651 	            }
       
  2652 	            if ($FirstLib =~ /EEXT/i) {
       
  2653 		            $ObjFile = "X_ENTRY_.o";
       
  2654 	            }
       
  2655 	            if ($FirstLib =~ /EVAR/i) {
       
  2656 		            $ObjFile = "V_ENTRY_.o";
       
  2657 	            }
       
  2658 
       
  2659 #		    If platform is a customization, take libs from parent directory.		   
       
  2660 		    if($IsCustomDll)
       
  2661 		    {
       
  2662 		    
       
  2663 			$linkCommand .= $oP.'entry _E32Dll "'.$FirstLib.'('.$ObjFile.')"'.
       
  2664 					' "${target.data}\\'.$tempFilenameRoot.'.exp"';
       
  2665 			    
       
  2666 		    }
       
  2667 		    else
       
  2668 		    {
       
  2669 		    # ARMV5 hardcoded here...
       
  2670 		    $linkCommand .= $oP.'entry _E32Dll "'.$FirstLib.'('.$ObjFile.')"';
       
  2671 		    }
       
  2672 
       
  2673 	        } elsif ($BasicTrgType=~/^EXE$/o || $TrgType=~/^EXEXP$/o) {
       
  2674 			    # get the right object file for the entry point
       
  2675 			    my $ObjFile = "UC_EXE_.o" ;
       
  2676 			    if ($FirstLib =~ /KC_EXE/i) {
       
  2677 					$ObjFile = "K_ENTRY_.o";
       
  2678 			    }
       
  2679 
       
  2680 		    # Should this use $ParentPlat rather than hardcoded ARMV5 dir?
       
  2681 		   $linkCommand .= $oP.'entry _E32Startup "'.$FirstLib.'('.$ObjFile.')"';
       
  2682 		
       
  2683 			}
       
  2684 
       
  2685 			$linkCommand .= ' -o "${target.data}\\${output.file.name}"';
       
  2686 
       
  2687 			if ($BasicTrgType=~/^DLL$/o) { # Add the DLL stub library
       
  2688 				if($IsPlatCustomization) 
       
  2689 				{
       
  2690 				if ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2) {
       
  2691 				   $linkCommand .= ' "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\\'.$ParentPlat.'\\'.$Bld.'\EDLLSTUB'.$RVCTVersion.'.LIB"';
       
  2692 				}
       
  2693 				else {
       
  2694 				   $linkCommand .= ' "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\\'.$ParentPlat.'\\'.$Bld.'\EDLLSTUB.LIB"';
       
  2695 				}
       
  2696 				}
       
  2697 				else
       
  2698 				{
       
  2699 				if ($RVCTMajorVersion == 2 && $RVCTMinorVersion < 2) {
       
  2700 				   $linkCommand .= ' "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\ARMV5\\'.$Bld.'\EDLLSTUB'.$RVCTVersion.'.LIB"';
       
  2701 				}
       
  2702 				else {
       
  2703 				   $linkCommand .= ' "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\ARMV5\\'.$Bld.'\EDLLSTUB.LIB"';
       
  2704 				}
       
  2705 				}
       
  2706 			}
       
  2707 
       
  2708 			$linkCommand .= ' ${var:LIBS}';
       
  2709 			
       
  2710 			
       
  2711 			my $runtimeLibs = "";
       
  2712 			my $StaticRTLib = "usrt".$RVCTVersion;
       
  2713 			
       
  2714 			# use ksrt for system code and for user ARM code
       
  2715 			$StaticRTLib = "ksrt".$RVCTVersion if ($SystemTrg);
       
  2716 			$runtimeLibs .= $StaticRTLib.".lib" unless ($Trg =~ /(U|K)SRT/i || ($BasicTrgType=~/^LIB$/o));
       
  2717 		
       
  2718 			unless ($ArmRT || ($BasicTrgType=~/^LIB$/o)) {
       
  2719 				my $TargLib = "$ExportLibrary.lib";
       
  2720 				$TargLib =~ s/\{(\d|a|b|c|d|e|f){8}\}//i;
       
  2721 				unless ($SystemTrg) {
       
  2722 					foreach (@RTLibList) {
       
  2723 						$runtimeLibs .= " ".$_ unless ($_ =~ /$TargLib/i);
       
  2724 					}
       
  2725 			    }
       
  2726 			}
       
  2727 
       
  2728 			foreach (@ArmLibList)
       
  2729 				{
       
  2730 				$runtimeLibs.= " ".$_;
       
  2731 				}
       
  2732 			
       
  2733 			addLinkDescriptorSymbol ('${var:RUNTIME_LIBS}', $runtimeLibs);
       
  2734 				
       
  2735 			$linkCommand .= ' --userlibpath "${var:KIT_EPOCROOT}\\EPOC32\RELEASE\ARMV5\\'.$Bld.'","${var:KIT_EPOCROOT}\\EPOC32\RELEASE\ARMV5\LIB" '.$oP.'via "${target.data}\\${output.file.root}_'.$Bld.'_objects.via" ${var:RUNTIME_LIBS} '.$librarylist.' ';
       
  2736 			
       
  2737 			addLinkDescriptorCommand ($linkCommand, undef, undef, undef, $FirstLib);
       
  2738 
       
  2739 		}
       
  2740 		
       
  2741 		#### Create the .sym file
       
  2742 		$linkCommand = 'cmd.exe /C copy "${target.data}\\${output.file.name}" "${output}\\${output.file.root}.sym"';
       
  2743 		addLinkDescriptorCommand ($linkCommand);
       
  2744 		
       
  2745 		#### copy the project .def file for prep
       
  2746 		if ($DefFile and !$NoExportLibrary)
       
  2747 		{
       
  2748 			unless (&main::ExportUnfrozen)
       
  2749 			{
       
  2750         	$linkCommand = 'cmd.exe /C copy "${var:DEF_FILE}" "${target.data}\\${var:IMPORT_LIBRARY_NO_EXT}.prep.def"';
       
  2751 			addLinkDescriptorCommand ($linkCommand);
       
  2752 			}
       
  2753 		}
       
  2754 		
       
  2755 		
       
  2756 		#### ELF2E32 POST-LINK COMMAND ####
       
  2757 		# Section needs to be generic for BPABI (e.g. GCCE & ARMV5_ABIV2)
       
  2758 		$linkCommand  = '${var:KIT_EPOCROOT}\\epoc32\\tools\\elf2e32.exe ';		
       
  2759 		
       
  2760 		# Change - exexps are allowed data, but they look like dlls to elftran....
       
  2761 		if (&main::AllowDllData || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  2762 			$linkCommand .= ' --dlldata';
       
  2763 		}
       
  2764 
       
  2765 		if (&main::DataLinkAddress) {
       
  2766 			$linkCommand .= ' --datalinkaddress=',&main::DataLinkAddress;
       
  2767 		}
       
  2768 		if (&main::FixedProcess) {
       
  2769 			$linkCommand .=	' --fixedaddress';
       
  2770 		}
       
  2771 		
       
  2772 		$linkCommand .= ' --sid='.&main::SecureId();
       
  2773 		$linkCommand .= ' --version='. &Genutl_VersionToUserString(%Version);
       
  2774 		
       
  2775 		if (&main::HeapSize) {
       
  2776 			my %HeapSize=&main::HeapSize;
       
  2777 			$linkCommand.=' --heap '.$HeapSize{Min} .','.$HeapSize{Max};
       
  2778 		}
       
  2779 		
       
  2780 		if (&main::ProcessPriority) {
       
  2781 			$linkCommand .=	' --priority='.&main::ProcessPriority;
       
  2782 		}
       
  2783 		
       
  2784 		if (&main::StackSize) {
       
  2785 			$linkCommand .= ' --stack='.&main::StackSize;
       
  2786 		}
       
  2787 		
       
  2788 		my $i=1;
       
  2789 		foreach (@UidList) {
       
  2790 			$linkCommand .= " --uid$i=$_";
       
  2791 			$i++;
       
  2792 		}
       
  2793 		if (&main::VendorId) {
       
  2794 			$linkCommand .= ' --vid='.&main::VendorId;
       
  2795 		}
       
  2796 		
       
  2797 		$linkCommand .= ' --capability='.&main::Capability;
       
  2798 
       
  2799 		# ARMFPU only currently supported for RVCT BPABI builds
       
  2800 		if (&main::ARMFPU && (&main::ARMFPU =~ /^VFPV2$/i)) {
       
  2801 			$linkCommand .= ' --fpu=vfpv2'
       
  2802 		}
       
  2803 		else {
       
  2804 			$linkCommand .= ' --fpu=softvfp'
       
  2805 		}
       
  2806 		
       
  2807 	
       
  2808 		if(($BasicTrgType=~/^DLL/ && $TrgType!~/^DLL/ ) || $TrgType=~/^EXEXP/) {
       
  2809 	 		$linkCommand .= ' --targettype='.$TrgType;
       
  2810  		}
       
  2811  		else {
       
  2812  			$linkCommand .= ' --targettype='.$BasicTrgType;
       
  2813  		}
       
  2814 		
       
  2815 		$linkCommand .= ' --output="${output}\\${output.file.name}"';
       
  2816 		
       
  2817 		my $warningMessage;
       
  2818 		if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  2819 			if ($DefFile and !$NoExportLibrary) {
       
  2820 				$linkCommand .= ' --definput="${target.data}\\${var:IMPORT_LIBRARY_NO_EXT}.prep.def"';
       
  2821 			}
       
  2822 			$linkCommand .= ' --dso=';
       
  2823 			$linkCommand .= '"${var:KIT_EPOCROOT}\\EPOC32\\RELEASE\\ARMV5\\LIB\\${var:IMPORT_LIBRARY}"';
       
  2824 				
       
  2825 			$linkCommand .= ' --defoutput=';
       
  2826 			$linkCommand .= '"${target.data}\\${var:IMPORT_LIBRARY_NO_EXT}.def"';
       
  2827 				
       
  2828 			if (&main::ExportUnfrozen) {
       
  2829 				$warningMessage = $exportUnfrozenWarningMessage;
       
  2830 				$linkCommand .= ' --unfrozen';
       
  2831 			}
       
  2832 		}
       
  2833 		
       
  2834 		$linkCommand .= ' --elfinput="${target.data}\\${output.file.name}"';
       
  2835 		$linkCommand .= ' --linkas='.$LinkAs;
       
  2836 		#Change - LIB path is hardcoded here...
       
  2837 		$linkCommand .= ' --libpath="${var:KIT_EPOCROOT}\\EPOC32\\RELEASE\\ARMV5\\LIB"';
       
  2838 		
       
  2839         if ($BasicTrgType=~/^DLL$/o && $TrgType!~/^DLL/){
       
  2840 			my $Export;
       
  2841 			my $Ordinal=1;
       
  2842 			foreach $Export (&main::Exports)
       
  2843 				{
       
  2844 				if ($Ordinal eq 1) {
       
  2845 					$linkCommand .= ' --sysdef=';
       
  2846 				}
       
  2847 				elsif ($Ordinal ne 1) {
       
  2848 					$linkCommand .= ';';
       
  2849 					}
       
  2850 					
       
  2851 				$linkCommand .= "$Export,".$Ordinal;
       
  2852 				$Ordinal++;
       
  2853 				}
       
  2854 		}
       
  2855 		
       
  2856 		addLinkDescriptorCommand ($linkCommand, undef, undef, undef, undef, $warningMessage);
       
  2857 		
       
  2858 		}
       
  2859 		
       
  2860 		# copy def file output
       
  2861 		if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  2862 			$linkCommand = 'cmd.exe /C copy  "${target.data}\\${var:IMPORT_LIBRARY_NO_EXT}.def" "${Project}\${var:IMPORT_LIBRARY_NO_EXT}.def"';
       
  2863 			addLinkDescriptorCommand($linkCommand);
       
  2864 		}
       
  2865 		
       
  2866 		# copy the import lib (dso) created
       
  2867 		if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  2868 			if ($DefFile and !$NoExportLibrary) {
       
  2869 				$linkCommand = 'cmd.exe /C copy ${var:KIT_EPOCROOT}\\EPOC32\\RELEASE\\ARMV5\\LIB\\${var:IMPORT_LIBRARY} ${var:KIT_EPOCROOT}\\EPOC32\\RELEASE\\ARMV5\\LIB\\${output.file.root}.dso';
       
  2870 			}
       
  2871 			addLinkDescriptorCommand($linkCommand);
       
  2872 		}
       
  2873 	
       
  2874 	}
       
  2875 			
       
  2876 #########################################
       
  2877 # GCC library generation and link stage #
       
  2878 #########################################
       
  2879 
       
  2880 	elsif ($Plat eq "ARM4")
       
  2881 		{
       
  2882 		# Generate library
       
  2883 
       
  2884 		if ($DefFile and !$NoExportLibrary)
       
  2885 			{
       
  2886 			unless (&main::ExportUnfrozen)
       
  2887 				{
       
  2888 				$linkCommand = 'perl.exe -S prepdef.pl "${var:DEF_FILE}" "${target.data}\\'.$tempFilenameRoot.'.prep.def"';
       
  2889 				addLinkDescriptorCommand ($linkCommand);
       
  2890 
       
  2891 				$linkCommand = "$Dlltool $PlatOpt{Dlltool}".' --output-lib "${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).'${var:IMPORT_LIBRARY}" --def "'.
       
  2892 						'${target.data}\\'.$tempFilenameRoot.'.prep.def" --dllname "'.$LinkAs.'"';
       
  2893 				addLinkDescriptorCommand ($linkCommand);
       
  2894 
       
  2895 				if ($ExtraExportLibrary)
       
  2896 					{
       
  2897 					$linkCommand = $copyCommand.'"${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).'${var:IMPORT_LIBRARY}" '.
       
  2898 									'"${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).$ExtraExportLibrary.'.lib"';
       
  2899 					addLinkDescriptorCommand ($linkCommand,"false", "false");
       
  2900 					}
       
  2901 
       
  2902 				foreach (@CompatibleABIs)
       
  2903 					{
       
  2904 					$linkCommand = "$Dlltool $ABIDlltool{$_}".' --output-lib "${var:KIT_EPOCROOT}'.kitRelativePath($ABILibPath{$_}).'UREL\\${var:IMPORT_LIBRARY}" --def "'.
       
  2905 							'${target.data}\\'.$tempFilenameRoot.'.prep.def" --dllname "'.$LinkAs.'"';
       
  2906 					addLinkDescriptorCommand ($linkCommand);
       
  2907 
       
  2908 					if ($ExtraExportLibrary)
       
  2909 						{
       
  2910 						$linkCommand = $copyCommand.'"${var:KIT_EPOCROOT}'.kitRelativePath($ABILibPath{$_}).'UREL\\${var:IMPORT_LIBRARY}" '.
       
  2911 										'"${var:KIT_EPOCROOT}'.kitRelativePath($ABILibPath{$_}).'UREL\\'.$ExtraExportLibrary.'.lib"';
       
  2912 						addLinkDescriptorCommand ($linkCommand,"false", "false");
       
  2913 						}
       
  2914 					}
       
  2915 				}
       
  2916 			}
       
  2917 
       
  2918 
       
  2919 		# TARGET *.IN
       
  2920 		#------------
       
  2921 		$linkCommand = $deleteCommand.'"${target.data}\\${output.file.root}.in"';
       
  2922 		addLinkDescriptorCommand ($linkCommand, "false", "false", undef, undef, undef, undef, (0,1));
       
  2923 				
       
  2924 		$linkCommand = 'ar.exe cr "${target.data}\\${output.file.root}.in" ${var:LINK_OBJS}';
       
  2925 		addLinkDescriptorCommand ($linkCommand);
       
  2926 		
       
  2927 
       
  2928 		# Perform Link
       
  2929 
       
  2930 	#	Establish the entry point symbol
       
  2931 		my $EntrySymbol;
       
  2932 		if ($BasicTrgType=~/^DLL$/o) {
       
  2933 			$EntrySymbol = '_E32Dll';
       
  2934 		}
       
  2935 		elsif ($BasicTrgType=~/^EXE$/o) {
       
  2936 			$EntrySymbol = '_E32Startup';
       
  2937 		}
       
  2938 		my $AbsentSubst = '';
       
  2939 		if ($EntrySymbol) {
       
  2940 			$AbsentSubst = " -absent $EntrySymbol";
       
  2941 		}
       
  2942 
       
  2943 		if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  2944 
       
  2945 	#		generate a .DEF file from the objects and static libraries
       
  2946 			$linkCommand = "$Dlltool $PlatOpt{Dlltool} --output-def ".'"${target.data}\\'.$tempFilenameRoot.'.inf" "${target.data}\\${output.file.root}.in"';
       
  2947 
       
  2948 			foreach (@StatLibList) {
       
  2949 				$linkCommand .= ' "${var:KIT_EPOCROOT}'.kitRelativePath($StatLinkPath).$_.'"';
       
  2950 			}
       
  2951 
       
  2952 			addLinkDescriptorCommand ($linkCommand);
       
  2953 
       
  2954 	#		reorder the .DEF file taking frozen exports into account if there are any
       
  2955 	#			call perl on the script here so nmake will die if there are errors - this doesn't happen if calling perl in a batch file
       
  2956 			$linkCommand = 'perl.exe -S makedef.pl -Deffile "${target.data}\\'.$tempFilenameRoot.'.inf" '.$AbsentSubst;
       
  2957 			if (-e $DefFile) { # effectively "if project frozen ..."
       
  2958 				$linkCommand .= " -Frzfile \"".'${var:DEF_FILE}'."\"";
       
  2959 			}
       
  2960 			# freeze ordinals, a maximum of 2, for polymorphic dlls
       
  2961 			my $Ordinal;
       
  2962 			my $Num=1;
       
  2963 			foreach $Ordinal (&main::Exports) {
       
  2964 				$linkCommand .= " -$Num $Ordinal";
       
  2965 				$Num++;
       
  2966 			}
       
  2967 			$linkCommand .= ' "${target.data}\\'.$tempFilenameRoot.'.def"';
       
  2968 			addLinkDescriptorCommand ($linkCommand);
       
  2969 
       
  2970 	#		delete the unordered definition file
       
  2971 			$linkCommand = $deleteCommand.'"${target.data}\\'.$tempFilenameRoot.'.inf"';
       
  2972 			addLinkDescriptorCommand ($linkCommand, "false", "false");
       
  2973 
       
  2974 	#		generate an export object from the ordered .DEF file
       
  2975 			$linkCommand = "$Dlltool $PlatOpt{Dlltool} --def".' "${target.data}\\'.$tempFilenameRoot.'.def"'.
       
  2976 				' --output-exp "${target.data}\\'.$tempFilenameRoot.'.exp"'.
       
  2977 				" --dllname \"$LinkAs\"";
       
  2978 
       
  2979 			my $warningMessage;
       
  2980 				
       
  2981 			if (&main::ExportUnfrozen) {
       
  2982 				$warningMessage = $exportUnfrozenWarningMessage;
       
  2983 				$linkCommand .= ' --output-lib "${var:KIT_EPOCROOT}'.kitRelativePath($LibPath).'${var:IMPORT_LIBRARY}"';
       
  2984 			}
       
  2985 			
       
  2986 			addLinkDescriptorCommand ($linkCommand, undef, undef, undef, undef, $warningMessage);
       
  2987 		}
       
  2988 
       
  2989 	#	call ld to do base relocations (and dll exports)
       
  2990 		if ($BasicTrgType=~/^(DLL|EXE)/o) {
       
  2991 			$linkCommand = "$Link $PlatOpt{Ld} -s";	
       
  2992 			if ($BasicTrgType=~/^DLL$/o) {
       
  2993 				$linkCommand .= " $PlatOpt{Entry} $EntrySymbol -u $EntrySymbol ".'"${target.data}\\'.$tempFilenameRoot.'.exp" --dll ';
       
  2994 			}
       
  2995 			elsif ($BasicTrgType=~/^EXE$/o) {
       
  2996 				$linkCommand .= " $PlatOpt{Entry} $EntrySymbol -u $EntrySymbol ";
       
  2997 			}
       
  2998 	#		--whole-archive is required here apparently because of a defect in the gcc toolchain
       
  2999 	#		the flag can probably be removed with a later version of gcc
       
  3000 
       
  3001 			$linkCommand .= '--base-file "${target.data}\\${output.file.root}.bas" -o "${target.data}\\${output.file.name}" '.
       
  3002 				'${var:FIRST_LIB} --whole-archive "${target.data}\\${output.file.root}.in" '.
       
  3003 				"--no-whole-archive";
       
  3004 			$linkCommand .= ' ${var:COMMON_LINK_FLAGS} ${var:LIBS}';
       
  3005 			addLinkDescriptorCommand ($linkCommand, undef, undef, undef, $FirstLib);
       
  3006 
       
  3007 	#		delete temporary files
       
  3008 			if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  3009 				$linkCommand = $deleteCommand.'"${target.data}\\'.$tempFilenameRoot.'.exp"';
       
  3010 				addLinkDescriptorCommand ($linkCommand, "false", "false", undef, undef, undef, undef, (0,1));
       
  3011 			}
       
  3012 			$linkCommand = $deleteCommand.'"${target.data}\\${output.file.name}"';
       
  3013 			addLinkDescriptorCommand ($linkCommand, "false", "false");
       
  3014 
       
  3015 	#		call dlltool to do base relocations (and dll exports)
       
  3016 			$linkCommand = "$Dlltool $PlatOpt{Dlltool} ";
       
  3017 			if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  3018 				$linkCommand .= '--def "${target.data}\\'.$tempFilenameRoot.'.def" '.
       
  3019 					"--dllname \"$LinkAs\" ";
       
  3020 			}
       
  3021 			$linkCommand .= '--base-file "${target.data}\\${output.file.root}.bas" '.
       
  3022 				'--output-exp "${target.data}\\'.$tempFilenameRoot.'.exp" ';
       
  3023 			addLinkDescriptorCommand ($linkCommand);
       
  3024 
       
  3025 	#		delete temporary files
       
  3026 			$linkCommand = $deleteCommand.'"${target.data}\\${output.file.root}.bas"';
       
  3027 			addLinkDescriptorCommand ($linkCommand, "false", "false");
       
  3028 
       
  3029 	#		call ld to link the target
       
  3030 			$linkCommand = "$Link $PlatOpt{Ld}";
       
  3031 			if ($Bld=~/^U?REL$/o) {
       
  3032 				$linkCommand .= " -s";
       
  3033 			}
       
  3034 			if ($BasicTrgType=~/^DLL$/o) {
       
  3035 				$linkCommand .= " $PlatOpt{Entry} $EntrySymbol -u $EntrySymbol --dll ";
       
  3036 			}
       
  3037 			elsif ($BasicTrgType=~/^EXE$/o) {
       
  3038 				$linkCommand .= " $PlatOpt{Entry} $EntrySymbol -u $EntrySymbol ";
       
  3039 			}
       
  3040 	#		--whole-archive is required here apparently because of a defect in the gcc toolchain
       
  3041 	#		the flag can probably be removed with a later version of gcc
       
  3042 			$linkCommand .= '"${target.data}\\'.$tempFilenameRoot.'.exp" '.
       
  3043 				'-Map "${output}\\${output.file.name}.map" -o "${target.data}\\${output.file.name}" '.
       
  3044 				'${var:FIRST_LIB} --whole-archive "${target.data}\\${output.file.root}.in" '.
       
  3045 				"--no-whole-archive";
       
  3046 			$linkCommand .= ' ${var:LIBS}';
       
  3047 
       
  3048 			if ($BasicTrgType=~/^LIB$/o) {				
       
  3049 			addLinkDescriptorCommand ($linkCommand, undef, undef, undef, undef);
       
  3050 			}
       
  3051 			else {
       
  3052 			addLinkDescriptorCommand ($linkCommand, undef, undef, undef, $FirstLib);
       
  3053 			}
       
  3054 
       
  3055 	#		delete temporary files
       
  3056 			$linkCommand = $deleteCommand.'"${target.data}\\'.$tempFilenameRoot.'.exp"';
       
  3057 			addLinkDescriptorCommand ($linkCommand, "false", "false");
       
  3058 
       
  3059 			if ($Bld=~/DEB$/o) {
       
  3060 				$linkCommand = $Objcopy.' -X "${target.data}\\${output.file.name}" "${output}\\${output.file.root}.sym"';
       
  3061 				addLinkDescriptorCommand ($linkCommand);
       
  3062 			}
       
  3063 
       
  3064 			$linkCommand = "petran.exe $PlatOpt{Petran} -version ". &Genutl_VersionToUserString(%Version). " -sid ". &main::SecureId(). ' "${target.data}\\${output.file.name}" "${output}\\${output.file.name}" ';
       
  3065 
       
  3066 			if (&main::CompressTarget) {
       
  3067 				$linkCommand .= ' -nocompress';
       
  3068 			}
       
  3069 			if (&main::AllowDllData) {
       
  3070 				$linkCommand .= ' -allow';
       
  3071 			}
       
  3072 			if (not &main::CallDllEntryPoints) {
       
  3073 				$linkCommand .= ' -nocall';
       
  3074 			}
       
  3075 			if (&main::DataLinkAddress) {
       
  3076 				$linkCommand .= ' -datalinkaddress '.&main::DataLinkAddress;
       
  3077 			}
       
  3078 			if (&main::FixedProcess) {
       
  3079 				$linkCommand .= ' -fixed';
       
  3080 			}
       
  3081 			if (&main::HeapSize) {
       
  3082 				my %HeapSize=&main::HeapSize;
       
  3083 				$linkCommand .= ' -heap '.$HeapSize{Min}.' '.$HeapSize{Max};
       
  3084 			}
       
  3085 			if (&main::ProcessPriority) {
       
  3086 				$linkCommand .= ' -priority '.&main::ProcessPriority;
       
  3087 			}
       
  3088 			if (&main::StackSize) {
       
  3089 				$linkCommand .= ' -stack '.&main::StackSize;
       
  3090 			}
       
  3091 			my $i=1;
       
  3092 			foreach (@UidList) {
       
  3093 				$linkCommand .= " -uid$i $_";
       
  3094 				$i++;
       
  3095 			}
       
  3096 				
       
  3097 			$linkCommand .= ' -capability '.&main::Capability;
       
  3098 			
       
  3099 			if (&main::VendorId) {
       
  3100 			$linkCommand .= ' -vid '.&main::VendorId;
       
  3101 			}
       
  3102 		
       
  3103 			addLinkDescriptorCommand ($linkCommand, "false");
       
  3104 			
       
  3105 			$linkCommand = $deleteCommand.'"${target.data}\\${output.file.name}"';
       
  3106 			addLinkDescriptorCommand ($linkCommand, "false", "false");
       
  3107 		}
       
  3108 		elsif ($BasicTrgType=~/^LIB$/o) {
       
  3109 			$linkCommand = $copyCommand.'"${target.data}\\${output.file.root}.in" "${var:KIT_EPOCROOT}'.kitRelativePath($StatLinkPath).'${output.file.name}"';
       
  3110 			addLinkDescriptorCommand ($linkCommand,"false", "false");
       
  3111 		}
       
  3112 	}
       
  3113 	
       
  3114 ###############################################
       
  3115 # GCCE library generation and link stage      #
       
  3116 # GCCE only supported for CW 3.1 and greater #
       
  3117 ###############################################
       
  3118 
       
  3119 	elsif ($Plat eq "GCCE" || $CustGCCE)
       
  3120 	{	
       
  3121 	
       
  3122         if ($BasicTrgType=~/^LIB$/o) {
       
  3123 	        $linkCommand = 'ar cr ${output}\\${output.file.name} ${var:LINK_OBJS} ${var:LIBS}';
       
  3124 	        addLinkDescriptorCommand ($linkCommand);
       
  3125          }
       
  3126          
       
  3127 		elsif ($BasicTrgType=~/^(DLL|EXE)/o) {
       
  3128         
       
  3129         $linkCommand = 'arm-none-symbianelf-ld';
       
  3130         my $GCCE_LibGCCPath = ' -L';
       
  3131         $GCCE_LibGCCPath .= '"'.GetGCCELibPath("-print-file-name=libsupc++.a").'"';
       
  3132         $GCCE_LibGCCPath .= ' -L';
       
  3133         $GCCE_LibGCCPath .= '"'.GetGCCELibPath("-print-libgcc-file-name").'"';
       
  3134 		$linkCommand .= $GCCE_LibGCCPath;
       
  3135 		$linkCommand .=	' ${var:COMMON_LINK_FLAGS}';
       
  3136 		$linkCommand .= ' --target1-abs --no-undefined -nostdlib -Ttext 0x8000 -Tdata 0x400000';
       
  3137 		$linkCommand .= ' -shared --default-symver -soname '.$LinkAs." ";
       
  3138 		
       
  3139 		if ($Bld=~/REL$/o) {
       
  3140 			$linkCommand .= ' -Map "${output}\\${output.file.name}.map"';
       
  3141 		}
       
  3142 		
       
  3143 		if ($BasicTrgType=~/^DLL$/o)
       
  3144 			{
       
  3145 			$linkCommand .= ' --entry _E32Dll -u _E32Dll';
       
  3146 			}
       
  3147 		elsif ($BasicTrgType=~/^EXE$/o)
       
  3148 			{
       
  3149 			$linkCommand .= ' --entry _E32Startup -u _E32Startup';
       
  3150 			}		
       
  3151 
       
  3152 		$linkCommand .= ' ${var:FIRST_LIB}';
       
  3153 		$linkCommand .= ' -o "${target.data}\\${output.file.name}" ${var:LINK_OBJS} ${var:LIBS}';
       
  3154 		$linkCommand .= ' -lsupc++ -lgcc'.' '.$linkeropts; 
       
  3155 		addLinkDescriptorCommand ($linkCommand, undef, undef, undef, $FirstLib);
       
  3156 		
       
  3157 		
       
  3158 		$linkCommand = 'cmd.exe /C copy "${target.data}\\${output.file.name}" "${output}\\${output.file.root}.sym"';
       
  3159 		addLinkDescriptorCommand ($linkCommand);
       
  3160 		
       
  3161 		# copy the project .def file for prep
       
  3162 		if ($DefFile and !$NoExportLibrary)
       
  3163 		{
       
  3164 			unless (&main::ExportUnfrozen)
       
  3165 			{
       
  3166         	$linkCommand = 'cmd.exe /C copy "${var:DEF_FILE}" "${target.data}\\${var:IMPORT_LIBRARY_NO_EXT}.prep.def"';
       
  3167 			addLinkDescriptorCommand ($linkCommand);
       
  3168 			}
       
  3169 		}
       
  3170 		
       
  3171 		$linkCommand  = '${var:KIT_EPOCROOT}\\epoc32\\tools\\elf2e32.exe ';		
       
  3172 		
       
  3173 		# Change - exexps are allowed data, but they look like dlls to elftran....
       
  3174 		if (&main::AllowDllData || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  3175 			$linkCommand .= ' --dlldata';
       
  3176 		}
       
  3177 
       
  3178 		if (&main::DataLinkAddress) {
       
  3179 			$linkCommand .= ' --datalinkaddress=',&main::DataLinkAddress;
       
  3180 		}
       
  3181 		if (&main::FixedProcess) {
       
  3182 			$linkCommand .=	' --fixedaddress';
       
  3183 		}
       
  3184 		
       
  3185 		$linkCommand .= ' --sid='.&main::SecureId();
       
  3186 		
       
  3187 		if (&main::HeapSize) {
       
  3188 			my %HeapSize=&main::HeapSize;
       
  3189 			$linkCommand.=' --heap '.$HeapSize{Min} .','.$HeapSize{Max};
       
  3190 		}
       
  3191 		
       
  3192 		if (&main::ProcessPriority) {
       
  3193 			$linkCommand .=	' --priority='.&main::ProcessPriority;
       
  3194 		}
       
  3195 		
       
  3196 		if (&main::StackSize) {
       
  3197 			$linkCommand .= ' --stack='.&main::StackSize;
       
  3198 		}
       
  3199 		
       
  3200 		my $i=1;
       
  3201 		foreach (@UidList) {
       
  3202 			$linkCommand .= " --uid$i=$_";
       
  3203 			$i++;
       
  3204 		}
       
  3205 		if (&main::VendorId) {
       
  3206 			$linkCommand .= ' --vid='.&main::VendorId;
       
  3207 		}
       
  3208 		
       
  3209 		$linkCommand .= ' --capability='.&main::Capability;
       
  3210 		
       
  3211 	
       
  3212 		if(($BasicTrgType=~/^DLL/ && $TrgType!~/^DLL/ ) || $TrgType=~/^EXEXP/) {
       
  3213 	 		$linkCommand .= ' --targettype='.$TrgType;
       
  3214  		}
       
  3215  		else {
       
  3216  			$linkCommand .= ' --targettype='.$BasicTrgType;
       
  3217  		}
       
  3218 		
       
  3219 		$linkCommand .= ' --output="${output}\\${output.file.name}"';
       
  3220 		
       
  3221 		my $warningMessage;
       
  3222 		if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  3223 			if ($DefFile and !$NoExportLibrary) {
       
  3224 				$linkCommand .= ' --definput="${target.data}\\${var:IMPORT_LIBRARY_NO_EXT}.prep.def"';
       
  3225 			}
       
  3226 			$linkCommand .= ' --dso=';
       
  3227 			$linkCommand .= '"${var:KIT_EPOCROOT}\\EPOC32\\RELEASE\\ARMV5\\LIB\\${var:IMPORT_LIBRARY}"';
       
  3228 				
       
  3229 			$linkCommand .= ' --defoutput=';
       
  3230 			$linkCommand .= '"${target.data}\\${var:IMPORT_LIBRARY_NO_EXT}.def"';
       
  3231 				
       
  3232 			if (&main::ExportUnfrozen) {
       
  3233 				$warningMessage = $exportUnfrozenWarningMessage;
       
  3234 				$linkCommand .= ' --unfrozen';
       
  3235 			}
       
  3236 		}
       
  3237 		
       
  3238 		$linkCommand .= ' --elfinput="${target.data}\\${output.file.name}"';
       
  3239 		$linkCommand .= ' --linkas='.$LinkAs;
       
  3240 		#Change - LIB path is hardcoded here...
       
  3241 		$linkCommand .= ' --libpath="${var:KIT_EPOCROOT}\\EPOC32\\RELEASE\\ARMV5\\LIB"';
       
  3242 		
       
  3243         if ($BasicTrgType=~/^DLL$/o && $TrgType!~/^DLL/){
       
  3244 			my $Export;
       
  3245 			my $Ordinal=1;
       
  3246 			foreach $Export (&main::Exports)
       
  3247 				{
       
  3248 				if ($Ordinal eq 1) {
       
  3249 					$linkCommand .= ' --sysdef=';
       
  3250 				}
       
  3251 				elsif ($Ordinal ne 1) {
       
  3252 					$linkCommand .= ';';
       
  3253 					}
       
  3254 					
       
  3255 				$linkCommand .= "$Export,".$Ordinal;
       
  3256 				$Ordinal++;
       
  3257 				}
       
  3258 		}
       
  3259 		
       
  3260 		addLinkDescriptorCommand ($linkCommand, undef, undef, undef, undef, $warningMessage);
       
  3261 				
       
  3262 		} # end...elsif if ($BasicTrgType=~/^(DLL|EXE)/o)
       
  3263 		
       
  3264 		# copy def file output
       
  3265 		if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  3266 			$linkCommand = 'cmd.exe /C copy  "${target.data}\\${var:IMPORT_LIBRARY_NO_EXT}.def" "${Project}\${var:IMPORT_LIBRARY_NO_EXT}.def"';
       
  3267 			addLinkDescriptorCommand($linkCommand);
       
  3268 		}
       
  3269 		
       
  3270 		# copy the import lib (dso) created
       
  3271 		if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) {
       
  3272 			if ($DefFile and !$NoExportLibrary) {
       
  3273 				$linkCommand = 'cmd.exe /C copy ${var:KIT_EPOCROOT}\\EPOC32\\RELEASE\\ARMV5\\LIB\\${var:IMPORT_LIBRARY} ${var:KIT_EPOCROOT}\\EPOC32\\RELEASE\\ARMV5\\LIB\\${output.file.root}.dso';
       
  3274 			}
       
  3275 			addLinkDescriptorCommand($linkCommand);
       
  3276 		}
       
  3277 		
       
  3278 	
       
  3279 	} # end  GCCE link stage... elsif ($Plat eq "GCCE")
       
  3280 	
       
  3281 	
       
  3282 	if ($addHeaders)
       
  3283 		{
       
  3284 		# Ideally we would do this for all targets, both UREL and UDEB.  This would,
       
  3285 		# however, be very slow - so we just do it for the first target we come to.
       
  3286 		my $cpp = &PreprocessorToUseExe();
       
  3287 		my $cppCommandLine = "$cpp.EXE -M -MG -nostdinc ";
       
  3288 		my $preInclude = "";
       
  3289 
       
  3290 		if (($Plat eq "ARMV5" || $Plat eq "ARMV5_ABIV2" || $Plat eq "ARMV5_ABIV1" || $Plat eq "GCCE" || $IsPlatCustomization) && $PrefixFile)
       
  3291 			{
       
  3292 			$preInclude = $PrefixFile;
       
  3293 			$preInclude =~ s/^.*://;
       
  3294 			}
       
  3295 		elsif($VariantFile)
       
  3296 			{	    
       
  3297 		    $preInclude = $VariantFile;
       
  3298 			}
       
  3299 
       
  3300 		$cppCommandLine .= '-include '.Path_RltToWork($preInclude).' ' if $preInclude;
       
  3301 
       
  3302 		foreach (&main::UserIncPaths, &main::SysIncPaths)
       
  3303 			{
       
  3304 			$cppCommandLine .= '-I '.&Path_Chop(&Path_RltToWork($_)).' ';
       
  3305 			}
       
  3306 
       
  3307 		foreach (@MacroList)
       
  3308 			{
       
  3309 			#ARMCC requires escaped '"', but CPP doesn't like them
       
  3310 			s/\\\"/\"/g if /^__PRODUCT_INCLUDE__/; 
       
  3311 			
       
  3312 			$cppCommandLine .= '-D'.$_.' ';
       
  3313 			}
       
  3314 		
       
  3315 		my $SourceStructRef=&main::SourceStructRef;
       
  3316 		my %localIncludes;
       
  3317 
       
  3318 		foreach my $SourceRef (@$SourceStructRef)
       
  3319 	   		{
       
  3320 			$file = Path_RltToWork(($$SourceRef{SrcPath}.$$SourceRef{CurFile}));
       
  3321 
       
  3322 			# ensure the case of the extension is what GCC expects
       
  3323 			$file =~ s/\.CPP$/.cpp/i;
       
  3324 			$file =~ s/\.C$/.c/i;
       
  3325 			$file =~ s/\.s$/.S/i;
       
  3326 
       
  3327 			open CPPPIPE,$cppCommandLine.$file." |" or die "ERROR: Can't invoke CPP.EXE\n";
       
  3328 
       
  3329 			while (<CPPPIPE>)
       
  3330 				{
       
  3331 				#convert any Unix slashes found in CPP output to DOS slashes
       
  3332 				s/\//\\/g;	
       
  3333 				while (/\.(\.\\|\\){1}\S+\.(hrh|h|inl){1}/gi)
       
  3334 					{
       
  3335 					my $file = $&;
       
  3336 					my $filePath = &main::Path_Split('Path',$file);
       
  3337 						
       
  3338 					# Ignore files that are clearly not local to the project
       
  3339 					next if ($filePath =~ /\\epoc32\\/i);
       
  3340 
       
  3341 					# Ignore files that are #included with intermediate directories -
       
  3342 					# we can't guarantee these will be on an Access Path.
       
  3343 					next if ($filePath =~ /\w+\\\.\./);
       
  3344 
       
  3345 					# Finally confirm that the file we have is definitely on an Access Path
       
  3346 					my $presentOnAccessPath = 0;
       
  3347 					foreach my $accessPath (&main::UserIncPaths, &main::SysIncPaths)
       
  3348 						{
       
  3349 						my $accessPathCompare = $accessPath;
       
  3350 						$accessPathCompare =~ s/\\/_/g;
       
  3351 
       
  3352 						my $filePathCompare = $filePath;
       
  3353 						$filePathCompare =~ s/(\.\\|\.\.\\)//g;
       
  3354 						$filePathCompare =~ s/\\/_/g;
       
  3355 
       
  3356 						$presentOnAccessPath = 1 if ($accessPathCompare =~ /$filePathCompare$/i);
       
  3357 						}
       
  3358 					next if (!$presentOnAccessPath);
       
  3359 
       
  3360 					# Maintain availability of original case of filename using a lc keyed hash
       
  3361 					my $localInclude = &main::Path_Split('Base',$file).&main::Path_Split('Ext',$file);					
       
  3362 					$localIncludes{lc ($localInclude)} = $localInclude unless (!-e $file);
       
  3363 					}
       
  3364 				}
       
  3365 			}
       
  3366 
       
  3367 		foreach my $localInclude (sort keys %localIncludes)
       
  3368 			{
       
  3369 			addFile($localIncludes{$localInclude}, "Text", 0, "", "Headers");
       
  3370 			}
       
  3371 
       
  3372 		$addHeaders = 0;
       
  3373 		}
       
  3374 
       
  3375 
       
  3376 	# Add DOCUMENT specified files that we know we can add - we only add these for one target,
       
  3377 	# as they should be identical through-out
       
  3378 
       
  3379 	if ($addDocuments)
       
  3380 		{
       
  3381 		foreach my $document (@DocList)
       
  3382 			{
       
  3383 			# Only add files as Documents if they haven't already been added to
       
  3384 			# the target (it's not possible to have duplicate entries) and if they
       
  3385 			# have an extension we know about.
       
  3386 
       
  3387 			next if (grep (/$document/i, @addedFiles));
       
  3388 
       
  3389 			my $extension = $document;
       
  3390 			$extension =~ s/^.*\.//;
       
  3391 
       
  3392 			next if (!grep (/$extension/i, @compatibleDOCUMENTExtensions));
       
  3393 			
       
  3394 			addFile($document, "Text", "", "", "Documents");
       
  3395 			}
       
  3396 
       
  3397 		$addDocuments = 0;
       
  3398 		}
       
  3399 
       
  3400 
       
  3401 	# Create the link descriptor file
       
  3402 
       
  3403 	$xmlLinkDescriptorCommandParent->addText("\n\t\t\t");
       
  3404 
       
  3405 	if ($CW_major_version >= 3)
       
  3406 		{
       
  3407 		$xmlLinkDescriptorDumpFileParent->addText("\n\t\t\t");
       
  3408 		}
       
  3409 
       
  3410 	&main::CreateExtraFile("${ExtraFilesPath}$linkDescriptorFile", $xmlLinkDescriptorDoc->toString);
       
  3411 	addFile($linkDescriptorFile, "Text", "", "", "Link");	
       
  3412 	
       
  3413 	# Apply the changed settings
       
  3414 
       
  3415 	my $settinglist = $xmlTarget->getElementsByTagName("SETTINGLIST",0)->item(0);
       
  3416 	my @settingnodes = $settinglist->getElementsByTagName("SETTING",0);
       
  3417 	foreach my $setting (@settingnodes)
       
  3418 		{
       
  3419 		my $element = $setting->getElementsByTagName("NAME",0)->item(0);
       
  3420 		my $settingname = $element->getFirstChild->getData();
       
  3421 		my $replacement = $changedsettings{$settingname};
       
  3422 		if (defined $replacement) 
       
  3423 			{
       
  3424 			if ($replacement eq "{}")
       
  3425 				{
       
  3426 				if ($settingname eq "UserSearchPaths")
       
  3427 					{
       
  3428 					&addUserSearchPaths($setting);
       
  3429 					}
       
  3430 				elsif ($settingname eq "SystemSearchPaths")
       
  3431 					{
       
  3432 					&addSystemSearchPaths($setting);
       
  3433 					}
       
  3434 				elsif ($settingname eq "UserSourceTrees")
       
  3435 					{
       
  3436 					&addSourceTrees($setting);
       
  3437 					}
       
  3438 				elsif ($settingname eq "FileList")
       
  3439 					{
       
  3440 					&addDownloadFileList($setting, @ResourceDownloadList);
       
  3441 					}
       
  3442 				}
       
  3443 			elsif ($replacement =~ /^{(.+)}(.+)$/)
       
  3444 				{					
       
  3445 				&changePathSetting($setting,$1,$2);
       
  3446 				}
       
  3447 			else
       
  3448 				{
       
  3449 				&changeValue($setting,$replacement);
       
  3450 				}
       
  3451 			}
       
  3452 		}
       
  3453 	}
       
  3454 
       
  3455 
       
  3456 sub addLinkDescriptorCommand($$;$;$;$;$;$;$;) {		
       
  3457 	my ($linkCommand, $parseStdOut, $parseStdErr, $outputParser, $firstLibProcessing,
       
  3458 	    $linkWarning, $linkInformation, @successCodes) = @_;
       
  3459 
       
  3460 	my $structIndent = "\n\t\t\t\t";
       
  3461 	my $settingIndent = "$structIndent\t";
       
  3462 	my $simpleIndent = "$settingIndent\t";
       
  3463 	my $successCodeArrayIndent = $simpleIndent;
       
  3464 	my $successCodeSimpleIndent = "$successCodeArrayIndent\t";
       
  3465 
       
  3466 	my $structElement = new XML::DOM::Element($xmlLinkDescriptorDoc,"struct");
       
  3467 	$xmlLinkDescriptorCommandParent->addText("$structIndent");
       
  3468 	$xmlLinkDescriptorCommandParent->appendChild ($structElement);
       
  3469 
       
  3470 	my $settingElementTemplate = new XML::DOM::Element($xmlLinkDescriptorDoc,"setting");
       
  3471 	$settingElementTemplate->setAttribute("uuid-alias", ".");
       
  3472 	my $simpleElementTemplate = new XML::DOM::Element($xmlLinkDescriptorDoc,"simple");
       
  3473 
       
  3474 	my $settingElement;
       
  3475 	my $simpleElement;
       
  3476 
       
  3477 	$settingElement = $settingElementTemplate->cloneNode(0);
       
  3478 	$simpleElement = $simpleElementTemplate->cloneNode(0);
       
  3479 	
       
  3480 	$settingElement->setAttribute ("entry", "linkCommand");
       
  3481 	$structElement->addText ($settingIndent);
       
  3482 	$structElement->appendChild ($settingElement);
       
  3483 
       
  3484 	$simpleElement->addText ($linkCommand);
       
  3485 
       
  3486 	$settingElement->addText ($simpleIndent);
       
  3487 	$settingElement->appendChild ($simpleElement);
       
  3488 	$settingElement->addText($settingIndent);
       
  3489 	
       
  3490 	if (defined $parseStdOut)
       
  3491 		{
       
  3492 		$settingElement = $settingElementTemplate->cloneNode(0);
       
  3493 		$simpleElement = $simpleElementTemplate->cloneNode(0);
       
  3494 
       
  3495 		$settingElement->setAttribute("entry", "parseStdOut");
       
  3496 		$simpleElement->addText($parseStdOut);
       
  3497 
       
  3498 		$structElement->addText ($settingIndent);
       
  3499 		$structElement->appendChild ($settingElement);
       
  3500 
       
  3501 		$settingElement->addText ($simpleIndent);
       
  3502 		$settingElement->appendChild ($simpleElement);
       
  3503 		$settingElement->addText($settingIndent);
       
  3504 		}
       
  3505 	
       
  3506 	if (defined $parseStdErr)
       
  3507 		{
       
  3508 		$settingElement = $settingElementTemplate->cloneNode(0);
       
  3509 		$simpleElement = $simpleElementTemplate->cloneNode(0);
       
  3510 
       
  3511 		$settingElement->setAttribute("entry", "parseStdErr");
       
  3512 		$simpleElement->addText($parseStdErr);
       
  3513 
       
  3514 		$structElement->addText ($settingIndent);
       
  3515 		$structElement->appendChild ($settingElement);
       
  3516 
       
  3517 		$settingElement->addText ($simpleIndent);
       
  3518 		$settingElement->appendChild ($simpleElement);
       
  3519 		$settingElement->addText($settingIndent);
       
  3520 		}
       
  3521 
       
  3522 	if (defined $outputParser)
       
  3523 		{
       
  3524 		$settingElement = $settingElementTemplate->cloneNode(0);
       
  3525 		$simpleElement = $simpleElementTemplate->cloneNode(0);
       
  3526 
       
  3527 		$settingElement->setAttribute("entry", "outputParser");
       
  3528 		$simpleElement->addText($outputParser);
       
  3529 
       
  3530 		$structElement->addText ($settingIndent);
       
  3531 		$structElement->appendChild ($settingElement);
       
  3532 
       
  3533 		$settingElement->addText ($simpleIndent);
       
  3534 		$settingElement->appendChild ($simpleElement);
       
  3535 		$settingElement->addText($settingIndent);
       
  3536 		}
       
  3537 
       
  3538 	if (defined $firstLibProcessing)
       
  3539 		{
       
  3540 		$settingElement = $settingElementTemplate->cloneNode(0);
       
  3541 		$simpleElement = $simpleElementTemplate->cloneNode(0);
       
  3542 
       
  3543 		$settingElement->setAttribute("entry", "firstLibProcessing");
       
  3544 		$simpleElement->addText($firstLibProcessing);
       
  3545 
       
  3546 		$structElement->addText ($settingIndent);
       
  3547 		$structElement->appendChild ($settingElement);
       
  3548 
       
  3549 		$settingElement->addText ($simpleIndent);
       
  3550 		$settingElement->appendChild ($simpleElement);
       
  3551 		$settingElement->addText($settingIndent);
       
  3552 		}
       
  3553 
       
  3554 	if (defined $linkWarning)
       
  3555 		{
       
  3556 		$settingElement = $settingElementTemplate->cloneNode(0);
       
  3557 		$simpleElement = $simpleElementTemplate->cloneNode(0);
       
  3558 
       
  3559 		$settingElement->setAttribute("entry", "linkWarning");
       
  3560 		$simpleElement->addText($linkWarning);
       
  3561 
       
  3562 		$structElement->addText ($settingIndent);
       
  3563 		$structElement->appendChild ($settingElement);
       
  3564 
       
  3565 		$settingElement->addText ($simpleIndent);
       
  3566 		$settingElement->appendChild ($simpleElement);
       
  3567 		$settingElement->addText($settingIndent);
       
  3568 		}
       
  3569 
       
  3570 	if (defined $linkInformation)
       
  3571 		{
       
  3572 		$settingElement = $settingElementTemplate->cloneNode(0);
       
  3573 		$simpleElement = $simpleElementTemplate->cloneNode(0);
       
  3574 
       
  3575 		$settingElement->setAttribute("entry", "linkInformation");
       
  3576 		$simpleElement->addText($linkInformation);
       
  3577 
       
  3578 		$structElement->addText ($settingIndent);
       
  3579 		$structElement->appendChild ($settingElement);
       
  3580 
       
  3581 		$settingElement->addText ($simpleIndent);
       
  3582 		$settingElement->appendChild ($simpleElement);
       
  3583 		$settingElement->addText($settingIndent);
       
  3584 		}
       
  3585 
       
  3586 	if (@successCodes)
       
  3587 		{
       
  3588 		$settingElement = $settingElementTemplate->cloneNode(0);
       
  3589 		$settingElement->setAttribute("entry", "successCodes");
       
  3590 
       
  3591 		my $arrayElement = new XML::DOM::Element($xmlLinkDescriptorDoc,"array");
       
  3592 		$arrayElement->setAttribute("inheritance", "none");
       
  3593 		
       
  3594 		foreach my $successCode (@successCodes)
       
  3595 			{
       
  3596 			$simpleElement = $simpleElementTemplate->cloneNode(0);
       
  3597 			$simpleElement->addText($successCode);
       
  3598 			$arrayElement->addText ($successCodeSimpleIndent);
       
  3599 			$arrayElement->appendChild ($simpleElement);
       
  3600 			}
       
  3601 
       
  3602 		$arrayElement->addText ($successCodeArrayIndent);
       
  3603 
       
  3604 		$settingElement->addText ($successCodeArrayIndent);
       
  3605 		$settingElement->appendChild ($arrayElement);
       
  3606 		$settingElement->addText($settingIndent);
       
  3607 
       
  3608 		$structElement->addText ($settingIndent);
       
  3609 		$structElement->appendChild ($settingElement);
       
  3610 		}
       
  3611 
       
  3612 	$structElement->addText($structIndent);
       
  3613 }
       
  3614 
       
  3615 
       
  3616 sub addLinkDescriptorSymbol ($$) {
       
  3617 	my ($symbolName, $symbolValue) = @_;
       
  3618 	
       
  3619 	my $structIndent = "\n\t\t\t\t";
       
  3620 	my $settingIndent = "$structIndent\t";
       
  3621 	my $simpleIndent = "$settingIndent\t";
       
  3622 
       
  3623 	my $structElement = new XML::DOM::Element($xmlLinkDescriptorDoc,"struct");
       
  3624 	$xmlLinkDescriptorSymbolParent->addText("$structIndent");
       
  3625 	$xmlLinkDescriptorSymbolParent->appendChild ($structElement);
       
  3626 
       
  3627 	my $settingElementTemplate = new XML::DOM::Element($xmlLinkDescriptorDoc,"setting");
       
  3628 	$settingElementTemplate->setAttribute("uuid-alias", ".");
       
  3629 	my $simpleElementTemplate = new XML::DOM::Element($xmlLinkDescriptorDoc,"simple");
       
  3630 
       
  3631 	my $symbolNameSettingElement;
       
  3632 	my $symbolNameSimpleElement;
       
  3633 	my $symbolValueSettingElement;
       
  3634 	my $symbolValueSimpleElement;
       
  3635 
       
  3636 	$symbolNameSettingElement = $settingElementTemplate->cloneNode(0);
       
  3637 	$symbolNameSimpleElement = $simpleElementTemplate->cloneNode(0);
       
  3638 	$symbolValueSettingElement = $settingElementTemplate->cloneNode(0);
       
  3639 	$symbolValueSimpleElement = $simpleElementTemplate->cloneNode(0);
       
  3640 
       
  3641 	$symbolNameSettingElement->setAttribute("entry", "symbolName");
       
  3642 	$symbolNameSimpleElement->addText ($symbolName);
       
  3643 	$symbolValueSettingElement->setAttribute("entry", "symbolValue");
       
  3644 	$symbolValueSimpleElement->addText ($symbolValue);
       
  3645 
       
  3646 	$symbolNameSettingElement->addText ($simpleIndent);
       
  3647 	$symbolNameSettingElement->appendChild ($symbolNameSimpleElement);
       
  3648 	$symbolNameSettingElement->addText($settingIndent);
       
  3649 	$symbolValueSettingElement->addText ($simpleIndent);
       
  3650 	$symbolValueSettingElement->appendChild ($symbolValueSimpleElement);
       
  3651 	$symbolValueSettingElement->addText ($settingIndent);
       
  3652 
       
  3653 	$structElement->addText ($settingIndent);
       
  3654 	$structElement->appendChild ($symbolNameSettingElement);
       
  3655 	$structElement->addText ($settingIndent);
       
  3656 	$structElement->appendChild ($symbolValueSettingElement);
       
  3657 	$structElement->addText ($structIndent);
       
  3658 	}
       
  3659 
       
  3660 
       
  3661 sub addLinkDescriptorDumpFile ($$) {
       
  3662 	my ($dumpFileContent, $dumpFileName) = @_;
       
  3663 	
       
  3664 	my $structIndent = "\n\t\t\t\t";
       
  3665 	my $settingIndent = "$structIndent\t";
       
  3666 	my $simpleIndent = "$settingIndent\t";
       
  3667 
       
  3668 	my $structElement = new XML::DOM::Element($xmlLinkDescriptorDoc,"struct");
       
  3669 	$xmlLinkDescriptorDumpFileParent->addText("$structIndent");
       
  3670 	$xmlLinkDescriptorDumpFileParent->appendChild ($structElement);
       
  3671 
       
  3672 	my $settingElementTemplate = new XML::DOM::Element($xmlLinkDescriptorDoc,"setting");
       
  3673 	$settingElementTemplate->setAttribute("uuid-alias", ".");
       
  3674 	my $simpleElementTemplate = new XML::DOM::Element($xmlLinkDescriptorDoc,"simple");
       
  3675 
       
  3676 	my $dumpFileContentSettingElement;
       
  3677 	my $dumpFileContentSimpleElement;
       
  3678 	my $dumpFileNameSettingElement;
       
  3679 	my $dumpFileNameSimpleElement;
       
  3680 
       
  3681 	$dumpFileContentSettingElement = $settingElementTemplate->cloneNode(0);
       
  3682 	$dumpFileContentSimpleElement = $simpleElementTemplate->cloneNode(0);
       
  3683 	$dumpFileNameSettingElement = $settingElementTemplate->cloneNode(0);
       
  3684 	$dumpFileNameSimpleElement = $simpleElementTemplate->cloneNode(0);
       
  3685 
       
  3686 	$dumpFileContentSettingElement->setAttribute("entry", "dumpFileContent");
       
  3687 	$dumpFileContentSimpleElement->addText ($dumpFileContent);
       
  3688 	$dumpFileNameSettingElement->setAttribute("entry", "dumpFileName");
       
  3689 	$dumpFileNameSimpleElement->addText ($dumpFileName);
       
  3690 
       
  3691 	$dumpFileContentSettingElement->addText ($simpleIndent);
       
  3692 	$dumpFileContentSettingElement->appendChild ($dumpFileContentSimpleElement);
       
  3693 	$dumpFileContentSettingElement->addText($settingIndent);
       
  3694 	$dumpFileNameSettingElement->addText ($simpleIndent);
       
  3695 	$dumpFileNameSettingElement->appendChild ($dumpFileNameSimpleElement);
       
  3696 	$dumpFileNameSettingElement->addText ($settingIndent);
       
  3697 
       
  3698 	$structElement->addText ($settingIndent);
       
  3699 	$structElement->appendChild ($dumpFileContentSettingElement);
       
  3700 	$structElement->addText ($settingIndent);
       
  3701 	$structElement->appendChild ($dumpFileNameSettingElement);
       
  3702 	$structElement->addText ($structIndent);
       
  3703 	}
       
  3704 
       
  3705 
       
  3706 sub ExtraPlat($) {
       
  3707 
       
  3708 # Call PmBld again after reprocessing the MMP file and tweaking various main:: variables
       
  3709 
       
  3710 	my ($Plat) = @_;
       
  3711 	
       
  3712 	&main::SetVarsFromMmp($Plat);
       
  3713 	&main::InitLinkPaths();
       
  3714 
       
  3715 	foreach (&main::BldList) {
       
  3716 		&main::SetCurBld($_);
       
  3717 		&PMPlatProcessMmp(&main::PlatTxt2D);
       
  3718 		&PMStartBldList;
       
  3719 		&PMBld;
       
  3720 	}
       
  3721 
       
  3722 }
       
  3723 
       
  3724 sub disconnectNode($) {
       
  3725 
       
  3726 # Remove a node from its parent, also removing the following text node (if any)
       
  3727 # The text node is assumed to contain whitespace for file formatting.
       
  3728  
       
  3729 	my ($node)=@_;
       
  3730 
       
  3731 	my $parent = $node->getParentNode;
       
  3732 	my $sibling = $node->getNextSibling;
       
  3733 	$parent->removeChild($node);
       
  3734 	if (defined $sibling && $sibling->getNodeType == TEXT_NODE)
       
  3735 		{
       
  3736 		$parent->removeChild($sibling);
       
  3737 		}
       
  3738 	return $node;
       
  3739 }
       
  3740 
       
  3741 sub removeNode($) {
       
  3742 
       
  3743 # disconnect the node and dispose of it
       
  3744 
       
  3745 	my ($node) = @_;
       
  3746 	&disconnectNode($node);
       
  3747 	$node->dispose;		# setAttribute("disposed",1);
       
  3748 }
       
  3749 
       
  3750 sub textElement($$$$) {
       
  3751 	my ($element,$name,$value,$insertionpoint)=@_;
       
  3752 
       
  3753 	my $subElement = new XML::DOM::Element($xmlProjectDoc,$name);
       
  3754 	$subElement->appendChild($xmlProjectDoc->createTextNode($value));
       
  3755 	$element->insertBefore($subElement, $insertionpoint);
       
  3756 }
       
  3757 
       
  3758 sub addFile($$$$;$) {    
       
  3759 
       
  3760 	my ($src, $kind, $debug, $shared, $group) = @_;
       
  3761 
       
  3762 	my $linkElement = new XML::DOM::Element($xmlProjectDoc,"FILEREF");
       
  3763 
       
  3764 	&textElement($linkElement, "PATHTYPE",   "Name");
       
  3765 	&textElement($linkElement, "PATH",       $src);
       
  3766 	&textElement($linkElement, "PATHFORMAT", "Windows");
       
  3767 
       
  3768 	my $fileElement = $linkElement->cloneNode(1);
       
  3769 	$fileElement->setTagName("FILE");
       
  3770 	&textElement($fileElement, "FILEKIND",   $kind);
       
  3771 	&textElement($fileElement, "FILEFLAGS",  "Debug") if ($debug);
       
  3772 
       
  3773 	$xmlLinkOrder->appendChild($linkElement);
       
  3774 	$xmlFileList->appendChild($fileElement);
       
  3775 
       
  3776 	$xmlLinkOrder->addText("\n");
       
  3777 	$xmlFileList->addText("\n");
       
  3778 
       
  3779 	# Accumulate source group information
       
  3780 
       
  3781 	my $groupfile = $linkElement->cloneNode(1);
       
  3782 	$groupfile->setAttribute("NAME", "$shared$src");			# convenience - remove this later!
       
  3783 
       
  3784 	push (@addedFiles, $src) unless ($kind eq "Documents");
       
  3785 
       
  3786 	if ($kind eq "Library")
       
  3787 		{
       
  3788 		$xmlLibGroup->appendChild($groupfile);
       
  3789 		$xmlLibGroup->addText("\n");
       
  3790 		}
       
  3791 	elsif (defined $group)
       
  3792 		{
       
  3793 		if ($group eq "Link")
       
  3794 			{
       
  3795 			$xmlLinkGroup->appendChild($groupfile);
       
  3796 			$xmlLinkGroup->addText("\n");
       
  3797 			}
       
  3798 		elsif ($group eq "Resources")
       
  3799 			{
       
  3800 			$xmlResourcesGroup->appendChild($groupfile);
       
  3801 			$xmlResourcesGroup->addText("\n");
       
  3802 			}
       
  3803 		elsif ($group eq "Root")
       
  3804 			{
       
  3805 			$xmlRootGroup->appendChild($groupfile);
       
  3806 			$xmlRootGroup->addText("\n");
       
  3807 			}
       
  3808 		elsif ($group eq "Headers")
       
  3809 			{
       
  3810 			$xmlHeadersGroup->appendChild($groupfile);
       
  3811 			$xmlHeadersGroup->addText("\n");
       
  3812 			}
       
  3813 		elsif ($group eq "Documents")
       
  3814 			{
       
  3815 			$xmlDocumentsGroup->appendChild($groupfile);
       
  3816 			$xmlDocumentsGroup->addText("\n");
       
  3817 			}
       
  3818 		}
       
  3819 	else
       
  3820 		{
       
  3821 		$xmlSourceGroup->appendChild($groupfile);
       
  3822 		$xmlSourceGroup->addText("\n");
       
  3823 		}
       
  3824 }
       
  3825 
       
  3826 sub addGroup($$) {
       
  3827 	my ($grouplist,$name)=@_;
       
  3828 
       
  3829 	my $group = new XML::DOM::Element($xmlProjectDoc,"GROUP");
       
  3830 	$grouplist->appendChild($group);
       
  3831 	$grouplist->addText("\n");
       
  3832 
       
  3833 	&textElement($group, "NAME", $name);
       
  3834 	$group->addText("\n");
       
  3835 	return $group;
       
  3836 }
       
  3837 
       
  3838 sub addSubTarget($$) {
       
  3839 	my ($subtargetlist,$name)=@_;
       
  3840 
       
  3841 	my $subtarget = new XML::DOM::Element($xmlProjectDoc,"SUBTARGET");
       
  3842 	$subtargetlist->appendChild($subtarget);
       
  3843 	$subtargetlist->addText("\n");
       
  3844 
       
  3845 	&textElement($subtarget, "TARGETNAME", $name);
       
  3846 }
       
  3847 
       
  3848 sub addOrderedTarget($$) {
       
  3849 	my ($targetorder,$name)=@_;
       
  3850 
       
  3851 	my $orderedtarget = new XML::DOM::Element($xmlProjectDoc,"ORDEREDTARGET");
       
  3852 	$targetorder->appendChild($orderedtarget);
       
  3853 	$targetorder->addText("\n");
       
  3854 
       
  3855 	&textElement($orderedtarget, "NAME", $name);
       
  3856 }
       
  3857 
       
  3858 sub finaliseProject {
       
  3859 
       
  3860 	# Run through the project, removing all unused targets
       
  3861 	# and build up the TARGETORDER list and the "Build All" target
       
  3862 
       
  3863 	my $target;
       
  3864 	my $targetname;
       
  3865 
       
  3866 	my $xmlSubTargetList = new XML::DOM::Element($xmlProjectDoc,"SUBTARGETLIST");
       
  3867 
       
  3868 	my $xmlTargetOrder = new XML::DOM::Element($xmlProjectDoc,"TARGETORDER");
       
  3869 	$xmlTargetOrder->addText("\n");
       
  3870 
       
  3871 	my @targets = $xmlProjectDoc->getElementsByTagName("TARGET",1);
       
  3872 	my @emulatortargetnames;
       
  3873 	my @othertargetnames;
       
  3874 	
       
  3875 	foreach $target (@targets)
       
  3876 		{			
       
  3877 		$targetname = $target->getAttribute("NAME");
       
  3878 
       
  3879 		if ($targetname eq "")
       
  3880 			{
       
  3881 			&removeNode($target);
       
  3882 			}
       
  3883 		else
       
  3884 			{
       
  3885 			$target->removeAttribute("NAME");
       
  3886 
       
  3887 			if ($targetname =~ /^WINSCW/)
       
  3888 				{
       
  3889 				push (@emulatortargetnames, $targetname);
       
  3890 				}
       
  3891 			else
       
  3892 				{
       
  3893 				push (@othertargetnames, $targetname);
       
  3894 				}
       
  3895 			}
       
  3896 		}
       
  3897 
       
  3898 	foreach $targetname ((sort @emulatortargetnames), (sort @othertargetnames))
       
  3899 		{
       
  3900 		&addSubTarget($xmlSubTargetList, $targetname);
       
  3901 		&addOrderedTarget($xmlTargetOrder, $targetname);
       
  3902 		}
       
  3903 
       
  3904 	# Build the GROUPLIST
       
  3905 	
       
  3906 	my $xmlGroupList = new XML::DOM::Element($xmlProjectDoc,"GROUPLIST");
       
  3907 
       
  3908 	# Build the "Root" group
       
  3909 
       
  3910 	my %rootfiles;
       
  3911 	my @rootgroups = $xmlProjectDoc->getElementsByTagName("ROOTGROUP",1);
       
  3912 	foreach my $group (@rootgroups)
       
  3913 		{
       
  3914 		$targetname = $group->getAttribute("TARGET");
       
  3915 
       
  3916 		my @files = $group->getElementsByTagName("FILEREF",0);
       
  3917 		foreach my $file (@files)
       
  3918 			{
       
  3919 			my $name = $file->getAttribute("NAME");
       
  3920 			if (!defined $rootfiles{$name})
       
  3921 				{
       
  3922 				# first occurrence - add to list
       
  3923 				$rootfiles{$name}=1;
       
  3924 				&textElement($file, "TARGETNAME", $targetname, $file->getFirstChild);
       
  3925 				$file->removeAttribute("NAME");
       
  3926 				&disconnectNode($file);					
       
  3927 				$xmlGroupList->appendChild($file);
       
  3928 				$xmlGroupList->addText("\n");
       
  3929 				}
       
  3930 			}
       
  3931 		&removeNode($group);
       
  3932 		}
       
  3933 
       
  3934 	# Build the "Source" group
       
  3935 
       
  3936 	my $xmlSourceGroup = &addGroup($xmlGroupList,"Source");
       
  3937 	my %sourcefiles;
       
  3938 	my @sourcegroups = $xmlProjectDoc->getElementsByTagName("SOURCEGROUP",1);
       
  3939 	foreach my $group (@sourcegroups)
       
  3940 		{
       
  3941 		$targetname = $group->getAttribute("TARGET");
       
  3942 		my @files = $group->getElementsByTagName("FILEREF",0);
       
  3943 		foreach my $file (@files)
       
  3944 			{
       
  3945 			my $name = $file->getAttribute("NAME");
       
  3946 			if (!defined $sourcefiles{$name})
       
  3947 				{
       
  3948 				# first occurrence - add to list
       
  3949 				$sourcefiles{$name}=1;
       
  3950 				&textElement($file, "TARGETNAME", $targetname, $file->getFirstChild);
       
  3951 				$file->removeAttribute("NAME");
       
  3952 				&disconnectNode($file);
       
  3953 				$xmlSourceGroup->appendChild($file);
       
  3954 				$xmlSourceGroup->addText("\n");
       
  3955 				}
       
  3956 			}
       
  3957 		&removeNode($group);
       
  3958 		}
       
  3959 
       
  3960 
       
  3961 	# Build the "Headers" group
       
  3962 			
       
  3963 	my $xmlHeadersGroup;
       
  3964 	my %headerfiles;
       
  3965 	my @headersgroups = $xmlProjectDoc->getElementsByTagName("HEADERSGROUP",1);
       
  3966 	foreach my $group (@headersgroups)
       
  3967 		{
       
  3968 		$targetname = $group->getAttribute("TARGET");
       
  3969 		my @files = $group->getElementsByTagName("FILEREF",0);
       
  3970 		foreach my $file (@files)
       
  3971 			{
       
  3972 			# Only create the "Headers" group if there are some files to add to it
       
  3973 			if (!defined $xmlHeadersGroup)
       
  3974 				{
       
  3975 				$xmlHeadersGroup = &addGroup($xmlGroupList,"Headers");
       
  3976 				}
       
  3977 				
       
  3978 			my $name = $file->getAttribute("NAME");
       
  3979 			if (!defined $headerfiles{$name})
       
  3980 				{
       
  3981 				# first occurrence - add to list
       
  3982 				$headerfiles{$name}=1;
       
  3983 				&textElement($file, "TARGETNAME", $targetname, $file->getFirstChild);
       
  3984 				$file->removeAttribute("NAME");
       
  3985 				&disconnectNode($file);
       
  3986 				$xmlHeadersGroup->appendChild($file);
       
  3987 				$xmlHeadersGroup->addText("\n");
       
  3988 				}
       
  3989 			}
       
  3990 		&removeNode($group);
       
  3991 		}
       
  3992 
       
  3993 
       
  3994 	# Build the "Resources" group
       
  3995 			
       
  3996 	my $xmlResourcesGroup;
       
  3997 	my %resourcesfiles;
       
  3998 	my @resourcesgroups = $xmlProjectDoc->getElementsByTagName("RESOURCESGROUP",1);
       
  3999 	foreach my $group (@resourcesgroups)
       
  4000 		{
       
  4001 		$targetname = $group->getAttribute("TARGET");
       
  4002 		my @files = $group->getElementsByTagName("FILEREF",0);
       
  4003 		foreach my $file (@files)
       
  4004 			{
       
  4005 			# Only create the main "Resources" groups if there are some files to add
       
  4006 			# to them
       
  4007 			if (!defined $xmlResourcesGroup)
       
  4008 				{
       
  4009 				$xmlResourcesGroup = &addGroup($xmlGroupList,"Resources");
       
  4010 				}
       
  4011 				
       
  4012 			my $name = $file->getAttribute("NAME");
       
  4013 			if (!defined $resourcesfiles{$name})
       
  4014 				{
       
  4015 				# first occurrence - add to list
       
  4016 				$resourcesfiles{$name}=1;
       
  4017 				&textElement($file, "TARGETNAME", $targetname, $file->getFirstChild);
       
  4018 				$file->removeAttribute("NAME");
       
  4019 				&disconnectNode($file);
       
  4020 
       
  4021 				$xmlResourcesGroup->appendChild($file);
       
  4022 				$xmlResourcesGroup->addText("\n");
       
  4023 				}
       
  4024 			}
       
  4025 		&removeNode($group);
       
  4026 		}
       
  4027 
       
  4028 		
       
  4029 	# Build the "Link" group
       
  4030 			
       
  4031 	my $xmlLinkGroup = &addGroup($xmlGroupList,"Link");
       
  4032 	my %linkfiles;
       
  4033 	my @linkgroups = $xmlProjectDoc->getElementsByTagName("LINKGROUP",1);
       
  4034 	foreach my $group (@linkgroups)
       
  4035 		{
       
  4036 		$targetname = $group->getAttribute("TARGET");
       
  4037 		my @files = $group->getElementsByTagName("FILEREF",0);
       
  4038 		foreach my $file (@files)
       
  4039 			{
       
  4040 			my $name = $file->getAttribute("NAME");
       
  4041 			if (!defined $linkfiles{$name})
       
  4042 				{
       
  4043 				# first occurrence - add to list
       
  4044 				$linkfiles{$name}=1;
       
  4045 				&textElement($file, "TARGETNAME", $targetname, $file->getFirstChild);
       
  4046 				$file->removeAttribute("NAME");
       
  4047 				&disconnectNode($file);
       
  4048 				$xmlLinkGroup->appendChild($file);
       
  4049 				$xmlLinkGroup->addText("\n");
       
  4050 				}
       
  4051 			}
       
  4052 		&removeNode($group);
       
  4053 		}
       
  4054 
       
  4055 
       
  4056 	# Build the "Documents" group
       
  4057 			
       
  4058 	my $xmlDocumentsGroup;
       
  4059 	my %documentfiles;
       
  4060 	my @documentgroups = $xmlProjectDoc->getElementsByTagName("DOCUMENTSGROUP",1);
       
  4061 	foreach my $group (@documentgroups)
       
  4062 		{
       
  4063 		$targetname = $group->getAttribute("TARGET");
       
  4064 		my @files = $group->getElementsByTagName("FILEREF",0);
       
  4065 		foreach my $file (@files)
       
  4066 			{				
       
  4067 			# Only create the "Documents" group if there are some files to add to it
       
  4068 			if (!defined $xmlDocumentsGroup)
       
  4069 				{
       
  4070 				$xmlDocumentsGroup = &addGroup($xmlGroupList,"Documents");
       
  4071 				}
       
  4072 
       
  4073 			my $name = $file->getAttribute("NAME");
       
  4074 
       
  4075 			
       
  4076 			if (!defined $documentfiles{$name})
       
  4077 				{
       
  4078 				# first occurrence - add to list
       
  4079 				$documentfiles{$name}=1;
       
  4080 				&textElement($file, "TARGETNAME", $targetname, $file->getFirstChild);
       
  4081 				$file->removeAttribute("NAME");
       
  4082 				&disconnectNode($file);
       
  4083 				$xmlDocumentsGroup->appendChild($file);
       
  4084 				$xmlDocumentsGroup->addText("\n");
       
  4085 				}
       
  4086 			}
       
  4087 		&removeNode($group);
       
  4088 		}
       
  4089 
       
  4090 
       
  4091 	# Build the "Lib" group and its subgroups
       
  4092 
       
  4093 	my $xmlLibGroup = &addGroup($xmlGroupList, "Libraries");
       
  4094 	my %libplats;
       
  4095 	my @libgroups = $xmlProjectDoc->getElementsByTagName("LIBGROUP",1);
       
  4096 	foreach my $group (@libgroups)
       
  4097 		{
       
  4098 		$targetname = $group->getAttribute("TARGET");
       
  4099 		my $plat = $group->getAttribute("PLAT");
       
  4100 		if (!defined $libplats{$plat})
       
  4101 			{
       
  4102 			$libplats{$plat} = &addGroup($xmlLibGroup, $plat);
       
  4103 			}
       
  4104 		my $platgroup = $libplats{$plat};
       
  4105 		my @files = $group->getElementsByTagName("FILEREF",0);
       
  4106 		foreach my $file (@files)
       
  4107 			{
       
  4108 			my $name = $file->getAttribute("NAME");
       
  4109 			if (!defined $sourcefiles{"$plat\\$name"})
       
  4110 				{
       
  4111 				# first occurrence - add to list
       
  4112 				$sourcefiles{"$plat\\$name"}=1;
       
  4113 				&textElement($file, "TARGETNAME", $targetname, $file->getFirstChild);
       
  4114 				$file->removeAttribute("NAME");
       
  4115 				&disconnectNode($file);
       
  4116 				$platgroup->appendChild($file);
       
  4117 				$platgroup->addText("\n");
       
  4118 				}
       
  4119 			}
       
  4120 		&removeNode($group);
       
  4121 		}
       
  4122 
       
  4123 	# Replace the GROUPLIST & TARGETORDER in the template document
       
  4124 
       
  4125 	my $node = $xmlProjectDoc->getElementsByTagName("GROUPLIST",1)->item(0);
       
  4126 	$node->getParentNode->replaceChild($xmlGroupList, $node);
       
  4127 
       
  4128 	$node = $xmlProjectDoc->getElementsByTagName("TARGETORDER",1)->item(0);
       
  4129 	$node->getParentNode->replaceChild($xmlTargetOrder, $node);
       
  4130 
       
  4131 	# Insert the "Build All" target
       
  4132 
       
  4133 	my $xmlBuildAll = new XML::DOM::Element($xmlProjectDoc,"TARGET");
       
  4134 	$xmlBuildAll->addText("\n");
       
  4135 	&textElement($xmlBuildAll, "NAME", "Build All");
       
  4136 	my $settinglist = new XML::DOM::Element($xmlProjectDoc,"SETTINGLIST");
       
  4137 	&textSetting($settinglist, "Linker", "None");
       
  4138 	&textSetting($settinglist, "Targetname", "Build All");
       
  4139 	$xmlBuildAll->appendChild($settinglist);
       
  4140 	$xmlBuildAll->addText("\n");
       
  4141 	&textElement($xmlBuildAll, "FILELIST", "");
       
  4142 	$xmlBuildAll->addText("\n");
       
  4143 	&textElement($xmlBuildAll, "LINKORDER", "");
       
  4144 	$xmlBuildAll->addText("\n");
       
  4145 	$xmlBuildAll->appendChild($xmlSubTargetList);
       
  4146 
       
  4147 	&addOrderedTarget($xmlTargetOrder, "Build All");
       
  4148 
       
  4149 	$node = $xmlProjectDoc->getElementsByTagName("TARGETLIST",1)->item(0);
       
  4150 	$node->appendChild($xmlBuildAll);
       
  4151 
       
  4152 	# Output the result
       
  4153 
       
  4154 	&main::Output(
       
  4155 		$xmlProjectDoc->toString
       
  4156 	);
       
  4157 
       
  4158 }
       
  4159 
       
  4160 sub PMEndSrcList {
       
  4161 
       
  4162 	my @PlatList=&main::PlatOverrideList();
       
  4163 	
       
  4164 	if (scalar @PlatList == 0)
       
  4165 		{
       
  4166 		@PlatList = ("WINSCW", "ARM4", "ARMV5");
       
  4167 
       
  4168 		if ($CW_major_version >= 3)
       
  4169 			{
       
  4170 			push @PlatList, "ARMV5_ABIV1";
       
  4171 			}
       
  4172 		}
       
  4173 
       
  4174 	shift @PlatList;	# we've already done the first one in the list
       
  4175 	foreach (@PlatList)
       
  4176 		{
       
  4177 		ExtraPlat($_);
       
  4178 		}
       
  4179 
       
  4180 	&finaliseProject();
       
  4181 
       
  4182 }
       
  4183 
       
  4184 sub GetGCCELibPath($) {
       
  4185 	my $gnulibgccPath;
       
  4186 	open PIPE, "arm-none-symbianelf-g++ $_[0] 2>&1 | ";
       
  4187 	while(<PIPE>){
       
  4188 		$gnulibgccPath = $_;
       
  4189 		$gnulibgccPath =~ s/\//\\/g;
       
  4190 	}
       
  4191 	close PIPE;
       
  4192 	my $SearchlibgccDir = &main::Path_Chop(&main::Path_Split('Path', $gnulibgccPath));
       
  4193 
       
  4194 	return $SearchlibgccDir;
       
  4195 }
       
  4196 
       
  4197 sub Read_BSF_Options() {
       
  4198         my %plat = (main::PlatRec());
       
  4199 		my @Customization_Data = split(/\n/,$plat{'CUSTOMIZATION_DATA'});
       
  4200 	foreach my $option (@Customization_Data) {
       
  4201 			next if ($option =~ /^$/);
       
  4202 	        warn "Unrecognized BSF syntax: $option.\n"
       
  4203 		        unless ($option =~ /\s*(\S+)\s+(.+)$/);
       
  4204 		my $key = uc $1;
       
  4205 		my $val = $2;
       
  4206 	        warn "Unrecognized BSF keyword: $key.\n"
       
  4207 		        unless ($BSF_keywords{$key});
       
  4208 		if ($key =~ /COMMON_OPTIONS/) {
       
  4209 		        push @commonOptions, $val;
       
  4210 			next;
       
  4211 		}
       
  4212 		if ($key =~ /THUMB_OPTIONS/) {
       
  4213 		        push @thumbOptions, $val;
       
  4214 			next;
       
  4215 		}
       
  4216 		if ($key =~ /ARM_OPTIONS/) {
       
  4217 		        push @armOptions, $val;
       
  4218 			next;
       
  4219 		}
       
  4220 		if ($key =~ /KERNEL_OPTIONS/) {
       
  4221 		        push @kernelOptions, $val;
       
  4222 			next;
       
  4223 		}
       
  4224 		if ($key =~ /INVARIANT_OPTIONS/) {
       
  4225 		        push @invariantOptions, $val;
       
  4226 			next;
       
  4227 		}
       
  4228 		if ($key =~ /LD_OPTIONS/) {
       
  4229 		        push @linkerOptions, $val;
       
  4230 			next;
       
  4231 		}
       
  4232 		if ($key =~ /AR_OPTIONS/) {
       
  4233 		        push @archiverOptions, $val;
       
  4234 			next;
       
  4235 		}
       
  4236 
       
  4237 	}
       
  4238 }
       
  4239 
       
  4240 # Set the options passed from BSF file 
       
  4241 # @param OptionName    - BSF Keyword using which the options would be overridden in the BSF file
       
  4242 # @param Options       - List of options read from the BSF keyword
       
  4243 sub Set_BSF_Options($$)
       
  4244 {
       
  4245 	my ($OptionName,$Options) = @_;
       
  4246 	my @Fragments=();
       
  4247 	
       
  4248 	if ($CustPlat{'CUSTOMIZES'} && ($CustPlat{'ROOTPLATNAME'} eq "GCCE"))
       
  4249 	{
       
  4250 		$CustGCCE=1;
       
  4251 	}
       
  4252 	foreach my $val (@{$Options})
       
  4253 	{		
       
  4254 		# Check if the value of BSF option is to be set or added/removed.
       
  4255 		if($val =~ /\+\[.*\]\+|\-\[.*\]\-/)
       
  4256 		{
       
  4257 			if (@Fragments = Cl_bpabi::Split_BSF_Options($val,'RemoveOptions'))
       
  4258 			{
       
  4259 				foreach my $Opt (@Fragments) 
       
  4260 				{
       
  4261 					# Remove trailing white spaces
       
  4262 					$Opt =~ s/\s+$//;
       
  4263 					# Substitute '=' with '%' which is a wild card character in makefile.
       
  4264 					# This is required for cases where option to be removed contains '=' (e.g.'-march=armv5t').
       
  4265 					# When such options are to be removed, "$(INVARIANT_OPTIONS:-march=armv5t=)" is written in the makefile.
       
  4266 					# However, because of the occurence of '=', pattern match fails in the makefile and such options are not removed. 
       
  4267 					# To resolve this, '=' is replaced with '%'  in the makefile so that the substitution pattern looks like 
       
  4268 					# "$(INVARIANT_OPTIONS:-march%armv5t=)" in makefile (e.g."$(INVARIANT_OPTIONS:-march%armv5t=)").
       
  4269 					$Opt =~ s/=/%/;
       
  4270 					if((($OptionName =~ /COMMON_OPTIONS/)
       
  4271 					|| ($OptionName =~ /THUMB_OPTIONS/)
       
  4272 					|| ($OptionName =~ /ARM_OPTIONS/)
       
  4273 					|| ($OptionName =~ /KERNEL_OPTIONS/)
       
  4274 					|| ($OptionName =~ /INVARIANT_OPTIONS/))
       
  4275 					&& ($CustGCCE))
       
  4276 					{
       
  4277 						$GCCE_CompilerOption = RemoveBsfOptions($Opt,$GCCE_CompilerOption);
       
  4278 					}
       
  4279 					elsif($OptionName =~ /COMMON_OPTIONS/)
       
  4280 					{
       
  4281 						$CCFLAGS = RemoveBsfOptions($Opt,$CCFLAGS);
       
  4282 					}
       
  4283 					elsif(($OptionName =~ /THUMB_OPTIONS/)
       
  4284 					|| ($OptionName =~ /ARM_OPTIONS/)
       
  4285 					|| ($OptionName =~ /KERNEL_OPTIONS/))
       
  4286 					{
       
  4287 						$CCFLAGS = RemoveBsfOptions($Opt,$CCFLAGS);
       
  4288 					}
       
  4289 					elsif($OptionName =~ /INVARIANT_OPTIONS/)
       
  4290 					{
       
  4291 						$CCFLAGS = RemoveBsfOptions($Opt,$CCFLAGS);
       
  4292 					}
       
  4293 					elsif($OptionName =~ /LD_OPTIONS/)
       
  4294 					{
       
  4295 						$linkeropts = RemoveBsfOptions($Opt,$Link);
       
  4296 						$linkCommand = RemoveBsfOptions($Opt,$Link);
       
  4297 					}
       
  4298 					elsif($OptionName =~ /AR_OPTIONS/)
       
  4299 					{
       
  4300 						$archiveropts = RemoveBsfOptions($Opt,$linkCommand);
       
  4301 					}
       
  4302 				}					
       
  4303 				@Fragments=();
       
  4304 			}
       
  4305 			
       
  4306 			if (@Fragments = Cl_bpabi::Split_BSF_Options($val,'AddOptions')) 
       
  4307 			{
       
  4308 				my $v;
       
  4309 				foreach $v (@Fragments)
       
  4310 				{
       
  4311 					if((($OptionName =~ /COMMON_OPTIONS/)
       
  4312 					|| ($OptionName =~ /THUMB_OPTIONS/)
       
  4313 					|| ($OptionName =~ /ARM_OPTIONS/)
       
  4314 					|| ($OptionName =~ /KERNEL_OPTIONS/)
       
  4315 					|| ($OptionName =~ /INVARIANT_OPTIONS/))
       
  4316 					&& ($CustGCCE))
       
  4317 					{
       
  4318 						$GCCE_CompilerOption .= ' '.$v.' ';
       
  4319 					}
       
  4320 					elsif($OptionName =~ /COMMON_OPTIONS/)
       
  4321 					{
       
  4322 						$bsfaddoptions .= ' '.$v.' '; 						
       
  4323 					}
       
  4324 					elsif(($OptionName =~ /THUMB_OPTIONS/)
       
  4325 					|| ($OptionName =~ /ARM_OPTIONS/)
       
  4326 					|| ($OptionName =~ /KERNEL_OPTIONS/))
       
  4327 					{
       
  4328 						$bsfaddoptions .= ' '.$v.' ';	
       
  4329 					}
       
  4330 					elsif($OptionName =~ /INVARIANT_OPTIONS/)
       
  4331 					{
       
  4332 						$bsfaddoptions .= ' '.$v.' ';
       
  4333 					}
       
  4334 					elsif($OptionName =~ /LD_OPTIONS/)
       
  4335 					{
       
  4336 						$linkeropts .= ' '.$v.' ';
       
  4337 					}
       
  4338 					elsif($OptionName =~ /AR_OPTIONS/)
       
  4339 					{
       
  4340 						$archiveropts .= ' '.$v.' ';
       
  4341 					}
       
  4342 				}
       
  4343 				@Fragments=();
       
  4344 			}
       
  4345 		}
       
  4346 		else
       
  4347 		{
       
  4348 			if((($OptionName =~ /COMMON_OPTIONS/)
       
  4349 			|| ($OptionName =~ /THUMB_OPTIONS/)
       
  4350 			|| ($OptionName =~ /ARM_OPTIONS/)
       
  4351 			|| ($OptionName =~ /KERNEL_OPTIONS/)
       
  4352 			|| ($OptionName =~ /INVARIANT_OPTIONS/))
       
  4353 			&& ($CustGCCE))
       
  4354 			{
       
  4355 				$GCCE_CompilerOption .= ' '.$val.' ';
       
  4356 			}
       
  4357 			elsif($OptionName =~ /COMMON_OPTIONS/)
       
  4358 			{
       
  4359 				$bsfaddoptions .= ' '.$val.' ';
       
  4360 			}
       
  4361 			elsif(($OptionName =~ /THUMB_OPTIONS/)
       
  4362 			|| ($OptionName =~ /ARM_OPTIONS/)
       
  4363 			|| ($OptionName =~ /KERNEL_OPTIONS/))
       
  4364 			{
       
  4365 				$bsfaddoptions .= ' '.$val.' ';
       
  4366 			}
       
  4367 			elsif($OptionName =~ /INVARIANT_OPTIONS/)
       
  4368 			{
       
  4369 				$bsfaddoptions .= ' '.$val.' ';
       
  4370 			}
       
  4371 			elsif($OptionName =~ /LD_OPTIONS/)
       
  4372 			{
       
  4373 				$linkeropts .= ' '.$val.' ';
       
  4374 			}
       
  4375 			elsif($OptionName =~ /AR_OPTIONS/)
       
  4376 			{
       
  4377 				$archiveropts .= ' '.$val.' ';
       
  4378 			}
       
  4379 		}	
       
  4380 	}
       
  4381 }
       
  4382 
       
  4383 sub RemoveBsfOptions($$)
       
  4384 {
       
  4385 	my ($Opt_to_replace,$Opt_replaced_in) = @_;
       
  4386 	
       
  4387 	$Opt_replaced_in =~ s/$Opt_to_replace//g;
       
  4388 	return $Opt_replaced_in;
       
  4389 }
       
  4390 
       
  4391 # function to expand the macro as pass with appropriate options
       
  4392 sub printlist {
       
  4393 	my $option =shift @_;
       
  4394 	my @list = @_,
       
  4395 	my $data;
       
  4396 	my $finalval=undef;
       
  4397 	
       
  4398 	foreach $data (@list)
       
  4399 	{
       
  4400 		if($option =~ "-D") {
       
  4401 			$finalval .= " ".$option.$data;	
       
  4402 		}
       
  4403 		else {
       
  4404 			$finalval .= " ".$option." ".$data;
       
  4405 		}
       
  4406 	}
       
  4407 	return $finalval;
       
  4408 }
       
  4409 
       
  4410 #read the configuration make file into the HASH and use them for further processing
       
  4411 sub collect_config_data {
       
  4412 	my($configfile) = @_;
       
  4413 	open(DATA, "<$configfile");
       
  4414 	while(<DATA>) 
       
  4415 	{	
       
  4416 		my $line = $_;
       
  4417 		if($line =~ /=/)
       
  4418 		{
       
  4419 			if ($line =~ /(.*):=(.*)/)
       
  4420 			{ 
       
  4421 				$configdata{$1}=$2;
       
  4422 			}
       
  4423 			elsif ($line =~ /(.*)=(.*=.*)/)
       
  4424 			{ 
       
  4425 				$configdata{$1}=$2;
       
  4426 			}
       
  4427 			elsif ($line =~ /(.*)=(.*)/)
       
  4428 			{ 
       
  4429 				$configdata{$1}=$2;
       
  4430 			}
       
  4431 		}
       
  4432 	}
       
  4433 	close(DATA)
       
  4434 }
       
  4435 
       
  4436 #function is ti fetch the contents of the config data which is read from the configuration make file, 
       
  4437 # for ex: KERNEL_OPTIONS=$(ARM_INSTRUCTION_SET) $(NO_EXCEPTIONS), this function extracts the value for ARM_INSTRUCTION_SET & NO_EXCEPTIONS
       
  4438 sub fetch_config_data {
       
  4439 	my($list) = @_;
       
  4440 	my $op;
       
  4441 	my $op1;
       
  4442 	my $finaldata = undef;
       
  4443 	
       
  4444 	my @ip_options = split(/\s+/, $list);	
       
  4445 	foreach $op (@ip_options)
       
  4446 	{
       
  4447 		$op =~ s/\)//g;
       
  4448 		$op =~ s/\$\(//g;
       
  4449 		if($op =~ /-/) {
       
  4450 			$finaldata .= " ".$op;
       
  4451 		}
       
  4452 		else {
       
  4453 			$finaldata .= " ".$configdata{$op};
       
  4454 		}
       
  4455 	}
       
  4456 	return $finaldata;
       
  4457 }
       
  4458 
       
  4459 # function to fix the bsf options, if the bsf option is already present in the CCFLAGS then remove from it so that it can be added from bsf,
       
  4460 # this is to avoid the duplication of the options passed to the compiler.
       
  4461 sub fixbsfoptions {
       
  4462 	my ($options) = @_;
       
  4463 	my $ccflgs = $CCFLAGS;
       
  4464 	my $d;
       
  4465 	my $Pattern = '-{1,2}\S+\s*(?!-)\S*';
       
  4466 	my @list = $options =~ /$Pattern/g;
       
  4467 	foreach $d (@list) {
       
  4468 		if($ccflgs =~ /$d/) {
       
  4469 				$ccflgs =~ s/$d//g;	
       
  4470 		}
       
  4471 		else {
       
  4472 			if($d =~ /(.*)\s+(.*)/) {
       
  4473 				my $a = $1;
       
  4474 				if($ccflgs =~ /$a\s+\S+/) {
       
  4475 					$ccflgs =~ s/$a\s+\S+//g;
       
  4476 				}
       
  4477 			}
       
  4478 		}
       
  4479 	}
       
  4480 	$CCFLAGS = $ccflgs;
       
  4481 }
       
  4482 
       
  4483 # funtion to get the list if the libraries to be linked during linking
       
  4484 sub GetLibList() {
       
  4485 	my @LibList;
       
  4486 	my @StaticLibList;
       
  4487 	my $Plat=&main::Plat;
       
  4488 	unless(defined($ENV{RVCT_VER_MAJOR})){
       
  4489 		my ($rvct_M, $rvct_m, $rvct_b) = RVCT_plat2set::get_version_list($Plat);
       
  4490 		$ENV{RVCT_VER_MAJOR}=$rvct_M;
       
  4491 	}
       
  4492 	&Cl_bpabi::getVariableForNewPlat();
       
  4493 	my $list = &Cl_bpabi::getConfigVariable('STATIC_LIBS_LIST') ;
       
  4494 	
       
  4495 	if (length($list) >0)
       
  4496 	{
       
  4497 		@StaticLibList = split(/\s+/, $list);
       
  4498 	}
       
  4499 	if($Plat eq "ARMV5" || $Plat eq "ARMV5_ABIV2" || IsCustomization($Plat)) {
       
  4500 		@LibList=&Armutl_ArmLibList;
       
  4501 		if(@LibList==0) {
       
  4502 			my $LibDir = Armutl_ArmLibDir();
       
  4503 			if (@StaticLibList) {
       
  4504 				foreach my $lib (@StaticLibList) {
       
  4505 					push @LibList, ("$LibDir\\$lib");
       
  4506 				}
       
  4507 			}
       
  4508 		}
       
  4509 	}
       
  4510 	else
       
  4511 	{
       
  4512 		@LibList = ('$(STATIC_LIBS_LIST)');
       
  4513 	}
       
  4514 	return @LibList;
       
  4515 }
       
  4516 
       
  4517 1;