comparison g23m/nds_busyb.pl @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:509db1a7b7b8
1 #!perl -w
2 #-----------------------------------------------------------------------------
3 # Project :
4 # Modul : nds_busyb.pl
5 #-----------------------------------------------------------------------------
6 # Copyright 2003 Texas Instruments Deutschland GmbH
7 # All rights reserved.
8 #
9 # This file is confidential and a trade secret of Texas
10 # Instruments Deutschland GmbH
11 # The receipt of or possession of this file does not convey
12 # any rights to reproduce or disclose its contents or to
13 # manufacture, use, or sell anything it may describe, in
14 # whole, or in part, without the specific written consent of
15 # Texas Instruments Deutschland GmbH.
16 #-----------------------------------------------------------------------------
17 # Purpose :
18 #-----------------------------------------------------------------------------
19
20
21 use strict;
22 use File::Copy;
23 use File::Find;
24 use File::Spec;
25 use Cwd;
26 use Getopt::Long qw(:config pass_through);
27
28
29 #-------------------------------------------------------------------------------
30 # Variables
31 #-------------------------------------------------------------------------------
32
33 # misc. variables
34 my $hw_variant;
35 my $l1_variant;
36
37 my $command;
38
39 # make tool (gnumake/clearmake)
40 my $make;
41
42 # makefile file name
43 my $makeFile;
44
45 my $makeVars;
46 my $condat_var_variables;
47
48 # specifies whether input file format is XML (default) or make (*.mak)
49 my $called_with_mak_file;
50
51 # specifies whether there is a "mconst:" target in the makefile or not
52 my $has_target_named_mconst;
53
54 my @busyb_libs;
55 my @intram_libs;
56
57 my $current_dir = cwd;
58 # do not only store the drive in $current_drive, but rather store the path
59 # to the current dir (necessary to work directly on V:\<view>\...)
60 my $current_drive = cwd;
61 $current_drive =~ s|[\\/][^\\/]+$||;
62
63 # path to Nice software (covering SSA, WCP, and SDVK)
64 my $hw_root = $current_dir . "/../chipsetsw";
65 my $hw_layer1 = $hw_root . "/layer1";
66 my $hw_system = $hw_root . "/system";
67 my $hw_system_config = $hw_system . "/config";
68 # points to the system/deps_objs/<ABC-CONFIG> directory (initialized by
69 # extract_globals_from_makefile() function)
70 my $hw_system_objects;
71
72 # path to GPF software
73 my $gpf_root = $current_drive . "/gpf";
74 # we need to honor proper upper and lower case when using clearmake!
75 my $gpf_ccd = $gpf_root . "/CCD";
76
77 # BuSyB cdginc output directories (necessary for step 7)
78 my $cdginc_dir;
79 my $cdginc_tools_dir;
80
81 # BuSyB target image (.out) file name (necessary for step 9)
82 my $target_image;
83
84 # specifies whether output is being redirected (logged to a file) or not
85 my $outerr_redirected;
86
87 # specifies whether ccddata_dll.dll can be built (1) or not (0):
88 # this depends on the presence of cl.exe, see also determine_cl_version() and
89 # step__check_environment()
90 my $generate_ccddata_dll;
91
92 # Generated makefile names
93 my $abc_exports;
94 my $busyb_prefix;
95 my $condat_lib_ip_mak;
96 my $condat_var_mak;
97
98 # tool definitions
99 my $t_perl = "perl";
100 my $t_updtBusybInc = "gen_abc_exports.mak";
101 my $t_updtAbc = "update_exported_makefiles.pl";
102 my $t_abc = "abc.pl";
103 my $t_updtBusyb = "system/update_makefile.mak";
104
105 # command line options (do not initialize $o_make! -- see step 0 below)
106 my $o_file;
107 my $o_make;
108 my $o_logfile = "report.txt";
109 my $o_shell = 0;
110 my $o_help = 0;
111
112 # ABC/make pass-through options
113 my $abc_opt;
114 my $make_opt;
115
116 # script exit value, being set by last step: step__compile_berlin_sw()
117 my $exit_value;
118
119 # Variables needed for the progress bar
120 my $list_of_libs_available = 0 ;
121 my $pid;
122
123
124
125 #-------------------------------------------------------------------------------
126 # Main Program
127 #-------------------------------------------------------------------------------
128
129 # parse command line, passing through all unknown options to make
130 parse_command_line();
131
132
133 # logging is enabled by default (unless $o_shell is set, done by option "-s")
134 if (!$o_shell)
135 {
136 # attempt to redirect STDOUT+STDERR
137 $outerr_redirected = redirect_output();
138 }
139 else
140 {
141 # do not redirect output, it is being sent to shell
142 $outerr_redirected = 0;
143 }
144
145 my $build_message = "\nStarting build of " . $o_file . ",
146 REDIRECT_PLACEHOLDER
147
148 Build may take a while, so please be patient!\n\n";
149
150 if ($outerr_redirected)
151 {
152 $build_message =~ s/REDIRECT_PLACEHOLDER/output is being logged to $o_logfile,/;
153 print CONSOLE_OUT $build_message;
154 }
155 else
156 {
157 $build_message =~ s/REDIRECT_PLACEHOLDER/output is NOT being logged!/;
158 print $build_message;
159 }
160
161
162 # steps 1 and 2 must always be performed
163 step__check_environment (1);
164 step__parse_input_file (2);
165
166 # all other steps depend on the input file format, "mconst:" target in the
167 # BuSyB makefile, or hybrid build system vs. unified build system
168 my @build_steps;
169
170
171 # determine if UnBuSy or HyBuSy is being used for compilation
172 if (defined($hw_variant))
173 {
174 # queue HyBuSy (hybrid build system) steps
175 # ($called_with_mak_file is being set in step__check_environment() and is
176 # already known at this point)
177 push @build_steps, \&step__update_busyb_makefile
178 unless $called_with_mak_file;
179 push @build_steps, \&step__busyb_create_directories;
180 push @build_steps, sub
181 {
182 # $has_target_named_mconst may be set as late as in
183 # step__update_busyb_makefile(), so it may not yet be known and we need
184 # to check this at run-time
185 if ($has_target_named_mconst)
186 {
187 # only process SAP/MSG docs if "mconst:" target exists in makefile
188 step__busyb_process_interfaces (@_);
189 }
190 else
191 {
192 # if not, need to decrement $step_no (first parameter of this function)
193 $_[0]--;
194 }
195 };
196 push @build_steps, sub
197 {
198 # $cdginc_tools_dir may be set as late as in
199 # step__update_busyb_makefile(), so it may not yet be known and we need
200 # to check this at run-time
201 if ($cdginc_tools_dir)
202 {
203 # only generate ccddata_dll.dll if SAP/MSG docs were processed
204 step__generate_ccddata_dll (@_);
205 }
206 else
207 {
208 # if not, need to decrement $step_no (first parameter of this function)
209 $_[0]--;
210 }
211 };
212 push @build_steps, \&step__generate_interface_for_abc
213 unless $called_with_mak_file;
214 push @build_steps, \&step__update_abc_config;
215 push @build_steps, \&step__extract_abc_variables
216 unless $called_with_mak_file;
217 push @build_steps, \&step__abc_compilation;
218 push @build_steps, \&step__busyb_compilation;
219
220 }
221 else
222 {
223 # queue UnBuSy (unified build system) steps
224 # ($called_with_mak_file is being set in step__check_environment() and is
225 # already known at this point)
226 # push @build_steps, \&step__busyb_generate_l1_configdef_files;
227 push @build_steps, sub { step__update_busyb_makefile ($_[0], "system/unbusy_g23m.ini"); }
228 unless $called_with_mak_file;
229 push @build_steps, \&step__busyb_create_directories;
230 push @build_steps, \&step__busyb_generate_cfg_files;
231 push @build_steps, \&step__busyb_generate_header_files;
232 push @build_steps, sub
233 {
234 # $has_target_named_mconst may be set as late as in
235 # step__update_busyb_makefile(), so it may not yet be known and we need
236 # to check this at run-time
237 if ($has_target_named_mconst)
238 {
239 # only process SAP/MSG docs if "mconst:" target exists in makefile
240 step__busyb_process_interfaces (@_);
241 }
242 else
243 {
244 # if not, need to decrement $step_no (first parameter of this function)
245 $_[0]--;
246 }
247 };
248 push @build_steps, sub
249 {
250 # $cdginc_tools_dir may be set as late as in
251 # step__update_busyb_makefile(), so it may not yet be known and we need
252 # to check this at run-time
253 if ($cdginc_tools_dir)
254 {
255 # only generate ccddata_dll.dll if SAP/MSG docs were processed
256 step__generate_ccddata_dll (@_);
257 }
258 else
259 {
260 # if not, need to decrement $step_no (first parameter of this function)
261 $_[0]--;
262 }
263 };
264 push @build_steps, \&step__busyb_compilation;
265 }
266
267
268 # execution of queued steps, starting with step number 3
269 $exit_value = 0;
270 my $step_no = 3;
271 foreach my $step (@build_steps)
272 {
273 &{$step} ($step_no);
274 $step_no++;
275 }
276
277 # restore redirected STDOUT+STDERR, if necessary
278 restore_redirection()
279 if $outerr_redirected;
280
281 exit $exit_value;
282
283
284 #-------------------------------------------------------------------------------
285 # SUBROUTINES
286 #-------------------------------------------------------------------------------
287
288
289 #-------------------------------------------------------------------------------
290 # parses the command line, sets global $o_* variables to all specified options,
291 # checks which options/parameters are passed through to make or ABC
292 #-------------------------------------------------------------------------------
293 sub parse_command_line
294 {
295 GetOptions ("file=s"=>\$o_file,
296 "log=s"=>\$o_logfile,
297 "shell"=>\$o_shell,
298 "make=s"=>\$o_make,
299 "help|?" =>\$o_help);
300
301 if ($o_help)
302 {
303 usage();
304 exit 0;
305 }
306
307 # determine ABC and make/BuSyB pass-through options from @ARGV
308 $abc_opt = "";
309 $make_opt = "";
310 foreach (@ARGV)
311 {
312 if (/^-x/)
313 {
314 # ABC pass-through option: -x...
315 #FIXME: are multiple ABC options allowed?
316 s/^-x//;
317 $abc_opt = $_;
318 }
319 else
320 {
321 # make/BuSyB pass-through option: all else
322 $make_opt .= " " . $_;
323 }
324 }
325
326 # sanity checks: due to enabled 'pass_through' and 'permute' of GetOptions(),
327 # some busyb.pl options may end up in other options parameters instead (e.g. if
328 # options which require a parameter are specified w/o any parameter: "... -m",
329 # or "... -m -l", ...)
330 foreach ($o_file, $o_logfile, $o_make)
331 {
332 # check all options which should take a parameter if they actually contain
333 # another otion and no parameter
334 if (defined($_) and /^-/)
335 {
336 print "\nERROR: Option missing mandatory parameter!\n\n";
337 usage();
338 exit 1;
339 }
340 }
341 foreach ("-f", "-l", "-m")
342 {
343 # check if the pass-through options to make contain on of the busyb.pl
344 # options
345 if ($make_opt =~ /$_/i)
346 {
347 print "\nERROR: Option missing mandatory parameter!\n\n";
348 usage();
349 exit 1;
350 }
351 }
352
353 if (!$o_file)
354 {
355 print "\nERROR: No input/configuration file specified with \"-f file\"!\n\n";
356 usage();
357 exit 1;
358 }
359 die "\nERROR: Input/configuration file \"" . $o_file . "\" not found, aborting"
360 unless -e $o_file;
361 # replace backslash with slash in filename
362 $o_file =~ s:\\:/:g;
363 }
364
365
366 #-------------------------------------------------------------------------------
367 # print short usage notes
368 #-------------------------------------------------------------------------------
369 sub usage
370 {
371 print "\nUSAGE:
372 perl busyb.pl -f XML-File [OPTIONS] [make_flags] [make_targets]
373
374 Build TI protocol stack with BuSyB/ABC, logging all output to report.txt by
375 default.
376
377 OPTIONS:
378 -l LOGFILE log to LOGFILE (default is report.txt)
379 -s output to current shell, no logging to report.txt
380 -x\"OPT\" pass-through options for ABC
381
382 EXAMPLES:
383 perl busyb.pl -f variants/2b_gp_mf_fd_..ps.xml
384 perl busyb.pl -f variants/2b_gp_mf_fd_..ps.xml clean_aci
385 perl busyb.pl -f variants/2b_gp_mf_fd_..ps.xml -x\"ENVFILE=my_env.mak\"
386 perl busyb.pl -f variants/2b_gp_mf_fd_..ps.xml -k
387 ";
388 }
389
390
391 #-------------------------------------------------------------------------------
392 # print current step to STDOUT (usually redirected to report.txt) and
393 # additionally to CONSOLE_OUT
394 #-------------------------------------------------------------------------------
395 sub print_status
396 {
397 print "\n-------------------------------------------------------------------------------";
398 print "\n$_[0]\n";
399 print "-------------------------------------------------------------------------------\n\n";
400
401 print CONSOLE_OUT "$_[0]\n"
402 if $outerr_redirected;
403 }
404
405
406 #-------------------------------------------------------------------------------
407 # print to CONSOLE_OUT for progress bar
408 #-------------------------------------------------------------------------------
409 sub print_progress
410 {
411 print CONSOLE_OUT "$_[0]\r"
412 if $outerr_redirected;
413
414 }
415
416
417
418 #-------------------------------------------------------------------------------
419 # this function parses the XML file
420 # it returns 0 on failure
421 # it sets the following global variables
422 # $hw_variant, $l1_variant, $makeVars
423 #-------------------------------------------------------------------------------
424 sub parse_file {
425 my $line;
426 open (IN,"<$_[0]")
427 or die "ERROR: Can't open file \"$_[0]\" ($!), aborting";
428
429 while(defined($line = <IN>))
430 {
431 # find HW string in ConfigDef document, e.g.
432 # <property name="HW_VARIANT" value="GPRS_DSAMPLE_AMR_NW"/>
433 # ^^^^^^^^^^^^^^^^^^^
434 if ($line =~ /name=\"HW_VARIANT\"\s*value=\"(.*)\"/ ) {
435 $hw_variant = $1;
436 }
437 elsif ($line =~ /name=\"(L1)\"\s*value=\"(.*)\"/ ) {
438 $l1_variant = $2;
439 $makeVars .= " $1=$2";
440 }
441 # finding all other properties in order to pass them to make
442 elsif ($line =~ /name=\"(\w+)\"\s*value=\"(.*)\"/ ) {
443 $makeVars .= " $1=$2";
444 }
445 }
446 close IN ;
447
448
449 return 1;
450 }
451
452
453 #-------------------------------------------------------------------------------
454 # currently need to remove all L1 objects before compiling (dependency problems
455 # in ABC) when the ABC config (== $hw_variant) changes (last ABC config is stored in
456 # /g23m/.abc_config)
457 #-------------------------------------------------------------------------------
458 sub purge_abc_obj_files
459 {
460 my $last_abc_config_file = $current_dir . "/.abc_config";
461 my $abc_config_changed = 1;
462
463 if (-e $last_abc_config_file)
464 {
465 open (IN, $last_abc_config_file)
466 or die "ERROR: could not open file \"" . $last_abc_config_file . "\" ($!),";
467
468 while (<IN>)
469 {
470 chomp;
471 if (/ABC config = $hw_variant$/)
472 {
473 # still using the same ABC config as the last build
474 $abc_config_changed = 0;
475 print "ABC config not changed since the last build, keeping layer 1 *.obj files.\n";
476 }
477 }
478 close IN;
479 }
480
481 if ($abc_config_changed == 1)
482 {
483 # udpate .abc_config with current ABC config ($hw_variant)
484 open (OUT, ">$last_abc_config_file")
485 or die "ERROR: could not write to file \"" . $last_abc_config_file . "\" ($!),";
486 print OUT "This file is auto-generated, do not change!\nCurrent ABC config = " . $hw_variant . "\n";
487 close OUT;
488
489 # remove L1 .obj files
490 print "Removing all *.obj files in \"" . $hw_layer1 . "\" and below
491 (currently necessary to properly re-compile when the ABC config changed)\n\n";
492 find (\&rm_file, $hw_layer1);
493 }
494 }
495
496
497 #-------------------------------------------------------------------------------
498 # Check/Initialize some necessary env. variables:
499 # - %PATH must contain gpf/bin, gpf/tools/bin, chipsetsw/system (in that order)
500 # - %C_DIR must only contain slashes (no backslashes, semicolons)
501 #-------------------------------------------------------------------------------
502 sub init_environment
503 {
504 my $current_drive_winformat = $current_drive;
505 $current_drive_winformat =~ s:/:\\:g;
506
507 # check if all necessary paths are in %PATH, add them if not (this removes
508 # the dependency on initvars.bat)
509 if (!($ENV{'PATH'} =~ m:[\\/]chipsetsw[\\/]system:))
510 {
511 # add \chipsetsw\system to %PATH (should be third)
512 $ENV{'PATH'} = "$current_drive_winformat\\chipsetsw\\system;" . $ENV{'PATH'};
513 print "%PATH : \"$current_drive_winformat\\chipsetsw\\system\" + %PATH\n";
514 }
515
516 if (!($ENV{'PATH'} =~ m:[\\/]gpf[\\/]tools[\\/]bin:))
517 {
518 # add \gpf\tools\bin to %PATH (should be second)
519 $ENV{'PATH'} = "$current_drive_winformat\\gpf\\tools\\bin;" . $ENV{'PATH'};
520 print "%PATH : \"$current_drive_winformat\\gpf\\tools\\bin\" + %PATH\n";
521 }
522
523 if (!($ENV{'PATH'} =~ m:[\\/]gpf[\\/]bin:))
524 {
525 # add \gpf\bin to %PATH (should be first)
526 $ENV{'PATH'} = "$current_drive_winformat\\gpf\\bin;" . $ENV{'PATH'};
527 print "%PATH : \"$current_drive_winformat\\gpf\\bin\" + %PATH\n";
528 }
529
530 # check correct setting of environment variables for TI compiler and linker
531 # PATH_CC_1_22e=C:\tools\TMS4701x_1.22e\NT
532 die "\nERROR: environment variable %PATH_CC_1_22e must be set!\n"
533 unless exists($ENV{'PATH_CC_1_22e'});
534 $ENV{'PATH_CC_1_22e'} =~ s|\\|/|g;
535 $ENV{'PATH_CC_1_22e'} =~ s|;.*||;
536 print "%PATH_CC_1_22e : \"" . $ENV{'PATH_CC_1_22e'} . "\"\n";
537
538
539 # PATH_LNK_1_9902=C:\tools\vislink_1.9902
540 die "\nERROR: environment variable %PATH_LNK_1_9902 must be set!\n"
541 unless exists($ENV{'PATH_LNK_1_9902'});
542 $ENV{'PATH_LNK_1_9902'} =~ s|\\|/|g;
543 $ENV{'PATH_LNK_1_9902'} =~ s|;.*||;
544 print "%PATH_LNK_1_9902 : \"" . $ENV{'PATH_LNK_1_9902'} . "\"\n";
545
546 } # init_environment
547
548 #-------------------------------------------------------------------------------
549 # Return "<view-name> (type: <view-type>)" or "none":
550 # <view-name>: CC view name/"unknown"
551 # <view-type>: CC view type ("dynamic/snapshot/unknown")
552 # Check view text mode, which must be 'unix' (aka 'transparent mode').
553 #-------------------------------------------------------------------------------
554 sub determine_view_context
555 {
556 # check if using CC dynamic/snapshot view or no view at all
557 my $view_details = `cleartool lsview -long -properties -full -cview 2>&1`;
558 my $cc_view;
559
560 if ($? == 0)
561 {
562 # store view name + view type (dynamic/snapshot)
563 if ($view_details =~ /Tag:\s*(\w+)/)
564 {
565 $cc_view = $1;
566 }
567 else
568 {
569 print "\nWARNING: Could not determine current view name.\n";
570 $cc_view = "unknown";
571 }
572
573 if ($view_details =~ /Properties: (\w+)/)
574 {
575 $cc_view .= " (type: " . $1 . ")";
576 }
577 else
578 {
579 print "WARNING: Could not determine view type (dynamic/snapshot).\n";
580 $cc_view .= " (type: unknown)";
581 }
582
583 # check view text mode (_must_ be "unix", otherwise most GNU tools like
584 # gnumake don't work properly!)
585 if ($view_details =~ /Text mode: (\w+)/)
586 {
587 if ($1 ne "unix")
588 {
589 die "\nERROR: Wrong text mode (found \"$1\", should be \"unix\") of CC view $cc_view, aborting";
590 }
591 }
592 }
593 else
594 {
595 $cc_view = "none";
596 }
597 return $cc_view;
598 } # determine_view_context
599
600 #-------------------------------------------------------------------------------
601 # Check for gnumake/clearmake availability, returns gnumake/clearmake depending
602 # on view context ($dynamic_view) and user choice ($o_make)
603 #-------------------------------------------------------------------------------
604 sub determine_make_tool
605 {
606 my $cmake;
607 my $gmake;
608 my $use_make;
609
610 # checking for clearmake/gnumake availability
611 my ($rc) = int (system("gnumake -ver > NUL 2>&1") / 256);
612
613 if($rc == 0){
614 $gmake = "gnumake";
615 }
616
617 # choosing the "right" make (gnumake for all kind of views)
618 if (defined($gmake)) {
619 $use_make = $gmake;
620 }
621 else {
622 die "\nERROR: No appropriate gnumake tool found, aborting";
623 }
624
625 # checking for user supplied make
626 if (defined($o_make) && ($o_make =~ /clearmake/i) && defined($cmake)) {
627 die "\nERROR: Clearmake make tool no longer supported, aborting";
628 }
629 elsif (defined($o_make) && ($o_make =~ /gnumake/i) && defined($gmake)) {
630 $use_make = $gmake;
631 }
632 elsif (defined($o_make)) {
633 die "\nERROR: Specified make tool \"$o_make\" not found or not supported, aborting";
634 }
635
636 return $use_make;
637 }
638
639
640 #-------------------------------------------------------------------------------
641 # Check which GCC variant (Cygwin/MingW) and which version is installed,
642 # return GCC version and set %GCC env. variable to run this GCC variant in ABC.
643 #-------------------------------------------------------------------------------
644 sub determine_gcc_version
645 {
646 my $gcc_ver = `gcc --version 2>&1`;
647 if ($? == 0)
648 {
649 # only keep the first line of GCC version string
650 $gcc_ver =~ s/\n.*$//s;
651
652 # Nice GCC variant: Cygwin
653 $ENV{'GCC'} = "\@gcc";
654 }
655 else
656 {
657 $gcc_ver = `cpp --version 2>&1`;
658 if ($? == 0)
659 {
660 # only keep the first line of GCC version string
661 $gcc_ver =~ s/\n.*$//s;
662
663 # Berlin GCC variant: MingW (defines WIN32 by default which is
664 # interpreted by Nice SW as 'simulation build')
665 $ENV{'GCC'} = "\@cpp -UWIN32";
666 }
667 else
668 {
669 die "\nERROR: GCC not found (gcc.exe/cpp.exe not installed or not in the path), aborting";
670 }
671 }
672
673 return $gcc_ver;
674 }
675
676
677 #-------------------------------------------------------------------------------
678 # Check if cl.exe (shipped with MS Visual Studio/VC++) is installed in the path,
679 # return version string and indicate whether ccddata_dll.dll can be built
680 # ($generate_ccddata_dll = 1) or not (= 0)
681 #-------------------------------------------------------------------------------
682 sub determine_cl_version
683 {
684 my $cl_ver = `cl.exe 2>&1`;
685 if ($? == 0)
686 {
687 # only keep the first line of version string
688 chomp $cl_ver;
689 $cl_ver =~ s/\n.*$//s;
690
691 # indicate that ccddata_dll.dll should be built
692 $generate_ccddata_dll = 1;
693 }
694 else
695 {
696 $cl_ver = "not found, unable to generate ccddata_dll.dll";
697
698 # indicate that ccddata_dll.dll should not be built
699 $generate_ccddata_dll = 0;
700 }
701
702 return $cl_ver;
703 }
704
705
706 #-------------------------------------------------------------------------------
707 # Check if Java is installed (in the path), return version string of Java.
708 #-------------------------------------------------------------------------------
709 sub determine_java_version
710 {
711 my $java_ver = `java -version 2>&1`;
712 if ($? == 0)
713 {
714 # only keep the first line of java version string and remove "java", if present
715 $java_ver =~ s/\n.*$//s;
716 $java_ver =~ s/\s*java\s*//;
717 }
718 else
719 {
720 die "\nERROR: Java not found (not installed or not in the path), aborting";
721 }
722
723 return $java_ver;
724 }
725
726
727 #-------------------------------------------------------------------------------
728 # Extract some globals from a given makefile
729 # 1) $cdginc_dir
730 # 2) $cdginc_tools_dir
731 # 3) $target_image
732 # 4) $has_target_named_mconst
733 # 5) @busyb_libs
734 #-------------------------------------------------------------------------------
735 sub extract_globals_from_makefile
736 {
737 my ($makeFile) = @_;
738
739 my $grab_libs = 0;
740 my $grab_irlibs = 0;
741 my $grab_irplacements = 0;
742 my $lib_no = 0;
743
744 open (IN, $makeFile)
745 or die "ERROR: could not open file \"" . $makeFile . "\" ($!),";
746
747 while (<IN>)
748 {
749 if (/.*(__out__\/.+\/cdginc)\/mconst\.cdg/)
750 {
751 # grep cdginc directory from generated makefile
752 $cdginc_dir = $1;
753 }
754 elsif (/.*(__out__\/.+\/cdginc[^ \/]+)/)
755 {
756 # grep cdginc_tools dir from generated makefile (take anything which
757 # starts with "cdginc" but w/o blank or slash directly afterwards)
758 $cdginc_tools_dir = $1;
759 }
760 elsif (/(__out__\/.+\.out):/)
761 {
762 # grep target image (.out) name (w/ complete path) from generated
763 # makefile for step 9
764 $target_image = $1;
765
766 # start grabbing libs (from next line on)
767 $grab_libs = 1;
768 }
769 elsif ($grab_libs and /\s+(\S+)\s*([\\]*)/)
770 {
771 # disable lib-grabbing if last lib (i.e. no "\" at end of line)
772 if ($2 eq "")
773 {
774 $grab_libs = 0;
775 }
776 # skip any make variables
777 next if ($1 =~ /\$\(/);
778 # skip the linker command file (*.lcf)
779 next if ($1 =~ /.*\.lcf/);
780 # skip all libs stored in chipsetsw VOB
781 next if ($1 =~ /chipsetsw\//);
782
783 # store lib in @busyb_libs
784 push @busyb_libs, $1;
785 }
786 elsif (/__out__.+\.lcf:\s*(\w*)\s*\\/)
787 {
788 # start grabbing intram libs
789 $grab_irlibs = 1;
790 }
791 elsif ($grab_irlibs and /\s+(\S+)\s*([\\]*)/)
792 {
793 # disable lib-grabbing if last lib (i.e. "\" at end of line),
794 # start grabbing ir-placements instead
795 if ($2 eq "")
796 {
797 $grab_irlibs = 0;
798 $grab_irplacements = 1;
799 }
800
801 # skip any make variables
802 next if ($1 =~ /\$\(/);
803 # skip linker command file template
804 next if ($1 =~ /\.template/);
805
806 # store lib in @intram_libs
807 push @intram_libs, $1;
808 }
809 elsif ($grab_irplacements and /\$\(BSB_ECHO\)\s+(\(.*\))\s*>/)
810 {
811 # grab intram lib placements
812 # skip any make variables (e.g. $SSA_INT_RAM_PLACEMENT)
813 next if ($1 =~ /\$\(/);
814
815 # need to store each placement with the correct lib
816 $intram_libs[$lib_no] .= " $1";
817 $lib_no++;
818 }
819 elsif ($grab_irplacements and /make_cmd\.pl/)
820 {
821 # stop grabbing intram lib placements
822 $grab_irplacements = 0;
823 }
824 elsif (/^mconst:/)
825 {
826 $has_target_named_mconst = 1;
827 }
828 elsif (/chipsetsw\/system\/deps_objs\/(\w+)\// and !defined($hw_system_objects))
829 {
830 # grep Nice deps_objs dir (different for each ABC config)
831 $hw_system_objects = $1;
832 }
833 }
834 close IN;
835 } # extract_globals_from_makefile
836
837
838 sub step__check_environment
839 {
840 print_status ($_[0] . ". Checking environment");
841
842 # create the makefile filename
843 my $dir = (File::Spec->splitpath($o_file))[1]; #FIXME: remove this, we don't seem to need it anymore
844 $makeFile = (File::Spec->splitpath($o_file))[2];
845 $makeFile =~ s/(.*)\..*/$1.mak/;
846
847 # generate *.abc_exports.mak filename
848 $abc_exports = $makeFile;
849 $abc_exports =~ s/\.mak$//;
850 $abc_exports = $abc_exports . ".abc_exports.mak";
851
852 # initialize necessary env. variables (%PATH, %C_DIR)
853 init_environment();
854
855 # get view name, view type (dynamic/snapshot/none), and check text mode for
856 # dynamic views (must be 'unix')
857 my $view = determine_view_context();
858 print "CC View : $view\n";
859
860 # check for clearmake & gnumake, determine if user specified make exists
861 $make = determine_make_tool ($view);
862 print "Make : using \"$make\" for the build\n";
863
864 # check installed GCC variant (gcc.exe/cpp.exe), set %GCC env. variable for ABC
865 my $gcc_version = determine_gcc_version();
866 print "GCC : " . $gcc_version . ", using \"" . $ENV{'GCC'} . "\" for ABC\n";
867
868 # check installed cl.exe version (part of MS Visual Studio/VC++)
869 my $cl_version = determine_cl_version();
870 print "cl.exe : $cl_version\n";
871
872
873 # determine input file format: XML (default), or make (*.mak)
874 $called_with_mak_file = ($o_file =~ /.*\.mak/);
875 if ($called_with_mak_file)
876 {
877 print "Input : Makefile format (will skip several steps during build)\n";
878
879 # set global variables $cdginc_dir, $target_image, and
880 # $has_target_named_mconst, which are needed to determine further steps
881 extract_globals_from_makefile ($makeFile);
882 }
883 else
884 {
885 print "Input : XML format\n";
886
887 # extract_globals_from_makefile() is only possible after step 2, where the
888 # makefile is being created
889 }
890
891
892 # only check if Java is installed, if input is XML (i.e. we need to generate
893 # everything ourselves) _or_ if input is MAK and we have a target "mconst:"
894 my $java_version;
895 if ((not ($called_with_mak_file)) or
896 (($called_with_mak_file) and ($has_target_named_mconst)))
897 {
898 $java_version = determine_java_version();
899 }
900 else
901 {
902 $java_version = "not necessary";
903 }
904 print "Java : " . $java_version . "\n";
905
906
907 # set environment variable %BUSYB_PREFIX, which is being used in ABCs master.mak
908 # (is necessary for supporting old Berlin build system in parallel)
909 $busyb_prefix = $makeFile;
910 $busyb_prefix =~ s/\.mak$/\./;
911 $ENV{'BUSYB_PREFIX'} = $busyb_prefix;
912 print "Prefix : BUSYB_PREFIX=" . $busyb_prefix . "\n";
913 }
914
915
916 sub step__parse_input_file
917 {
918 print_status ($_[0] . ". Parsing input file ($o_file)");
919
920 if (!parse_file ($o_file))
921 {
922 die "ERROR: Either HW_VARIANT or L1 property missing in file \"$o_file\", aborting";
923 }
924
925 if (defined($l1_variant))
926 {
927 print "L1: " . $l1_variant . "\n";
928 }
929 else
930 {
931 print "L1 : Not defined\n"
932 }
933 if (defined($hw_variant))
934 {
935 print "HW variant: " . $hw_variant . "\n";
936 }
937 else
938 {
939 print "HW variant : Not defined - Compiling with Unified BuSyB\n"
940 }
941
942 }
943
944
945 #-------------------------------------------------------------------------------
946 # update BuSyB makefile, if necessary; takes an additional second parameter
947 # to specify the BuSyB .ini file
948 #-------------------------------------------------------------------------------
949 sub step__update_busyb_makefile
950 {
951 print_status ($_[0] . ". Updating BuSyB makefile ($makeFile)");
952
953 $command = "$make -f $t_updtBusyb MFILE=$makeFile XMLFILE=$o_file ABC_EXPORTS_MAKEFILE_NAME=$abc_exports";
954 if (defined ($_[1]))
955 {
956 $command .= " BUSYB_INI_FILE=$_[1]";
957 }
958 print "$command\n\n";
959
960 system($command) == 0
961 or die "ERROR: Can't create makefile \"$makeFile\" ($!), aborting";
962 print "\n";
963
964 # set global variables $cdginc_dir, $target_image, and $has_target_named_mconst,
965 # which are needed to determine further steps (in case $called_with_mak_file
966 # is not true, see step__check_environment())
967 extract_globals_from_makefile ($makeFile);
968
969 # generate clearmake build option specification (<makefile>.options),
970 # regardless if using clearmake or gnumake in order to have this file
971 # available in case one first wants to use gnumake and switches later on
972 # to clearmake
973 open (BOS, ">$makeFile.options")
974 or die "ERROR: could not write to file \"" . $makeFile . ".options\" ($!),";
975 print BOS "# clearmake build option specification (BOS) file
976
977 # this clearmake-specific rule causes clearmake to treat the logfile as a
978 # view-private file and not as a derived object (which causes several problems
979 # during the initial and subsequent builds with clearmake)
980 .NO_DO_FOR_SIBLING: " . $o_logfile . "\n";
981 close BOS;
982 }
983
984
985 sub step__busyb_create_directories
986 {
987 print_status ($_[0] . ". Creating directories ($make)");
988
989 # create all the directories using the BUSYB makefile
990
991 $command = "$make -f $makeFile MAKEDEPEND=0 allOutDirs";
992 print "$command\n\n";
993
994 system($command) == 0
995 or die "ERROR: Can't create directories ($!), aborting";
996 print "\n";
997 }
998
999
1000 sub step__busyb_process_interfaces
1001 {
1002 print_status ($_[0] . ". Processing SAP/MSG interfaces ($make)");
1003
1004 # process SAP/MSG documents using the BUSYB makefile
1005
1006 $command = "$make -f $makeFile MAKEDEPEND=0 mconst";
1007 print "$command\n\n";
1008
1009 system($command) == 0
1010 or die "ERROR: Can't process SAP/MSG documents ($!), aborting";
1011 print "\n";
1012 }
1013
1014
1015 #-------------------------------------------------------------------------------
1016 # generate ccddata_dll.dll (requires cl.exe, see determine_cl_version() above)
1017 #-------------------------------------------------------------------------------
1018 sub step__generate_ccddata_dll
1019 {
1020 if ($generate_ccddata_dll)
1021 {
1022 print_status ($_[0] . ". Generating ccddata_dll.dll ($make)");
1023
1024 chdir $gpf_ccd
1025 or die "ERROR: Can't cd to \"$gpf_ccd\" ($!), aborting";
1026
1027 #FIXME: PROJECT=gprs may always be used...? Check with Henning.
1028 my $out_dir = $cdginc_tools_dir;
1029 $out_dir =~ s:/cdginc.+::;
1030
1031 $command = "$make -f ccddata.mk TARGET=win32 PROJECT=gprs \
1032 GPF=$gpf_root \
1033 CCDDATA_LIB=$current_dir/$out_dir/bin/ccddata_dll.dll \
1034 CDGINCDIR=$current_dir/$cdginc_tools_dir \
1035 OBJDIR=$current_dir/$cdginc_tools_dir";
1036 print "$command\n\n";
1037
1038 system($command) == 0
1039 or print "WARNING: Error while executing ccddata.mk ($!), continuing build.\n";
1040 print "\n";
1041
1042 chdir $current_dir
1043 or die "ERROR: Can't cd to \"$current_dir\" ($!), aborting";
1044 }
1045 else
1046 {
1047 print_status ($_[0] . ". Skipping ccddata_dll.dll generation (cl.exe not found)");
1048 }
1049 }
1050
1051
1052 #-------------------------------------------------------------------------------
1053 # generate makefiles <variant>_condat_lib_ip.mak and <variant>_condat_var.mak for ABC
1054 #-------------------------------------------------------------------------------
1055 sub step__generate_interface_for_abc
1056 {
1057 print_status ($_[0] . ". Generate interface for ABC (<variant>_condat_*.mak)");
1058
1059 $condat_lib_ip_mak = $busyb_prefix . "condat_lib_ip.mak";
1060 $condat_var_mak = $busyb_prefix . "condat_var.mak";
1061
1062 print "cdginc output dir: \"" . $cdginc_dir . "\"\n\n";
1063
1064 # Berlin libs
1065 my $berlin_libs;
1066 foreach my $lib (@busyb_libs)
1067 {
1068 $berlin_libs .= " \$(CONDAT_BASE_DIR)/../$lib";
1069 }
1070
1071 # Berlin intram libs + their placements
1072 my $berlin_bss_libs;
1073 my $berlin_const_libs;
1074 foreach my $place (@intram_libs)
1075 {
1076 next if ($place =~ /chipsetsw\//);
1077 if ($place =~ /BSS_LIBS/)
1078 {
1079 (my $bss = $place) =~ s/CONST_LIBS\s+\(.*\)//;
1080 $bss =~ s/\(+BSS_LIBS\s+(\([^)]+\))/$1/;
1081 $berlin_bss_libs .= " \$(CONDAT_BASE_DIR)/../$bss"
1082 if ($bss ne "");
1083 }
1084 if ($place =~ /CONST_LIBS/)
1085 {
1086 (my $const = $place) =~ s/BSS_LIBS\s+\(\.\w+\)\s+//;
1087 $const =~ s/\(+CONST_LIBS\s+(\([^)]+\))\)*/$1/;
1088 $berlin_const_libs .= " \$(CONDAT_BASE_DIR)/../$const"
1089 if ($const ne "");
1090 }
1091 }
1092
1093 # generate <variant>.condat_lib_ip.mak
1094 print "Generating condat/" . $condat_lib_ip_mak . "\n";
1095 open (CONDAT_LIB_IP, ">condat/" . $condat_lib_ip_mak)
1096 or die "ERROR: could not open file \"condat/" . $condat_lib_ip_mak . "\" for writing ($!),";
1097 print CONDAT_LIB_IP "# This file is auto-generated, do not change!
1098 ifndef CONDAT_LIB_IP_MAK # to avoid multiple condat_lib_ip.mak (import + include)
1099 export CONDAT_LIB_IP_MAK := 1
1100
1101 ifndef GPF_DIR
1102 export GPF_DIR := \$(CONDAT_BASE_DIR)/../../gpf
1103 export CONDAT_DIR := \$(CONDAT_BASE_DIR)
1104 endif
1105
1106 L23_NAMES := \$(NCMPMODE)\$(NMMI)\$(NPMODE)\$(NPKTIO)\$(NSRVC)\$(NSTD)\$(NTK)\$(NWAP)\$(NGAME)\$(NEMS)\$(NMMS)\$(NHZONE)\$(NUNIC)\$(NCHIMMI)\$(NETXT)\$(NPDU)\$(NPS)\$(NEM)\$(NDP)\$(NCOMPTRC)\$(NEOTD)\$(NTTY)\$(NCPHS)\$(NBT)
1107
1108 export CONDAT_INCLUDES := \$(CONDAT_BASE_DIR)/com/include \$(CONDAT_BASE_DIR)/ms/src/l1 \$(GPF_DIR)/frame/cust_os \$(CONDAT_BASE_DIR)/com/src/comframe/configps \$(GPF_DIR)/inc
1109
1110 export CONDAT_LIBS :=" . $berlin_libs . "
1111
1112 export CONDAT_BSS_LIBS :=" . $berlin_bss_libs . "
1113 export CONDAT_CONST_LIBS :=" . $berlin_const_libs . "
1114
1115 # extracted from " . $makeFile . "
1116 export ICDG=\$(CONDAT_BASE_DIR)/../" . $cdginc_dir . "
1117 export SRCACI=\$(CONDAT_BASE_DIR)/ms/src/aci
1118 export SRCACIDTIMNG=\$(CONDAT_BASE_DIR)/ms/src/aci_dti_mng
1119 export SRCACIA=\$(CONDAT_BASE_DIR)/ms/src/acia
1120 export SRCKSD=\$(CONDAT_BASE_DIR)/ms/src/ksd
1121
1122 endif # ifndef CONDAT_LIB_IP_MAK\n";
1123 close CONDAT_LIB_IP;
1124
1125 # generate <variant>.condat_var.mak
1126 print "Generating condat/" . $condat_var_mak . "\n";
1127
1128 # put all feature flags in <variant>.condat_var.mak, except for
1129 # L1, CHIPSET, BOARD, COPY_DOCS, BUILD_UTILITIES, CMP_MODE, MAKE_DEPENDENCIES,
1130 # since these are not relevant for ABC
1131 $condat_var_variables = $makeVars;
1132 $condat_var_variables =~ s/ /\nexport /g;
1133 $condat_var_variables =~ s/\nexport L1=/\n#export L1=/;
1134 $condat_var_variables =~ s/\nexport CHIPSET=/\n#export CHIPSET=/;
1135 $condat_var_variables =~ s/\nexport BOARD=/\n#export BOARD=/;
1136 $condat_var_variables =~ s/\nexport COPY_DOCS=/\n#export COPY_DOCS=/;
1137 $condat_var_variables =~ s/\nexport BUILD_UTILITIES=/\n#export BUILD_UTILITIES=/;
1138 $condat_var_variables =~ s/\nexport CMP_MODE=/\n#export CMP_MODE=/;
1139 $condat_var_variables =~ s/\nexport MAKE_DEPENDENCIES=/\n#export MAKE_DEPENDENCIES=/;
1140
1141 open (CONDAT_VAR, ">condat/" . $condat_var_mak)
1142 or die "ERROR: could not open file \"condat/" . $condat_var_mak . "\" for writing ($!),";
1143 print CONDAT_VAR "# This file is auto-generated, do not change!
1144 ifndef CONDAT_VAR_MAK # to avoid multiple condat_var.mak (import + include)
1145 export CONDAT_VAR_MAK := 1
1146
1147 # matching " . $o_file . ":
1148 # all feature flags, except for L1, CHIPSET, BOARD, COPY_DOCS, BUILD_UTILITIES, CMP_MODE, MAKE_DEPENDENCIES
1149 " . $condat_var_variables . "
1150
1151 endif # ifndef CONDAT_VAR_MAK\n";
1152 close CONDAT_VAR;
1153 } # generate_interface_for_abc
1154
1155
1156 sub step__update_abc_config
1157 {
1158 print_status ($_[0] . ". Updating ABC config ($t_updtAbc)");
1159
1160 chdir $hw_system
1161 or die "ERROR: Can't cd to \"$hw_system\" ($!), aborting";
1162
1163 $command = "$t_perl $t_updtAbc $hw_variant";
1164 print "$command\n\n";
1165
1166 system($command) == 0
1167 or die "ERROR: Execution of \"$t_updtAbc\" failed ($!), aborting";
1168
1169 chdir $current_dir
1170 or die "ERROR: Can't cd to \"$current_dir\" ($!), aborting";
1171 }
1172
1173
1174 #-------------------------------------------------------------------------------
1175 # generate include makefile for SSA filenames
1176 #-------------------------------------------------------------------------------
1177
1178 sub step__extract_abc_variables
1179 {
1180 print_status ($_[0] . ". Extracting ABC variables for Berlin SW ($abc_exports)");
1181
1182 my $command;
1183
1184 $command = "$make -f $t_updtBusybInc ABC_EXPORTS_MAKEFILE_NAME=$abc_exports $makeVars";
1185 print "$command\n\n";
1186
1187 system($command) == 0
1188 or die "ERROR: Execution of \"" . $t_updtBusybInc . "\" failed ($!),\n";
1189 print " \n";
1190
1191 if (! -e $abc_exports) {
1192 die "ERROR: File \"$abc_exports\" has not been generated\n"
1193 }
1194 } # extracting_abc_variables
1195
1196
1197
1198 #-------------------------------------------------------------------------------
1199 # compiling nice sw using abc
1200 #-------------------------------------------------------------------------------
1201 sub step__abc_compilation
1202 {
1203 print_status ($_[0] . ". Compiling Nice SW ($t_abc)");
1204
1205 my $command;
1206
1207 # remove some .obj files in the \chipsetsw VOB due to ABC dependency errors
1208 # (temporary solution!)
1209 ##purge_abc_obj_files();
1210 print "\n";
1211
1212 # compile Nice software w/ ABC
1213 chdir $hw_system
1214 or die "ERROR: Can't cd to \"" . $hw_system . "\" ($!),";
1215
1216 $command = "$t_perl $t_abc $hw_variant";
1217 if ($abc_opt)
1218 {
1219 $command .= " -x\"$abc_opt\"";
1220 }
1221 print "$command\n\n";
1222
1223 my $res = system($command);
1224
1225 if ($res != 0)
1226 {
1227 print_status ("ERROR: BUILD FAILED!");
1228 exit 1;
1229 }
1230
1231 chdir $current_dir
1232 or die "ERROR: Can't cd to \"" . $current_dir . "\" ($!),";
1233 } # compiling_nice_sw
1234
1235
1236
1237 #-------------------------------------------------------------------------------
1238 # finally run make w/ the generated makefile from BuSyB
1239 #-------------------------------------------------------------------------------
1240
1241 sub step__busyb_compilation
1242 {
1243 print_status ($_[0] . ". Running BuSyB makefile ($make)");
1244
1245 # Start progress bar display mechanism
1246 start_progress_bar_display();
1247
1248 my $command;
1249
1250 $command = "$make -f $makeFile$make_opt";
1251 print "$command\n\n";
1252
1253 if ((system($command) == 0) and (-e $target_image))
1254 {
1255 print_status ("Build succeeded");
1256 $exit_value = 0;
1257 }
1258 else
1259 {
1260 print_status ("ERROR: BUILD FAILED!");
1261 $exit_value = 1;
1262 }
1263 # Kill child process if it exists
1264 if ($list_of_libs_available == 1) {kill 2, $pid; }
1265 }
1266
1267
1268
1269 sub step__busyb_generate_l1_configdef_files
1270 {
1271 print_status ($_[0] . ". Generating Layer1 ConfigDef files");
1272
1273 chdir ("$hw_layer1\\tools")
1274 or die "ERROR: Can't cd to \"" . $hw_system . "\" ($!),";
1275
1276 $command = "perl -w $hw_system\\Scripts\\L1Config.pl";
1277 print "$command\n\n";
1278
1279 system($command) == 0
1280 or die "ERROR: Execution of \"" . $command . "\" failed ($!),";
1281
1282 chdir $current_dir
1283 or die "ERROR: Can't cd to \"" . $current_dir . "\" ($!),";
1284 }
1285
1286
1287 sub step__busyb_generate_cfg_files
1288 {
1289 print_status ($_[0] . ". Generating .cfg files ($make)");
1290
1291 $command = "$make -f $makeFile cfg_files";
1292 print "$command\n\n";
1293
1294 system($command) == 0
1295 or die "ERROR: Execution of \"" . $command . "\" failed ($!),";
1296
1297 }
1298
1299
1300 sub step__busyb_generate_header_files
1301 {
1302 print_status ($_[0] . ". Generating header files ($make)");
1303
1304 $command = "$make -f $makeFile header_files";
1305 print "$command\n\n";
1306
1307 system($command) == 0
1308 or die "ERROR: Execution of \"" . $command . "\" failed ($!),";
1309
1310 }
1311
1312
1313 sub step__init_icl470_environment
1314 {
1315 print_status ($_[0] . ". Init icl470 environment");
1316
1317 print "%TEMPORARY_FILE_DIR: \"" . $hw_system . "/deps_objs/" . $hw_system_objects . "\"\n\n";
1318
1319 $ENV{'TEMPORARY_FILE_DIR'} = $hw_system . "/deps_objs/" . $hw_system_objects;
1320 }
1321
1322 #-------------------------------------------------------------------------------
1323 # this function is used by find() (File::Find) above and removes all found
1324 # *.obj files (NOTE: some are checked-in, so unlink() will fail)
1325 #-------------------------------------------------------------------------------
1326 sub rm_file
1327 {
1328 unlink ($_)
1329 if /.*\.obj$/;
1330 }
1331
1332
1333 #-------------------------------------------------------------------------------
1334 # redirect STDOUT+STDERR to $o_logfile, return 1 if redirection successful or
1335 # 0 if redirection failed
1336 #-------------------------------------------------------------------------------
1337 sub redirect_output
1338 {
1339 my $redirected = 1;
1340
1341 open (CONSOLE_OUT, ">&STDOUT");
1342 open (CONSOLE_ERR, ">&STDERR");
1343
1344 open (STDOUT, '>', $o_logfile)
1345 or $redirected = 0;
1346 open (STDERR, ">&STDOUT")
1347 or $redirected = 0;
1348
1349 if ($redirected)
1350 {
1351 # make output unbuffered
1352 select (STDERR); $| = 1;
1353 select (STDOUT); $| = 1;
1354
1355 # install signal handler function for die()
1356 $SIG{__DIE__} = \&die_handler
1357 or print CONSOLE_ERR "WARNING: Could not install die() signal handler,
1358 console output may be corrupted when exiting with an error!\n";
1359 }
1360 else
1361 {
1362 # redirection failed: use old STDOUT+STDERR
1363 restore_redirection();
1364
1365 print "WARNING: Could not redirect STDOUT+STDERR to " . $o_logfile . ",
1366 not logging output!\n";
1367 }
1368
1369 return $redirected;
1370 }
1371
1372
1373 #-------------------------------------------------------------------------------
1374 # close logging to $o_logfile and restore old STDOUT+STDERR
1375 # (pointing to console)
1376 #-------------------------------------------------------------------------------
1377 sub restore_redirection
1378 {
1379 # restore redirected STDOUT+STDERR
1380 close (STDOUT);
1381 close (STDERR);
1382
1383 open (STDOUT, ">&CONSOLE_OUT");
1384 open (STDERR, ">&CONSOLE_ERR");
1385 }
1386
1387
1388 #-------------------------------------------------------------------------------
1389 # print die() error message, to also log it to $o_logfile and then restore
1390 # the STDOUT+STDERR redirection
1391 #-------------------------------------------------------------------------------
1392 sub die_handler
1393 {
1394 print STDERR $_[0];
1395
1396 restore_redirection();
1397 }
1398
1399 #-------------------------------------------------------------------------------
1400 # Get number of libraries that have to be generated and display a 'progress bar'
1401 # during the build according to the number of rebuilt libraries
1402 #-------------------------------------------------------------------------------
1403
1404 sub start_progress_bar_display
1405 {
1406 # Get libraries list
1407 my @libraries = () ;
1408 my %libDates ;
1409 my $total_lib = 0;
1410 my $line;
1411
1412 open (IN, "<$makeFile")
1413 or die "ERROR: could not open file \"" . $makeFile . "\" ($!),";
1414
1415 while(defined($line = <IN>))
1416 {
1417 # Check if variable BSB_TARGETS_ALL exists in the makefile
1418 if ( ( $line =~ /^BSB_TARGETS_ALL\s*=\s*([^\s]*)\s*(\\*)/ ) ||
1419 ( ( $line =~ /\s*([^\s]*)\s*(\\*)/ ) && ( $list_of_libs_available == 1 ) ) )
1420 {
1421 my $cur_lib = $1 ;
1422 my $end = $2 ;
1423 $list_of_libs_available = 1 ;
1424
1425 if ( $cur_lib =~ m/\.lib$/ )
1426 {
1427 push( @libraries, $cur_lib ) ;
1428 }
1429
1430 if ( $end eq "" ) {last;}
1431 next ;
1432 }
1433 }
1434 $total_lib = $#libraries + 1;
1435
1436 # Retrieve current time (this allows to make time dif with future generated libraries)
1437 my $mytime = time;
1438
1439 # If the list of libraries is available, create the process which take care about the progress
1440 # and start display progress
1441 if ($list_of_libs_available == 1)
1442 {
1443 # Create the process to display the progress bar
1444 defined($pid = fork)
1445 or die "Cannot fork: $!";
1446
1447 # If child process
1448 unless ($pid)
1449 {
1450 # Flush Output buffer
1451 select CONSOLE_OUT;
1452 $| = 1;
1453
1454 # The child process is stopped when the build is finished
1455 while (1)
1456 {
1457 # For the algorithm, we guess that the list of libraries in the array are ordered
1458 # in the same way that BuSyB compile these one. This means if the lib at index n
1459 # has been rebuilt, that means 100*n/total_lib have been rebuilt (where
1460 # total_libs is the number of libs that contribute to the image file)
1461 my $i = 0;
1462 foreach (reverse( @libraries ))
1463 {
1464 my $mlib = "$_" ;
1465 if (-e $mlib) # Check if the library exist
1466 {
1467 if ( ( stat( $mlib ) )[ 10 ] > $mytime ) # Check if the file has been rebuilt
1468 {
1469 last;
1470 }
1471 else
1472 {
1473 $i++;
1474 }
1475 }
1476 else {$i++;} # If the library does not exist, we continue with the
1477 #previous library in the array
1478 }
1479 my $nb_generated_libs = $total_lib - $i;
1480
1481 # Search for the number of files already generated
1482 my $progress;
1483
1484 $progress = sprintf ("%.02d", (100 * $nb_generated_libs)/$total_lib);
1485
1486 print_progress("Progress : " . $progress . "%");
1487
1488 sleep 10;
1489 }
1490 }
1491 }
1492 }
1493