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