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