FreeCalypso > hg > tcs211-c139
view g23m/nds_busyb.pl @ 43:52325cb524a8
new README written for the UI-enabled configuration
author | Mychaela Falconia <falcon@ivan.Harhan.ORG> |
---|---|
date | Thu, 05 Nov 2015 08:09:54 +0000 |
parents | 509db1a7b7b8 |
children |
line wrap: on
line source
#!perl -w #----------------------------------------------------------------------------- # Project : # Modul : nds_busyb.pl #----------------------------------------------------------------------------- # Copyright 2003 Texas Instruments Deutschland GmbH # All rights reserved. # # This file is confidential and a trade secret of Texas # Instruments Deutschland GmbH # The receipt of or possession of this file does not convey # any rights to reproduce or disclose its contents or to # manufacture, use, or sell anything it may describe, in # whole, or in part, without the specific written consent of # Texas Instruments Deutschland GmbH. #----------------------------------------------------------------------------- # Purpose : #----------------------------------------------------------------------------- use strict; use File::Copy; use File::Find; use File::Spec; use Cwd; use Getopt::Long qw(:config pass_through); #------------------------------------------------------------------------------- # Variables #------------------------------------------------------------------------------- # misc. variables my $hw_variant; my $l1_variant; my $command; # make tool (gnumake/clearmake) my $make; # makefile file name my $makeFile; my $makeVars; my $condat_var_variables; # specifies whether input file format is XML (default) or make (*.mak) my $called_with_mak_file; # specifies whether there is a "mconst:" target in the makefile or not my $has_target_named_mconst; my @busyb_libs; my @intram_libs; my $current_dir = cwd; # do not only store the drive in $current_drive, but rather store the path # to the current dir (necessary to work directly on V:\<view>\...) my $current_drive = cwd; $current_drive =~ s|[\\/][^\\/]+$||; # path to Nice software (covering SSA, WCP, and SDVK) my $hw_root = $current_dir . "/../chipsetsw"; my $hw_layer1 = $hw_root . "/layer1"; my $hw_system = $hw_root . "/system"; my $hw_system_config = $hw_system . "/config"; # points to the system/deps_objs/<ABC-CONFIG> directory (initialized by # extract_globals_from_makefile() function) my $hw_system_objects; # path to GPF software my $gpf_root = $current_drive . "/gpf"; # we need to honor proper upper and lower case when using clearmake! my $gpf_ccd = $gpf_root . "/CCD"; # BuSyB cdginc output directories (necessary for step 7) my $cdginc_dir; my $cdginc_tools_dir; # BuSyB target image (.out) file name (necessary for step 9) my $target_image; # specifies whether output is being redirected (logged to a file) or not my $outerr_redirected; # specifies whether ccddata_dll.dll can be built (1) or not (0): # this depends on the presence of cl.exe, see also determine_cl_version() and # step__check_environment() my $generate_ccddata_dll; # Generated makefile names my $abc_exports; my $busyb_prefix; my $condat_lib_ip_mak; my $condat_var_mak; # tool definitions my $t_perl = "perl"; my $t_updtBusybInc = "gen_abc_exports.mak"; my $t_updtAbc = "update_exported_makefiles.pl"; my $t_abc = "abc.pl"; my $t_updtBusyb = "system/update_makefile.mak"; # command line options (do not initialize $o_make! -- see step 0 below) my $o_file; my $o_make; my $o_logfile = "report.txt"; my $o_shell = 0; my $o_help = 0; # ABC/make pass-through options my $abc_opt; my $make_opt; # script exit value, being set by last step: step__compile_berlin_sw() my $exit_value; # Variables needed for the progress bar my $list_of_libs_available = 0 ; my $pid; #------------------------------------------------------------------------------- # Main Program #------------------------------------------------------------------------------- # parse command line, passing through all unknown options to make parse_command_line(); # logging is enabled by default (unless $o_shell is set, done by option "-s") if (!$o_shell) { # attempt to redirect STDOUT+STDERR $outerr_redirected = redirect_output(); } else { # do not redirect output, it is being sent to shell $outerr_redirected = 0; } my $build_message = "\nStarting build of " . $o_file . ", REDIRECT_PLACEHOLDER Build may take a while, so please be patient!\n\n"; if ($outerr_redirected) { $build_message =~ s/REDIRECT_PLACEHOLDER/output is being logged to $o_logfile,/; print CONSOLE_OUT $build_message; } else { $build_message =~ s/REDIRECT_PLACEHOLDER/output is NOT being logged!/; print $build_message; } # steps 1 and 2 must always be performed step__check_environment (1); step__parse_input_file (2); # all other steps depend on the input file format, "mconst:" target in the # BuSyB makefile, or hybrid build system vs. unified build system my @build_steps; # determine if UnBuSy or HyBuSy is being used for compilation if (defined($hw_variant)) { # queue HyBuSy (hybrid build system) steps # ($called_with_mak_file is being set in step__check_environment() and is # already known at this point) push @build_steps, \&step__update_busyb_makefile unless $called_with_mak_file; push @build_steps, \&step__busyb_create_directories; push @build_steps, sub { # $has_target_named_mconst may be set as late as in # step__update_busyb_makefile(), so it may not yet be known and we need # to check this at run-time if ($has_target_named_mconst) { # only process SAP/MSG docs if "mconst:" target exists in makefile step__busyb_process_interfaces (@_); } else { # if not, need to decrement $step_no (first parameter of this function) $_[0]--; } }; push @build_steps, sub { # $cdginc_tools_dir may be set as late as in # step__update_busyb_makefile(), so it may not yet be known and we need # to check this at run-time if ($cdginc_tools_dir) { # only generate ccddata_dll.dll if SAP/MSG docs were processed step__generate_ccddata_dll (@_); } else { # if not, need to decrement $step_no (first parameter of this function) $_[0]--; } }; push @build_steps, \&step__generate_interface_for_abc unless $called_with_mak_file; push @build_steps, \&step__update_abc_config; push @build_steps, \&step__extract_abc_variables unless $called_with_mak_file; push @build_steps, \&step__abc_compilation; push @build_steps, \&step__busyb_compilation; } else { # queue UnBuSy (unified build system) steps # ($called_with_mak_file is being set in step__check_environment() and is # already known at this point) # push @build_steps, \&step__busyb_generate_l1_configdef_files; push @build_steps, sub { step__update_busyb_makefile ($_[0], "system/unbusy_g23m.ini"); } unless $called_with_mak_file; push @build_steps, \&step__busyb_create_directories; push @build_steps, \&step__busyb_generate_cfg_files; push @build_steps, \&step__busyb_generate_header_files; push @build_steps, sub { # $has_target_named_mconst may be set as late as in # step__update_busyb_makefile(), so it may not yet be known and we need # to check this at run-time if ($has_target_named_mconst) { # only process SAP/MSG docs if "mconst:" target exists in makefile step__busyb_process_interfaces (@_); } else { # if not, need to decrement $step_no (first parameter of this function) $_[0]--; } }; push @build_steps, sub { # $cdginc_tools_dir may be set as late as in # step__update_busyb_makefile(), so it may not yet be known and we need # to check this at run-time if ($cdginc_tools_dir) { # only generate ccddata_dll.dll if SAP/MSG docs were processed step__generate_ccddata_dll (@_); } else { # if not, need to decrement $step_no (first parameter of this function) $_[0]--; } }; push @build_steps, \&step__busyb_compilation; } # execution of queued steps, starting with step number 3 $exit_value = 0; my $step_no = 3; foreach my $step (@build_steps) { &{$step} ($step_no); $step_no++; } # restore redirected STDOUT+STDERR, if necessary restore_redirection() if $outerr_redirected; exit $exit_value; #------------------------------------------------------------------------------- # SUBROUTINES #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # parses the command line, sets global $o_* variables to all specified options, # checks which options/parameters are passed through to make or ABC #------------------------------------------------------------------------------- sub parse_command_line { GetOptions ("file=s"=>\$o_file, "log=s"=>\$o_logfile, "shell"=>\$o_shell, "make=s"=>\$o_make, "help|?" =>\$o_help); if ($o_help) { usage(); exit 0; } # determine ABC and make/BuSyB pass-through options from @ARGV $abc_opt = ""; $make_opt = ""; foreach (@ARGV) { if (/^-x/) { # ABC pass-through option: -x... #FIXME: are multiple ABC options allowed? s/^-x//; $abc_opt = $_; } else { # make/BuSyB pass-through option: all else $make_opt .= " " . $_; } } # sanity checks: due to enabled 'pass_through' and 'permute' of GetOptions(), # some busyb.pl options may end up in other options parameters instead (e.g. if # options which require a parameter are specified w/o any parameter: "... -m", # or "... -m -l", ...) foreach ($o_file, $o_logfile, $o_make) { # check all options which should take a parameter if they actually contain # another otion and no parameter if (defined($_) and /^-/) { print "\nERROR: Option missing mandatory parameter!\n\n"; usage(); exit 1; } } foreach ("-f", "-l", "-m") { # check if the pass-through options to make contain on of the busyb.pl # options if ($make_opt =~ /$_/i) { print "\nERROR: Option missing mandatory parameter!\n\n"; usage(); exit 1; } } if (!$o_file) { print "\nERROR: No input/configuration file specified with \"-f file\"!\n\n"; usage(); exit 1; } die "\nERROR: Input/configuration file \"" . $o_file . "\" not found, aborting" unless -e $o_file; # replace backslash with slash in filename $o_file =~ s:\\:/:g; } #------------------------------------------------------------------------------- # print short usage notes #------------------------------------------------------------------------------- sub usage { print "\nUSAGE: perl busyb.pl -f XML-File [OPTIONS] [make_flags] [make_targets] Build TI protocol stack with BuSyB/ABC, logging all output to report.txt by default. OPTIONS: -l LOGFILE log to LOGFILE (default is report.txt) -s output to current shell, no logging to report.txt -x\"OPT\" pass-through options for ABC EXAMPLES: perl busyb.pl -f variants/2b_gp_mf_fd_..ps.xml perl busyb.pl -f variants/2b_gp_mf_fd_..ps.xml clean_aci perl busyb.pl -f variants/2b_gp_mf_fd_..ps.xml -x\"ENVFILE=my_env.mak\" perl busyb.pl -f variants/2b_gp_mf_fd_..ps.xml -k "; } #------------------------------------------------------------------------------- # print current step to STDOUT (usually redirected to report.txt) and # additionally to CONSOLE_OUT #------------------------------------------------------------------------------- sub print_status { print "\n-------------------------------------------------------------------------------"; print "\n$_[0]\n"; print "-------------------------------------------------------------------------------\n\n"; print CONSOLE_OUT "$_[0]\n" if $outerr_redirected; } #------------------------------------------------------------------------------- # print to CONSOLE_OUT for progress bar #------------------------------------------------------------------------------- sub print_progress { print CONSOLE_OUT "$_[0]\r" if $outerr_redirected; } #------------------------------------------------------------------------------- # this function parses the XML file # it returns 0 on failure # it sets the following global variables # $hw_variant, $l1_variant, $makeVars #------------------------------------------------------------------------------- sub parse_file { my $line; open (IN,"<$_[0]") or die "ERROR: Can't open file \"$_[0]\" ($!), aborting"; while(defined($line = <IN>)) { # find HW string in ConfigDef document, e.g. # <property name="HW_VARIANT" value="GPRS_DSAMPLE_AMR_NW"/> # ^^^^^^^^^^^^^^^^^^^ if ($line =~ /name=\"HW_VARIANT\"\s*value=\"(.*)\"/ ) { $hw_variant = $1; } elsif ($line =~ /name=\"(L1)\"\s*value=\"(.*)\"/ ) { $l1_variant = $2; $makeVars .= " $1=$2"; } # finding all other properties in order to pass them to make elsif ($line =~ /name=\"(\w+)\"\s*value=\"(.*)\"/ ) { $makeVars .= " $1=$2"; } } close IN ; return 1; } #------------------------------------------------------------------------------- # currently need to remove all L1 objects before compiling (dependency problems # in ABC) when the ABC config (== $hw_variant) changes (last ABC config is stored in # /g23m/.abc_config) #------------------------------------------------------------------------------- sub purge_abc_obj_files { my $last_abc_config_file = $current_dir . "/.abc_config"; my $abc_config_changed = 1; if (-e $last_abc_config_file) { open (IN, $last_abc_config_file) or die "ERROR: could not open file \"" . $last_abc_config_file . "\" ($!),"; while (<IN>) { chomp; if (/ABC config = $hw_variant$/) { # still using the same ABC config as the last build $abc_config_changed = 0; print "ABC config not changed since the last build, keeping layer 1 *.obj files.\n"; } } close IN; } if ($abc_config_changed == 1) { # udpate .abc_config with current ABC config ($hw_variant) open (OUT, ">$last_abc_config_file") or die "ERROR: could not write to file \"" . $last_abc_config_file . "\" ($!),"; print OUT "This file is auto-generated, do not change!\nCurrent ABC config = " . $hw_variant . "\n"; close OUT; # remove L1 .obj files print "Removing all *.obj files in \"" . $hw_layer1 . "\" and below (currently necessary to properly re-compile when the ABC config changed)\n\n"; find (\&rm_file, $hw_layer1); } } #------------------------------------------------------------------------------- # Check/Initialize some necessary env. variables: # - %PATH must contain gpf/bin, gpf/tools/bin, chipsetsw/system (in that order) # - %C_DIR must only contain slashes (no backslashes, semicolons) #------------------------------------------------------------------------------- sub init_environment { my $current_drive_winformat = $current_drive; $current_drive_winformat =~ s:/:\\:g; # check if all necessary paths are in %PATH, add them if not (this removes # the dependency on initvars.bat) if (!($ENV{'PATH'} =~ m:[\\/]chipsetsw[\\/]system:)) { # add \chipsetsw\system to %PATH (should be third) $ENV{'PATH'} = "$current_drive_winformat\\chipsetsw\\system;" . $ENV{'PATH'}; print "%PATH : \"$current_drive_winformat\\chipsetsw\\system\" + %PATH\n"; } if (!($ENV{'PATH'} =~ m:[\\/]gpf[\\/]tools[\\/]bin:)) { # add \gpf\tools\bin to %PATH (should be second) $ENV{'PATH'} = "$current_drive_winformat\\gpf\\tools\\bin;" . $ENV{'PATH'}; print "%PATH : \"$current_drive_winformat\\gpf\\tools\\bin\" + %PATH\n"; } if (!($ENV{'PATH'} =~ m:[\\/]gpf[\\/]bin:)) { # add \gpf\bin to %PATH (should be first) $ENV{'PATH'} = "$current_drive_winformat\\gpf\\bin;" . $ENV{'PATH'}; print "%PATH : \"$current_drive_winformat\\gpf\\bin\" + %PATH\n"; } # check correct setting of environment variables for TI compiler and linker # PATH_CC_1_22e=C:\tools\TMS4701x_1.22e\NT die "\nERROR: environment variable %PATH_CC_1_22e must be set!\n" unless exists($ENV{'PATH_CC_1_22e'}); $ENV{'PATH_CC_1_22e'} =~ s|\\|/|g; $ENV{'PATH_CC_1_22e'} =~ s|;.*||; print "%PATH_CC_1_22e : \"" . $ENV{'PATH_CC_1_22e'} . "\"\n"; # PATH_LNK_1_9902=C:\tools\vislink_1.9902 die "\nERROR: environment variable %PATH_LNK_1_9902 must be set!\n" unless exists($ENV{'PATH_LNK_1_9902'}); $ENV{'PATH_LNK_1_9902'} =~ s|\\|/|g; $ENV{'PATH_LNK_1_9902'} =~ s|;.*||; print "%PATH_LNK_1_9902 : \"" . $ENV{'PATH_LNK_1_9902'} . "\"\n"; } # init_environment #------------------------------------------------------------------------------- # Return "<view-name> (type: <view-type>)" or "none": # <view-name>: CC view name/"unknown" # <view-type>: CC view type ("dynamic/snapshot/unknown") # Check view text mode, which must be 'unix' (aka 'transparent mode'). #------------------------------------------------------------------------------- sub determine_view_context { # check if using CC dynamic/snapshot view or no view at all my $view_details = `cleartool lsview -long -properties -full -cview 2>&1`; my $cc_view; if ($? == 0) { # store view name + view type (dynamic/snapshot) if ($view_details =~ /Tag:\s*(\w+)/) { $cc_view = $1; } else { print "\nWARNING: Could not determine current view name.\n"; $cc_view = "unknown"; } if ($view_details =~ /Properties: (\w+)/) { $cc_view .= " (type: " . $1 . ")"; } else { print "WARNING: Could not determine view type (dynamic/snapshot).\n"; $cc_view .= " (type: unknown)"; } # check view text mode (_must_ be "unix", otherwise most GNU tools like # gnumake don't work properly!) if ($view_details =~ /Text mode: (\w+)/) { if ($1 ne "unix") { die "\nERROR: Wrong text mode (found \"$1\", should be \"unix\") of CC view $cc_view, aborting"; } } } else { $cc_view = "none"; } return $cc_view; } # determine_view_context #------------------------------------------------------------------------------- # Check for gnumake/clearmake availability, returns gnumake/clearmake depending # on view context ($dynamic_view) and user choice ($o_make) #------------------------------------------------------------------------------- sub determine_make_tool { my $cmake; my $gmake; my $use_make; # checking for clearmake/gnumake availability my ($rc) = int (system("gnumake -ver > NUL 2>&1") / 256); if($rc == 0){ $gmake = "gnumake"; } # choosing the "right" make (gnumake for all kind of views) if (defined($gmake)) { $use_make = $gmake; } else { die "\nERROR: No appropriate gnumake tool found, aborting"; } # checking for user supplied make if (defined($o_make) && ($o_make =~ /clearmake/i) && defined($cmake)) { die "\nERROR: Clearmake make tool no longer supported, aborting"; } elsif (defined($o_make) && ($o_make =~ /gnumake/i) && defined($gmake)) { $use_make = $gmake; } elsif (defined($o_make)) { die "\nERROR: Specified make tool \"$o_make\" not found or not supported, aborting"; } return $use_make; } #------------------------------------------------------------------------------- # Check which GCC variant (Cygwin/MingW) and which version is installed, # return GCC version and set %GCC env. variable to run this GCC variant in ABC. #------------------------------------------------------------------------------- sub determine_gcc_version { my $gcc_ver = `gcc --version 2>&1`; if ($? == 0) { # only keep the first line of GCC version string $gcc_ver =~ s/\n.*$//s; # Nice GCC variant: Cygwin $ENV{'GCC'} = "\@gcc"; } else { $gcc_ver = `cpp --version 2>&1`; if ($? == 0) { # only keep the first line of GCC version string $gcc_ver =~ s/\n.*$//s; # Berlin GCC variant: MingW (defines WIN32 by default which is # interpreted by Nice SW as 'simulation build') $ENV{'GCC'} = "\@cpp -UWIN32"; } else { die "\nERROR: GCC not found (gcc.exe/cpp.exe not installed or not in the path), aborting"; } } return $gcc_ver; } #------------------------------------------------------------------------------- # Check if cl.exe (shipped with MS Visual Studio/VC++) is installed in the path, # return version string and indicate whether ccddata_dll.dll can be built # ($generate_ccddata_dll = 1) or not (= 0) #------------------------------------------------------------------------------- sub determine_cl_version { my $cl_ver = `cl.exe 2>&1`; if ($? == 0) { # only keep the first line of version string chomp $cl_ver; $cl_ver =~ s/\n.*$//s; # indicate that ccddata_dll.dll should be built $generate_ccddata_dll = 1; } else { $cl_ver = "not found, unable to generate ccddata_dll.dll"; # indicate that ccddata_dll.dll should not be built $generate_ccddata_dll = 0; } return $cl_ver; } #------------------------------------------------------------------------------- # Check if Java is installed (in the path), return version string of Java. #------------------------------------------------------------------------------- sub determine_java_version { my $java_ver = `java -version 2>&1`; if ($? == 0) { # only keep the first line of java version string and remove "java", if present $java_ver =~ s/\n.*$//s; $java_ver =~ s/\s*java\s*//; } else { die "\nERROR: Java not found (not installed or not in the path), aborting"; } return $java_ver; } #------------------------------------------------------------------------------- # Extract some globals from a given makefile # 1) $cdginc_dir # 2) $cdginc_tools_dir # 3) $target_image # 4) $has_target_named_mconst # 5) @busyb_libs #------------------------------------------------------------------------------- sub extract_globals_from_makefile { my ($makeFile) = @_; my $grab_libs = 0; my $grab_irlibs = 0; my $grab_irplacements = 0; my $lib_no = 0; open (IN, $makeFile) or die "ERROR: could not open file \"" . $makeFile . "\" ($!),"; while (<IN>) { if (/.*(__out__\/.+\/cdginc)\/mconst\.cdg/) { # grep cdginc directory from generated makefile $cdginc_dir = $1; } elsif (/.*(__out__\/.+\/cdginc[^ \/]+)/) { # grep cdginc_tools dir from generated makefile (take anything which # starts with "cdginc" but w/o blank or slash directly afterwards) $cdginc_tools_dir = $1; } elsif (/(__out__\/.+\.out):/) { # grep target image (.out) name (w/ complete path) from generated # makefile for step 9 $target_image = $1; # start grabbing libs (from next line on) $grab_libs = 1; } elsif ($grab_libs and /\s+(\S+)\s*([\\]*)/) { # disable lib-grabbing if last lib (i.e. no "\" at end of line) if ($2 eq "") { $grab_libs = 0; } # skip any make variables next if ($1 =~ /\$\(/); # skip the linker command file (*.lcf) next if ($1 =~ /.*\.lcf/); # skip all libs stored in chipsetsw VOB next if ($1 =~ /chipsetsw\//); # store lib in @busyb_libs push @busyb_libs, $1; } elsif (/__out__.+\.lcf:\s*(\w*)\s*\\/) { # start grabbing intram libs $grab_irlibs = 1; } elsif ($grab_irlibs and /\s+(\S+)\s*([\\]*)/) { # disable lib-grabbing if last lib (i.e. "\" at end of line), # start grabbing ir-placements instead if ($2 eq "") { $grab_irlibs = 0; $grab_irplacements = 1; } # skip any make variables next if ($1 =~ /\$\(/); # skip linker command file template next if ($1 =~ /\.template/); # store lib in @intram_libs push @intram_libs, $1; } elsif ($grab_irplacements and /\$\(BSB_ECHO\)\s+(\(.*\))\s*>/) { # grab intram lib placements # skip any make variables (e.g. $SSA_INT_RAM_PLACEMENT) next if ($1 =~ /\$\(/); # need to store each placement with the correct lib $intram_libs[$lib_no] .= " $1"; $lib_no++; } elsif ($grab_irplacements and /make_cmd\.pl/) { # stop grabbing intram lib placements $grab_irplacements = 0; } elsif (/^mconst:/) { $has_target_named_mconst = 1; } elsif (/chipsetsw\/system\/deps_objs\/(\w+)\// and !defined($hw_system_objects)) { # grep Nice deps_objs dir (different for each ABC config) $hw_system_objects = $1; } } close IN; } # extract_globals_from_makefile sub step__check_environment { print_status ($_[0] . ". Checking environment"); # create the makefile filename my $dir = (File::Spec->splitpath($o_file))[1]; #FIXME: remove this, we don't seem to need it anymore $makeFile = (File::Spec->splitpath($o_file))[2]; $makeFile =~ s/(.*)\..*/$1.mak/; # generate *.abc_exports.mak filename $abc_exports = $makeFile; $abc_exports =~ s/\.mak$//; $abc_exports = $abc_exports . ".abc_exports.mak"; # initialize necessary env. variables (%PATH, %C_DIR) init_environment(); # get view name, view type (dynamic/snapshot/none), and check text mode for # dynamic views (must be 'unix') my $view = determine_view_context(); print "CC View : $view\n"; # check for clearmake & gnumake, determine if user specified make exists $make = determine_make_tool ($view); print "Make : using \"$make\" for the build\n"; # check installed GCC variant (gcc.exe/cpp.exe), set %GCC env. variable for ABC my $gcc_version = determine_gcc_version(); print "GCC : " . $gcc_version . ", using \"" . $ENV{'GCC'} . "\" for ABC\n"; # check installed cl.exe version (part of MS Visual Studio/VC++) my $cl_version = determine_cl_version(); print "cl.exe : $cl_version\n"; # determine input file format: XML (default), or make (*.mak) $called_with_mak_file = ($o_file =~ /.*\.mak/); if ($called_with_mak_file) { print "Input : Makefile format (will skip several steps during build)\n"; # set global variables $cdginc_dir, $target_image, and # $has_target_named_mconst, which are needed to determine further steps extract_globals_from_makefile ($makeFile); } else { print "Input : XML format\n"; # extract_globals_from_makefile() is only possible after step 2, where the # makefile is being created } # only check if Java is installed, if input is XML (i.e. we need to generate # everything ourselves) _or_ if input is MAK and we have a target "mconst:" my $java_version; if ((not ($called_with_mak_file)) or (($called_with_mak_file) and ($has_target_named_mconst))) { $java_version = determine_java_version(); } else { $java_version = "not necessary"; } print "Java : " . $java_version . "\n"; # set environment variable %BUSYB_PREFIX, which is being used in ABCs master.mak # (is necessary for supporting old Berlin build system in parallel) $busyb_prefix = $makeFile; $busyb_prefix =~ s/\.mak$/\./; $ENV{'BUSYB_PREFIX'} = $busyb_prefix; print "Prefix : BUSYB_PREFIX=" . $busyb_prefix . "\n"; } sub step__parse_input_file { print_status ($_[0] . ". Parsing input file ($o_file)"); if (!parse_file ($o_file)) { die "ERROR: Either HW_VARIANT or L1 property missing in file \"$o_file\", aborting"; } if (defined($l1_variant)) { print "L1: " . $l1_variant . "\n"; } else { print "L1 : Not defined\n" } if (defined($hw_variant)) { print "HW variant: " . $hw_variant . "\n"; } else { print "HW variant : Not defined - Compiling with Unified BuSyB\n" } } #------------------------------------------------------------------------------- # update BuSyB makefile, if necessary; takes an additional second parameter # to specify the BuSyB .ini file #------------------------------------------------------------------------------- sub step__update_busyb_makefile { print_status ($_[0] . ". Updating BuSyB makefile ($makeFile)"); $command = "$make -f $t_updtBusyb MFILE=$makeFile XMLFILE=$o_file ABC_EXPORTS_MAKEFILE_NAME=$abc_exports"; if (defined ($_[1])) { $command .= " BUSYB_INI_FILE=$_[1]"; } print "$command\n\n"; system($command) == 0 or die "ERROR: Can't create makefile \"$makeFile\" ($!), aborting"; print "\n"; # set global variables $cdginc_dir, $target_image, and $has_target_named_mconst, # which are needed to determine further steps (in case $called_with_mak_file # is not true, see step__check_environment()) extract_globals_from_makefile ($makeFile); # generate clearmake build option specification (<makefile>.options), # regardless if using clearmake or gnumake in order to have this file # available in case one first wants to use gnumake and switches later on # to clearmake open (BOS, ">$makeFile.options") or die "ERROR: could not write to file \"" . $makeFile . ".options\" ($!),"; print BOS "# clearmake build option specification (BOS) file # this clearmake-specific rule causes clearmake to treat the logfile as a # view-private file and not as a derived object (which causes several problems # during the initial and subsequent builds with clearmake) .NO_DO_FOR_SIBLING: " . $o_logfile . "\n"; close BOS; } sub step__busyb_create_directories { print_status ($_[0] . ". Creating directories ($make)"); # create all the directories using the BUSYB makefile $command = "$make -f $makeFile MAKEDEPEND=0 allOutDirs"; print "$command\n\n"; system($command) == 0 or die "ERROR: Can't create directories ($!), aborting"; print "\n"; } sub step__busyb_process_interfaces { print_status ($_[0] . ". Processing SAP/MSG interfaces ($make)"); # process SAP/MSG documents using the BUSYB makefile $command = "$make -f $makeFile MAKEDEPEND=0 mconst"; print "$command\n\n"; system($command) == 0 or die "ERROR: Can't process SAP/MSG documents ($!), aborting"; print "\n"; } #------------------------------------------------------------------------------- # generate ccddata_dll.dll (requires cl.exe, see determine_cl_version() above) #------------------------------------------------------------------------------- sub step__generate_ccddata_dll { if ($generate_ccddata_dll) { print_status ($_[0] . ". Generating ccddata_dll.dll ($make)"); chdir $gpf_ccd or die "ERROR: Can't cd to \"$gpf_ccd\" ($!), aborting"; #FIXME: PROJECT=gprs may always be used...? Check with Henning. my $out_dir = $cdginc_tools_dir; $out_dir =~ s:/cdginc.+::; $command = "$make -f ccddata.mk TARGET=win32 PROJECT=gprs \ GPF=$gpf_root \ CCDDATA_LIB=$current_dir/$out_dir/bin/ccddata_dll.dll \ CDGINCDIR=$current_dir/$cdginc_tools_dir \ OBJDIR=$current_dir/$cdginc_tools_dir"; print "$command\n\n"; system($command) == 0 or print "WARNING: Error while executing ccddata.mk ($!), continuing build.\n"; print "\n"; chdir $current_dir or die "ERROR: Can't cd to \"$current_dir\" ($!), aborting"; } else { print_status ($_[0] . ". Skipping ccddata_dll.dll generation (cl.exe not found)"); } } #------------------------------------------------------------------------------- # generate makefiles <variant>_condat_lib_ip.mak and <variant>_condat_var.mak for ABC #------------------------------------------------------------------------------- sub step__generate_interface_for_abc { print_status ($_[0] . ". Generate interface for ABC (<variant>_condat_*.mak)"); $condat_lib_ip_mak = $busyb_prefix . "condat_lib_ip.mak"; $condat_var_mak = $busyb_prefix . "condat_var.mak"; print "cdginc output dir: \"" . $cdginc_dir . "\"\n\n"; # Berlin libs my $berlin_libs; foreach my $lib (@busyb_libs) { $berlin_libs .= " \$(CONDAT_BASE_DIR)/../$lib"; } # Berlin intram libs + their placements my $berlin_bss_libs; my $berlin_const_libs; foreach my $place (@intram_libs) { next if ($place =~ /chipsetsw\//); if ($place =~ /BSS_LIBS/) { (my $bss = $place) =~ s/CONST_LIBS\s+\(.*\)//; $bss =~ s/\(+BSS_LIBS\s+(\([^)]+\))/$1/; $berlin_bss_libs .= " \$(CONDAT_BASE_DIR)/../$bss" if ($bss ne ""); } if ($place =~ /CONST_LIBS/) { (my $const = $place) =~ s/BSS_LIBS\s+\(\.\w+\)\s+//; $const =~ s/\(+CONST_LIBS\s+(\([^)]+\))\)*/$1/; $berlin_const_libs .= " \$(CONDAT_BASE_DIR)/../$const" if ($const ne ""); } } # generate <variant>.condat_lib_ip.mak print "Generating condat/" . $condat_lib_ip_mak . "\n"; open (CONDAT_LIB_IP, ">condat/" . $condat_lib_ip_mak) or die "ERROR: could not open file \"condat/" . $condat_lib_ip_mak . "\" for writing ($!),"; print CONDAT_LIB_IP "# This file is auto-generated, do not change! ifndef CONDAT_LIB_IP_MAK # to avoid multiple condat_lib_ip.mak (import + include) export CONDAT_LIB_IP_MAK := 1 ifndef GPF_DIR export GPF_DIR := \$(CONDAT_BASE_DIR)/../../gpf export CONDAT_DIR := \$(CONDAT_BASE_DIR) endif 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) 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 export CONDAT_LIBS :=" . $berlin_libs . " export CONDAT_BSS_LIBS :=" . $berlin_bss_libs . " export CONDAT_CONST_LIBS :=" . $berlin_const_libs . " # extracted from " . $makeFile . " export ICDG=\$(CONDAT_BASE_DIR)/../" . $cdginc_dir . " export SRCACI=\$(CONDAT_BASE_DIR)/ms/src/aci export SRCACIDTIMNG=\$(CONDAT_BASE_DIR)/ms/src/aci_dti_mng export SRCACIA=\$(CONDAT_BASE_DIR)/ms/src/acia export SRCKSD=\$(CONDAT_BASE_DIR)/ms/src/ksd endif # ifndef CONDAT_LIB_IP_MAK\n"; close CONDAT_LIB_IP; # generate <variant>.condat_var.mak print "Generating condat/" . $condat_var_mak . "\n"; # put all feature flags in <variant>.condat_var.mak, except for # L1, CHIPSET, BOARD, COPY_DOCS, BUILD_UTILITIES, CMP_MODE, MAKE_DEPENDENCIES, # since these are not relevant for ABC $condat_var_variables = $makeVars; $condat_var_variables =~ s/ /\nexport /g; $condat_var_variables =~ s/\nexport L1=/\n#export L1=/; $condat_var_variables =~ s/\nexport CHIPSET=/\n#export CHIPSET=/; $condat_var_variables =~ s/\nexport BOARD=/\n#export BOARD=/; $condat_var_variables =~ s/\nexport COPY_DOCS=/\n#export COPY_DOCS=/; $condat_var_variables =~ s/\nexport BUILD_UTILITIES=/\n#export BUILD_UTILITIES=/; $condat_var_variables =~ s/\nexport CMP_MODE=/\n#export CMP_MODE=/; $condat_var_variables =~ s/\nexport MAKE_DEPENDENCIES=/\n#export MAKE_DEPENDENCIES=/; open (CONDAT_VAR, ">condat/" . $condat_var_mak) or die "ERROR: could not open file \"condat/" . $condat_var_mak . "\" for writing ($!),"; print CONDAT_VAR "# This file is auto-generated, do not change! ifndef CONDAT_VAR_MAK # to avoid multiple condat_var.mak (import + include) export CONDAT_VAR_MAK := 1 # matching " . $o_file . ": # all feature flags, except for L1, CHIPSET, BOARD, COPY_DOCS, BUILD_UTILITIES, CMP_MODE, MAKE_DEPENDENCIES " . $condat_var_variables . " endif # ifndef CONDAT_VAR_MAK\n"; close CONDAT_VAR; } # generate_interface_for_abc sub step__update_abc_config { print_status ($_[0] . ". Updating ABC config ($t_updtAbc)"); chdir $hw_system or die "ERROR: Can't cd to \"$hw_system\" ($!), aborting"; $command = "$t_perl $t_updtAbc $hw_variant"; print "$command\n\n"; system($command) == 0 or die "ERROR: Execution of \"$t_updtAbc\" failed ($!), aborting"; chdir $current_dir or die "ERROR: Can't cd to \"$current_dir\" ($!), aborting"; } #------------------------------------------------------------------------------- # generate include makefile for SSA filenames #------------------------------------------------------------------------------- sub step__extract_abc_variables { print_status ($_[0] . ". Extracting ABC variables for Berlin SW ($abc_exports)"); my $command; $command = "$make -f $t_updtBusybInc ABC_EXPORTS_MAKEFILE_NAME=$abc_exports $makeVars"; print "$command\n\n"; system($command) == 0 or die "ERROR: Execution of \"" . $t_updtBusybInc . "\" failed ($!),\n"; print " \n"; if (! -e $abc_exports) { die "ERROR: File \"$abc_exports\" has not been generated\n" } } # extracting_abc_variables #------------------------------------------------------------------------------- # compiling nice sw using abc #------------------------------------------------------------------------------- sub step__abc_compilation { print_status ($_[0] . ". Compiling Nice SW ($t_abc)"); my $command; # remove some .obj files in the \chipsetsw VOB due to ABC dependency errors # (temporary solution!) ##purge_abc_obj_files(); print "\n"; # compile Nice software w/ ABC chdir $hw_system or die "ERROR: Can't cd to \"" . $hw_system . "\" ($!),"; $command = "$t_perl $t_abc $hw_variant"; if ($abc_opt) { $command .= " -x\"$abc_opt\""; } print "$command\n\n"; my $res = system($command); if ($res != 0) { print_status ("ERROR: BUILD FAILED!"); exit 1; } chdir $current_dir or die "ERROR: Can't cd to \"" . $current_dir . "\" ($!),"; } # compiling_nice_sw #------------------------------------------------------------------------------- # finally run make w/ the generated makefile from BuSyB #------------------------------------------------------------------------------- sub step__busyb_compilation { print_status ($_[0] . ". Running BuSyB makefile ($make)"); # Start progress bar display mechanism start_progress_bar_display(); my $command; $command = "$make -f $makeFile$make_opt"; print "$command\n\n"; if ((system($command) == 0) and (-e $target_image)) { print_status ("Build succeeded"); $exit_value = 0; } else { print_status ("ERROR: BUILD FAILED!"); $exit_value = 1; } # Kill child process if it exists if ($list_of_libs_available == 1) {kill 2, $pid; } } sub step__busyb_generate_l1_configdef_files { print_status ($_[0] . ". Generating Layer1 ConfigDef files"); chdir ("$hw_layer1\\tools") or die "ERROR: Can't cd to \"" . $hw_system . "\" ($!),"; $command = "perl -w $hw_system\\Scripts\\L1Config.pl"; print "$command\n\n"; system($command) == 0 or die "ERROR: Execution of \"" . $command . "\" failed ($!),"; chdir $current_dir or die "ERROR: Can't cd to \"" . $current_dir . "\" ($!),"; } sub step__busyb_generate_cfg_files { print_status ($_[0] . ". Generating .cfg files ($make)"); $command = "$make -f $makeFile cfg_files"; print "$command\n\n"; system($command) == 0 or die "ERROR: Execution of \"" . $command . "\" failed ($!),"; } sub step__busyb_generate_header_files { print_status ($_[0] . ". Generating header files ($make)"); $command = "$make -f $makeFile header_files"; print "$command\n\n"; system($command) == 0 or die "ERROR: Execution of \"" . $command . "\" failed ($!),"; } sub step__init_icl470_environment { print_status ($_[0] . ". Init icl470 environment"); print "%TEMPORARY_FILE_DIR: \"" . $hw_system . "/deps_objs/" . $hw_system_objects . "\"\n\n"; $ENV{'TEMPORARY_FILE_DIR'} = $hw_system . "/deps_objs/" . $hw_system_objects; } #------------------------------------------------------------------------------- # this function is used by find() (File::Find) above and removes all found # *.obj files (NOTE: some are checked-in, so unlink() will fail) #------------------------------------------------------------------------------- sub rm_file { unlink ($_) if /.*\.obj$/; } #------------------------------------------------------------------------------- # redirect STDOUT+STDERR to $o_logfile, return 1 if redirection successful or # 0 if redirection failed #------------------------------------------------------------------------------- sub redirect_output { my $redirected = 1; open (CONSOLE_OUT, ">&STDOUT"); open (CONSOLE_ERR, ">&STDERR"); open (STDOUT, '>', $o_logfile) or $redirected = 0; open (STDERR, ">&STDOUT") or $redirected = 0; if ($redirected) { # make output unbuffered select (STDERR); $| = 1; select (STDOUT); $| = 1; # install signal handler function for die() $SIG{__DIE__} = \&die_handler or print CONSOLE_ERR "WARNING: Could not install die() signal handler, console output may be corrupted when exiting with an error!\n"; } else { # redirection failed: use old STDOUT+STDERR restore_redirection(); print "WARNING: Could not redirect STDOUT+STDERR to " . $o_logfile . ", not logging output!\n"; } return $redirected; } #------------------------------------------------------------------------------- # close logging to $o_logfile and restore old STDOUT+STDERR # (pointing to console) #------------------------------------------------------------------------------- sub restore_redirection { # restore redirected STDOUT+STDERR close (STDOUT); close (STDERR); open (STDOUT, ">&CONSOLE_OUT"); open (STDERR, ">&CONSOLE_ERR"); } #------------------------------------------------------------------------------- # print die() error message, to also log it to $o_logfile and then restore # the STDOUT+STDERR redirection #------------------------------------------------------------------------------- sub die_handler { print STDERR $_[0]; restore_redirection(); } #------------------------------------------------------------------------------- # Get number of libraries that have to be generated and display a 'progress bar' # during the build according to the number of rebuilt libraries #------------------------------------------------------------------------------- sub start_progress_bar_display { # Get libraries list my @libraries = () ; my %libDates ; my $total_lib = 0; my $line; open (IN, "<$makeFile") or die "ERROR: could not open file \"" . $makeFile . "\" ($!),"; while(defined($line = <IN>)) { # Check if variable BSB_TARGETS_ALL exists in the makefile if ( ( $line =~ /^BSB_TARGETS_ALL\s*=\s*([^\s]*)\s*(\\*)/ ) || ( ( $line =~ /\s*([^\s]*)\s*(\\*)/ ) && ( $list_of_libs_available == 1 ) ) ) { my $cur_lib = $1 ; my $end = $2 ; $list_of_libs_available = 1 ; if ( $cur_lib =~ m/\.lib$/ ) { push( @libraries, $cur_lib ) ; } if ( $end eq "" ) {last;} next ; } } $total_lib = $#libraries + 1; # Retrieve current time (this allows to make time dif with future generated libraries) my $mytime = time; # If the list of libraries is available, create the process which take care about the progress # and start display progress if ($list_of_libs_available == 1) { # Create the process to display the progress bar defined($pid = fork) or die "Cannot fork: $!"; # If child process unless ($pid) { # Flush Output buffer select CONSOLE_OUT; $| = 1; # The child process is stopped when the build is finished while (1) { # For the algorithm, we guess that the list of libraries in the array are ordered # in the same way that BuSyB compile these one. This means if the lib at index n # has been rebuilt, that means 100*n/total_lib have been rebuilt (where # total_libs is the number of libs that contribute to the image file) my $i = 0; foreach (reverse( @libraries )) { my $mlib = "$_" ; if (-e $mlib) # Check if the library exist { if ( ( stat( $mlib ) )[ 10 ] > $mytime ) # Check if the file has been rebuilt { last; } else { $i++; } } else {$i++;} # If the library does not exist, we continue with the #previous library in the array } my $nb_generated_libs = $total_lib - $i; # Search for the number of files already generated my $progress; $progress = sprintf ("%.02d", (100 * $nb_generated_libs)/$total_lib); print_progress("Progress : " . $progress . "%"); sleep 10; } } } }