|
1 @rem |
|
2 @rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 @rem All rights reserved. |
|
4 @rem This component and the accompanying materials are made available |
|
5 @rem under the terms of "Eclipse Public License v1.0" |
|
6 @rem which accompanies this distribution, and is available |
|
7 @rem at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 @rem |
|
9 @rem Initial Contributors: |
|
10 @rem Nokia Corporation - initial contribution. |
|
11 @rem |
|
12 @rem Contributors: |
|
13 @rem |
|
14 @rem Description: |
|
15 @rem |
|
16 @rem = '--*-Perl-*-- |
|
17 @echo off |
|
18 if "%OS%" == "Windows_NT" goto WinNT |
|
19 perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9 |
|
20 goto endofperl |
|
21 :WinNT |
|
22 perl -x -S "%0" %* |
|
23 if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl |
|
24 if %errorlevel% == 9009 echo You do not have Perl in your PATH. |
|
25 goto endofperl |
|
26 @rem '; |
|
27 #!perl |
|
28 #line 14 |
|
29 |
|
30 use strict; |
|
31 use Getopt::Long; |
|
32 |
|
33 my $toolVersion = 1.0; |
|
34 my $RVCTVersion = 2.1; |
|
35 my $RVCTBuild = 416; |
|
36 my @redundantExportsRegEx = (qr/^_ZTI/, qr/^_ZTV/); |
|
37 |
|
38 |
|
39 # 1. Check arguments, output help etc. |
|
40 |
|
41 if (@ARGV == 0) |
|
42 { |
|
43 print (STDERR "\nFIXEABIDEFS.BAT - Version $toolVersion for RVCT$RVCTVersion b$RVCTBuild\n"); |
|
44 |
|
45 print STDERR << 'END_OF_HELP'; |
|
46 |
|
47 Usage: fixeabidefs.bat [-analyse|-list|-update] build_log.log |
|
48 |
|
49 Parses the output from build_log.log and locates all MAKEDEF errors where ARMV5 built |
|
50 object files do not include exports specified in the current, frozen, EABI .def file. |
|
51 Where this has occurred, the tool checks against an internal list to determine |
|
52 whether these are redundant exports that are no longer required. |
|
53 |
|
54 -analyse Process MAKEDEF errors and warnings list .def files that cannot be updated by this tool. |
|
55 -list Lists all .def files that will be updated by the tool. |
|
56 -update Creates updated .def files with redundant exports removed. |
|
57 |
|
58 Updated .def files have redundant exports removed by "back-filling" from unfrozen exports |
|
59 flagged against the same .def file. If no unfrozen exports are available, the "ABSENT" |
|
60 export placeholder is used to effectively remove the export, but maintain a degree of BC. |
|
61 |
|
62 NOTE: The tool assumes that the original build source layout is replicated on the drive |
|
63 where it is being executed. |
|
64 |
|
65 Redundant exports processed on the following regex: |
|
66 END_OF_HELP |
|
67 |
|
68 foreach my $redundantExportRegEx (@redundantExportsRegEx) |
|
69 { |
|
70 print ("\t$redundantExportRegEx\n"); |
|
71 } |
|
72 |
|
73 exit(1); |
|
74 } |
|
75 |
|
76 my $list = 0; |
|
77 my $update = 0; |
|
78 my $analyse = 0; |
|
79 |
|
80 GetOptions ('list' => \$list, 'update' => \$update, 'analyse' => \$analyse); |
|
81 |
|
82 |
|
83 # 2. Parse the log and record the detail of all relevant MAKEDEF errors and warnings |
|
84 |
|
85 my $BUILD_LOG = $ARGV[0]; |
|
86 open BUILD_LOG, "< $BUILD_LOG" or die "\nCan't read $BUILD_LOG!\n\n"; |
|
87 |
|
88 my $line; |
|
89 my @buildLog; |
|
90 |
|
91 while ($line = <BUILD_LOG>) |
|
92 { |
|
93 push @buildLog, $line; |
|
94 } |
|
95 |
|
96 close BUILD_LOG; |
|
97 |
|
98 my $defFile; |
|
99 my $export; |
|
100 my $processExport; |
|
101 my $variant; |
|
102 |
|
103 # All hashes keyed on fully pathed .def file |
|
104 my %impactedDefFiles; |
|
105 my %missingURELExports; |
|
106 my %missingUDEBExports; |
|
107 my %unfrozenURELExports; |
|
108 my %unfrozenUDEBExports; |
|
109 |
|
110 my $parseWarning = 0; |
|
111 my $parseError = 0; |
|
112 |
|
113 my @exports; |
|
114 |
|
115 |
|
116 # Scan the log and build up UREL and UDEB lists of unfrozen and missing exports |
|
117 |
|
118 foreach $line (@buildLog) |
|
119 { |
|
120 if (($line !~ /^ /)) |
|
121 { |
|
122 if ($parseError) |
|
123 { |
|
124 $variant =~ /UREL/ ? push @{$missingURELExports{$defFile}}, [@exports] : push @{$missingUDEBExports{$defFile}}, [@exports]; |
|
125 $parseError = 0; |
|
126 $impactedDefFiles{$defFile} = 1; |
|
127 } |
|
128 elsif ($parseWarning) |
|
129 { |
|
130 $variant =~ /UREL/ ? push @{$unfrozenURELExports{$defFile}}, [@exports] : push @{$unfrozenUDEBExports{$defFile}}, [@exports]; |
|
131 $parseWarning = 0; |
|
132 $impactedDefFiles{$defFile} = 1; |
|
133 } |
|
134 |
|
135 @exports = (); |
|
136 } |
|
137 |
|
138 if ($line =~ /^ make.* CFG\=/) |
|
139 { |
|
140 $variant = $line; |
|
141 $variant =~ s/^.*CFG\=//; |
|
142 $variant =~ s/ .*$//; |
|
143 $variant =~ s/\s//g; |
|
144 next; |
|
145 } |
|
146 |
|
147 if ($line =~ /MAKEDEF WARNING:.*not yet Frozen in/) |
|
148 { |
|
149 $parseError = 0; |
|
150 $parseWarning = 1; |
|
151 |
|
152 $defFile = $line; |
|
153 $defFile =~ s/^.*not yet Frozen in//; |
|
154 $defFile =~ s/:$//; |
|
155 $defFile =~ s/\s//g; |
|
156 $defFile = lc $defFile; |
|
157 next; |
|
158 } |
|
159 |
|
160 if ($line =~ /MAKEDEF ERROR:/) |
|
161 { |
|
162 $parseError = 1; |
|
163 $parseWarning = 0; |
|
164 next; |
|
165 } |
|
166 |
|
167 if (($line =~ /^ /) && ($parseError || $parseWarning)) |
|
168 { |
|
169 $export = $line; |
|
170 $export =~ s/^.* : //; |
|
171 $export =~ s/ .*$//; |
|
172 $export =~ s/\s//g; |
|
173 |
|
174 if ($parseError) |
|
175 { |
|
176 $defFile = $line; |
|
177 $defFile =~ s/\(.*$//; |
|
178 $defFile =~ s/\s//g; |
|
179 $defFile = lc $defFile; |
|
180 } |
|
181 |
|
182 push @exports, $export; |
|
183 |
|
184 next; |
|
185 } |
|
186 } |
|
187 |
|
188 |
|
189 my %validDefFiles = %impactedDefFiles; |
|
190 |
|
191 my %missingExportDifferences; |
|
192 my %unfrozenExportDifferences; |
|
193 |
|
194 my %sharedDifferences; |
|
195 |
|
196 my $redundantExportRegEx; |
|
197 my %invalidExports; |
|
198 my $validExport; |
|
199 |
|
200 my $URELelements; |
|
201 my $UDEBelements; |
|
202 my $index1; |
|
203 my $index2; |
|
204 |
|
205 foreach $defFile (sort keys %impactedDefFiles) |
|
206 { |
|
207 if ($missingURELExports{$defFile}) |
|
208 { |
|
209 $URELelements = @{$missingURELExports{$defFile}}; |
|
210 $UDEBelements = @{$missingUDEBExports{$defFile}}; |
|
211 |
|
212 for ($index1 = 0; $index1 < $URELelements; $index1++) |
|
213 { |
|
214 foreach $export (@{@{$missingURELExports{$defFile}}[$index1]}) |
|
215 { |
|
216 for ($index2 = 0; $index2 < $UDEBelements; $index2++) |
|
217 { |
|
218 if (!grep (/$export/, @{@{$missingUDEBExports{$defFile}}[$index2]})) |
|
219 { |
|
220 if (!$index1 && !$index2) |
|
221 { |
|
222 $missingExportDifferences{$defFile} = 1; |
|
223 } |
|
224 else |
|
225 { |
|
226 $sharedDifferences{$defFile} = 1; |
|
227 } |
|
228 |
|
229 delete $validDefFiles{$defFile}; |
|
230 } |
|
231 } |
|
232 |
|
233 $validExport = 0; |
|
234 |
|
235 foreach $redundantExportRegEx (@redundantExportsRegEx) |
|
236 { |
|
237 if ($export =~ /$redundantExportRegEx/) |
|
238 { |
|
239 $validExport = 1; |
|
240 } |
|
241 } |
|
242 |
|
243 if (!$validExport) |
|
244 { |
|
245 ${$invalidExports{$defFile}}{$export} = 1; |
|
246 delete $validDefFiles{$defFile}; |
|
247 } |
|
248 } |
|
249 } |
|
250 |
|
251 for ($index1 = 0; $index1 < $URELelements; $index1++) |
|
252 { |
|
253 foreach $export (@{@{$missingUDEBExports{$defFile}}[$index1]}) |
|
254 { |
|
255 for ($index2 = 0; $index2 < $URELelements; $index2++) |
|
256 { |
|
257 if (!grep (/$export/, @{@{$missingURELExports{$defFile}}[$index2]})) |
|
258 { |
|
259 if (!$index1 && !$index2) |
|
260 { |
|
261 $missingExportDifferences{$defFile} = 1; |
|
262 } |
|
263 else |
|
264 { |
|
265 $sharedDifferences{$defFile} = 1; |
|
266 } |
|
267 |
|
268 delete $validDefFiles{$defFile}; |
|
269 } |
|
270 } |
|
271 |
|
272 $validExport = 0; |
|
273 |
|
274 foreach $redundantExportRegEx (@redundantExportsRegEx) |
|
275 { |
|
276 if ($export =~ /$redundantExportRegEx/) |
|
277 { |
|
278 $validExport = 1; |
|
279 } |
|
280 } |
|
281 |
|
282 if (!$validExport) |
|
283 { |
|
284 ${$invalidExports{$defFile}}{$export} = 1; |
|
285 delete $validDefFiles{$defFile}; |
|
286 } |
|
287 } |
|
288 } |
|
289 } |
|
290 |
|
291 if (!$unfrozenURELExports{$defFile} && $unfrozenUDEBExports{$defFile}) |
|
292 { |
|
293 $unfrozenExportDifferences{$defFile} = 1; |
|
294 } |
|
295 elsif ($unfrozenURELExports{$defFile}) |
|
296 { |
|
297 $URELelements = @{$unfrozenURELExports{$defFile}}; |
|
298 $UDEBelements = @{$unfrozenUDEBExports{$defFile}}; |
|
299 |
|
300 for ($index1 = 0; $index1 < $URELelements; $index1++) |
|
301 { |
|
302 foreach $export (@{@{$unfrozenURELExports{$defFile}}[$index1]}) |
|
303 { |
|
304 for ($index2 = 0; $index2 < $UDEBelements; $index2++) |
|
305 { |
|
306 if (!grep (/$export/, @{@{$unfrozenUDEBExports{$defFile}}[$index2]})) |
|
307 { |
|
308 if (!$index1 && !$index2) |
|
309 { |
|
310 $unfrozenExportDifferences{$defFile} = 1; |
|
311 } |
|
312 else |
|
313 { |
|
314 delete $validDefFiles{$defFile}; |
|
315 $sharedDifferences{$defFile} = 1; |
|
316 } |
|
317 } |
|
318 } |
|
319 } |
|
320 } |
|
321 |
|
322 for ($index1 = 0; $index1 < $URELelements; $index1++) |
|
323 { |
|
324 foreach $export (@{@{$unfrozenUDEBExports{$defFile}}[$index1]}) |
|
325 { |
|
326 for ($index2 = 0; $index2 < $URELelements; $index2++) |
|
327 { |
|
328 if (!grep (/$export/, @{@{$unfrozenURELExports{$defFile}}[$index2]})) |
|
329 { |
|
330 if (!$index1 && !$index2) |
|
331 { |
|
332 $unfrozenExportDifferences{$defFile} = 1; |
|
333 } |
|
334 else |
|
335 { |
|
336 delete $validDefFiles{$defFile}; |
|
337 $sharedDifferences{$defFile} = 1; |
|
338 } |
|
339 } |
|
340 } |
|
341 } |
|
342 } |
|
343 } |
|
344 } |
|
345 |
|
346 if ($analyse) |
|
347 { |
|
348 if (%missingExportDifferences) |
|
349 { |
|
350 print ("\nThe following .def files differ in the number of missing exports between UREL and UDEB builds.\n"); |
|
351 print ("These files will not be treated by this tool.\n\n"); |
|
352 |
|
353 foreach $defFile (sort keys %missingExportDifferences) |
|
354 { |
|
355 print ("\t$defFile\n"); |
|
356 } |
|
357 } |
|
358 |
|
359 if (%unfrozenExportDifferences) |
|
360 { |
|
361 print ("\nThe following .def files differ in the number of unfrozen exports between UREL and UDEB builds.\n"); |
|
362 print ("These files will be or were back-filled with regard to any UREL unfrozen exports available."); |
|
363 print ("If no UREL unfrozen exports are available, the classes in question have to be marked non-sharable.\n\n"); |
|
364 |
|
365 foreach $defFile (sort keys %unfrozenExportDifferences) |
|
366 { |
|
367 print ("\t$defFile\n"); |
|
368 } |
|
369 } |
|
370 |
|
371 if (%sharedDifferences) |
|
372 { |
|
373 print ("\nThe following .def files are shared between multiple components, and differ in exports\n"); |
|
374 print ("between either UDEB or UREL builds, or between the build of the components from which they are used.\n"); |
|
375 print ("These files will not be treated by this tool.\n\n"); |
|
376 |
|
377 foreach $defFile (sort keys %sharedDifferences) |
|
378 { |
|
379 print ("\t$defFile\n"); |
|
380 } |
|
381 } |
|
382 |
|
383 if (%invalidExports) |
|
384 { |
|
385 print ("\nThe following .def files contain missing exports that cannot be resolved by this tool.\n"); |
|
386 |
|
387 foreach $defFile (sort keys %invalidExports) |
|
388 { |
|
389 print ("\n\t$defFile\n"); |
|
390 |
|
391 foreach $export (sort keys %{$invalidExports{$defFile}}) |
|
392 { |
|
393 print ("\t\t$export\n"); |
|
394 } |
|
395 } |
|
396 } |
|
397 |
|
398 if (!%missingExportDifferences && !%unfrozenExportDifferences && !%sharedDifferences && !%invalidExports) |
|
399 { |
|
400 print ("\nAll MAKEDEF ERRORs and WARNINGs in the specified log can be treated by this tool.\n"); |
|
401 } |
|
402 } |
|
403 |
|
404 |
|
405 if ($list) |
|
406 { |
|
407 foreach $defFile (sort keys %validDefFiles) |
|
408 { |
|
409 print ("$defFile\n"); |
|
410 } |
|
411 } |
|
412 |
|
413 |
|
414 if ($update) |
|
415 { |
|
416 my %updatedDefFiles; |
|
417 my $missingExport; |
|
418 my $unfrozenExport; |
|
419 |
|
420 foreach $defFile (keys %validDefFiles) |
|
421 { |
|
422 if (!open DEF_FILE, "< $defFile") |
|
423 { |
|
424 print "Can't read $defFile!\n"; |
|
425 next; |
|
426 } |
|
427 |
|
428 while ($line = <DEF_FILE>) |
|
429 { |
|
430 |
|
431 # Either Back-fill or make 'ABSENT' any missing exports |
|
432 |
|
433 if ($missingURELExports{$defFile}) |
|
434 { |
|
435 foreach $missingExport (@{@{$missingURELExports{$defFile}}[0]}) |
|
436 { |
|
437 if ($line =~ /$missingExport/) |
|
438 { |
|
439 $unfrozenExport = ""; |
|
440 |
|
441 if ($unfrozenURELExports{$defFile}) |
|
442 { |
|
443 $unfrozenExport = pop @{@{$unfrozenURELExports{$defFile}}[0]}; |
|
444 } |
|
445 |
|
446 if ($unfrozenExport) |
|
447 { |
|
448 $line =~ s/$missingExport/$unfrozenExport/; |
|
449 |
|
450 # If there's an existing comment section, then update it appropriately |
|
451 |
|
452 my $commentUpdate = ''; |
|
453 |
|
454 if ($unfrozenExport =~ /^_ZTV/) |
|
455 { |
|
456 $commentUpdate = '; #<VT>#'; |
|
457 } |
|
458 elsif ($unfrozenExport =~ /^_ZTI/) |
|
459 { |
|
460 $commentUpdate = '; #<TI>#'; |
|
461 } |
|
462 |
|
463 $line =~ s/;.*$/$commentUpdate/; |
|
464 } |
|
465 else |
|
466 { |
|
467 if ($line =~ / \;/) |
|
468 { |
|
469 $line =~ s/ \;/ ABSENT \;/; |
|
470 } |
|
471 else |
|
472 { |
|
473 $line.= ' ABSENT'; |
|
474 } |
|
475 } |
|
476 |
|
477 $line .= "\n" unless ($line =~ /\n$/); |
|
478 |
|
479 last; |
|
480 } |
|
481 } |
|
482 } |
|
483 |
|
484 push (@{$updatedDefFiles{$defFile}}, $line); |
|
485 } |
|
486 close DEF_FILE; |
|
487 } |
|
488 |
|
489 |
|
490 # Resolve any remaining unfrozen exports in the standard way |
|
491 |
|
492 my $lastExportIndex; |
|
493 my $lastExportOrdinal; |
|
494 |
|
495 foreach $defFile (keys %updatedDefFiles) |
|
496 { |
|
497 if ($unfrozenURELExports{$defFile} && @{@{$unfrozenURELExports{$defFile}}[0]}) |
|
498 { |
|
499 $lastExportIndex = @{$updatedDefFiles{$defFile}}-1; |
|
500 |
|
501 while (@{$updatedDefFiles{$defFile}}[$lastExportIndex] =~ /^\s$/) |
|
502 { |
|
503 pop @{$updatedDefFiles{$defFile}}; |
|
504 $lastExportIndex--; |
|
505 } |
|
506 |
|
507 @{$updatedDefFiles{$defFile}}[$lastExportIndex] .= "\n" unless (@{$updatedDefFiles{$defFile}}[$lastExportIndex] =~ /\n$/); |
|
508 |
|
509 $lastExportOrdinal = @{$updatedDefFiles{$defFile}}[$lastExportIndex]; |
|
510 $lastExportOrdinal =~ s/^.*@\s+//; |
|
511 $lastExportOrdinal =~ s/ .*$//; |
|
512 $lastExportOrdinal =~ s/\s//g; |
|
513 |
|
514 foreach $unfrozenExport (@{@{$unfrozenURELExports{$defFile}}[0]}) |
|
515 { |
|
516 $lastExportOrdinal++; |
|
517 |
|
518 my $comment = ''; |
|
519 |
|
520 if ($unfrozenExport =~ /^_ZTV/) |
|
521 { |
|
522 $comment = ' ; #<VT>#'; |
|
523 } |
|
524 elsif ($unfrozenExport =~ /^_ZTI/) |
|
525 { |
|
526 $comment = ' ; #<TI>#'; |
|
527 } |
|
528 |
|
529 push (@{$updatedDefFiles{$defFile}}, "\t$unfrozenExport @ $lastExportOrdinal NONAME$comment\n"); |
|
530 } |
|
531 |
|
532 push (@{$updatedDefFiles{$defFile}}, "\n"); |
|
533 } |
|
534 } |
|
535 |
|
536 |
|
537 # Create the new .def files |
|
538 |
|
539 foreach $defFile (sort keys %updatedDefFiles) |
|
540 { |
|
541 if (!open NEW_DEF_FILE, ">$defFile") |
|
542 { |
|
543 print ("ERROR : Can\'t create \"$defFile\"\n"); |
|
544 next; |
|
545 } |
|
546 |
|
547 foreach $line (@{$updatedDefFiles{$defFile}}) |
|
548 { |
|
549 print (NEW_DEF_FILE $line); |
|
550 } |
|
551 |
|
552 close NEW_DEF_FILE; |
|
553 |
|
554 print ("Created : \"$defFile\"\n"); |
|
555 } |
|
556 |
|
557 } |
|
558 |
|
559 |
|
560 __END__ |
|
561 :endofperl |