FreeCalypso > hg > tcs211-c139
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/g23m/nds_busyb.pl Mon Jun 01 03:24:05 2015 +0000 @@ -0,0 +1,1493 @@ +#!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; + } + } + } +} +