#!perl
use File::Path;
use File::Glob;
use File::Spec;
use IO::Handle;
use Time::Local;
use Config;

###
# File build.pl
$pid_version            = "4.5";

# authors: Jan Galema (JG)
#          Peter Kazakov (PK)
#          Shivaraj P (SP)
#          Bhaskar G (BG)
#
# Revision history:
# -----------|---------|----------------------------------------------------------
# date       | version | Description 
# -----------|---------|----------------------------------------------------------
# 2000-09-05 | 0.1, JG | Initial
# -----------|---------|----------------------------------------------------------
# 2000-09-19 | 0.2, JG | Locate WildcardFile in _TMROOT
#            |         | Concat BuildLocation to BuildLocDir in ExecMake
# -----------|---------|----------------------------------------------------------
# 2000-12-06 | 0.3, JG | Arrays are not reinitialised for next component
# -----------|---------|----------------------------------------------------------
# 2000-12-18 | 0.4, JG | unclear message when REPORTS directory does not exist 
#            | 0.5, JG | Create directory if it does not exist
# -----------|---------|----------------------------------------------------------
# 2001-01-18 | 0.6, JG | Major changes, not upwards compatible with version 0.5
#            |         | See specs in c06s02_scripts.doc - 0.9
# -----------|---------|----------------------------------------------------------
# 2001-02-12 | 0.7, JG | <_TMTCSHOST> exists in the configuration file 
#            |         | if and only if <_TMTGTCPUCLASS>==tm.
#            |         | Script must not count empty lines as a configuration
# -----------|---------|----------------------------------------------------------
# 2001-05-22 | 0.8, PK | Bug fix for PR119 - M. Selten's remark and implementation
# -----------|---------|----------------------------------------------------------
# 2001-07-23 | 0.9, PK | PR161, PR165 -  build.pl requires a component, while I only have an executable; build all script should do two passes
#            |         | PR166 - script output is confusing
#            |         | PR180 - specify configuration.txt and buildlist.txt also via the command line.
#            |         | remarks from Rogier Wester, implementation - Peter Kazakov
# -----------|---------|----------------------------------------------------------
# 2001-07-23 | 1.0, PK | PR188 -  Multiproject SDE2
# -----------|---------|----------------------------------------------------------
# 2001-09-25 | 1.1, PK | putting all outputs to stdout, stderr
#            |         | Option for suppressing the DLLs generation              
# -----------|---------|----------------------------------------------------------
# 2001-09-25 | 1.2, PK | PR 298: build.pl does not generate .l files
# -----------|---------|----------------------------------------------------------
# 2001-10-15 | 1.4, PK | PR 305: Third synchonisation with Sunnyvale
# -----------|---------|----------------------------------------------------------
# 2001-12-04 | 1.5, PK | CR 181: introduce the notion of a board list in the wildcard.txt.
#            |         | CR 324: _TMREQPRJS should be re-introduced -- support of Unix env. variable in the prjlist.txt included
# -----------|---------|----------------------------------------------------------
# 2001-12-20 | 1.6, PK | CR 353: build.pl  always reports compiling warnings for mips_psos
# -----------|---------|----------------------------------------------------------
# 2002-02-05 | 1.7, PK | PR 418: Second executable is not build at all
# -----------|---------|----------------------------------------------------------
# 2002-03-12 | 1.8, PK | PR 454: _TMTOOLCHAIN is not present in the configurations.txt files
# -----------|---------|----------------------------------------------------------
# 2002-03-20 | 1.9, PK | PR 461: build.pl message should mention which input file
# -----------|---------|----------------------------------------------------------
# 2002-05-10 | 2.0, SP | CR 499/509: Add -target option to explicitly mention the makefile target
# -----------|---------|----------------------------------------------------------
# 2002-05-22 | 2.1, PK | CR 499/509: Fixes
# -----------|---------|----------------------------------------------------------
# 2002-05-31 | 2.2, PK | CR 413: Add debug mode
# -----------|---------|----------------------------------------------------------
# 2002-06-12 | 2.3, BG | PR 516: Fix for cannot generate <o/p>/reports
# -----------|---------|----------------------------------------------------------
# 2002-06-17 | 2.4, PK | PR 552: The configuration fields are not count corrently for some cases in build.pl
# -----------|---------|----------------------------------------------------------
# 2002-06-24 | 2.5, BG | CR 413: Add debug mode
# -----------|---------|----------------------------------------------------------
# 2002-07-01 | 2.6, SP | CR 499/509: Fix Add _target:<empty> check
# -----------|---------|----------------------------------------------------------
# 2002-07-01 | 2.7, PK | PR 561: build.pl does not work properly with project configurations rel.modes
# -----------|---------|----------------------------------------------------------
# 2002-07-30 | 2.8, SP | Corrections -target: option with multiple targets specified.
# -----------|---------|----------------------------------------------------------
# 2002-08-12 | 2.9, BG | build_exe.pl doesnot display environment variables properly
# -----------|---------|----------------------------------------------------------
# 2002-08-21 | 3.0, BG | build_exe.pl with -target clean_all will not clean if the 
#            |         | component exists outside $_TMROOT
# -----------|---------|----------------------------------------------------------
# 2002-12-02 |3.0.1,JG | PR ...: (locally changed - marked in code as PID-CHANGE)
#            |         |         allow build only libs  
#            |         |         optional build only application as in configurations_<appl>.txt
#            |         |         Skip build component if no configuration.txt file found in component dir
# -----------|---------|----------------------------------------------------------
# 2003-07-24 |3.0.2,JG | PR ...: optional build only application as in configurations_<appl>.txt
#            |         |         if appl is filled (locally changed - marked in code as PID-CHANGE)
# -----------|---------|----------------------------------------------------------
# 2003-08-27 |3.0.3,JG | -noexec flag: possibility to exclude building executables: 
#            |         |(locally changed - marked in code as PID-CHANGE)
# -----------|---------|----------------------------------------------------------
# 2002-11-28 | 3.4, BG | Changes made for clean_all target PR 509.
# -----------|---------|----------------------------------------------------------
# 2002-11-26 | 3.5, BG | PR 557: Change configurations.txt to XML format <...> ... </...>
#			 |		   | and configurations.txt to configs.txt
# -----------|---------|----------------------------------------------------------
# 2002-04-28 | 3.6, BG | build.pl doesnot report error if no buildable config found
# -----------|---------|----------------------------------------------------------
# 2002-05-28 | 3.7, BG | Roll back changes made for 3.3 adn 3.5
# -----------|---------|----------------------------------------------------------
# 2002-05-29 | 3.8, BG | SDE2_HS#21175: build.pl used wrong sequence from prjlist.txt
# -----------|---------|----------------------------------------------------------
# 2003-12-19 |3.8.2,JG | SDE2_HS#26491: order of finding configuration.txt files 
#            |         | should be bottom up in prjlist
# -----------|---------|----------------------------------------------------------
# 2004-01-28 |3.8.3,JG | Only one value in wildcard file does not expand properly
# -----------|---------|----------------------------------------------------------
# 2004-02-10 |3.8.4,JG | define empty start/end-address if host = Winnt
# -----------|---------|----------------------------------------------------------
# 2004-03-08 |3.8.5,JG | Allow variable wild card file: -wc:<filename> relative to _TMROOT
# -----------|---------|----------------------------------------------------------
# 2004-12-13 |3.8.6,BG |  Build.pl stops without error message if build directory does not exist  
# -----------|---------|----------------------------------------------------------
# 2004-12-15 |3.8.7,BG |  Add elapsed time in logging info for each component/diversity
# -----------|---------|----------------------------------------------------------
# 2005-02-21 |3.9,BG   |  HS#38334: Wildcard for _TMBSL in configurations.txt doesn't work. 
# -----------|---------|----------------------------------------------------------
# 2005-04-01 |4.0,BG   |  HS#37580: Possibility of use of build.pl in accordance with _TMDIVERSITY 
# -----------|---------|----------------------------------------------------------
# 2005-08-22 |4.1,RM   |  HS#45057: Move the wildcards.txt into project director 
# -----------|---------|----------------------------------------------------------
# 2005-08-26 |4.1.1,RM |  HS#45057: The wilddcards.txt file path relative to _TMPROJECT is removed.
#            |         |  The user should give the absolute path of the file.  
# -----------|---------|----------------------------------------------------------
# 2006-03-22 |4.2,BG   |  HS#47811: build.pl cannot generate several executables in a component
# -----------|---------|----------------------------------------------------------
# 2006-05-17 |4.3,BG   |  Removed all the warnings.
# -----------|---------|----------------------------------------------------------
# 2006-06-05 |4.4,  BG | PR 55921: Generated loc_list.* incomplete when using the 
#            |         |           Build_exe.pl script  
#------------|---------|----------------------------------------------------------
# 2006-07-27 |4.5,  BG | Build.pl doesnot work with _TMPROJECT set 
#------------|---------|----------------------------------------------------------
# Globals

$ConfigurationSeparator = "EXECUTABLE"; # A line containining this value separates configurations in the ConfigFile
$ReportLogfile          = "build_script_report.log";
$Logfile                = "build_script.log";
$WildcardFile           = "wildcards.txt";
$ProjectConfigFile      = "configurations.txt"; # file with possible configurations in this project (containing wildcards)
$ConfigFile             = "configurations.txt";
$Buildlistfile          = "buildlist.txt";
$format                 = '-' x80;
$format1                = '*' x80;
$format2                = '=' x80;

#Possible environment variables in the wildcards.txt file
$ENDIAN                 = "_TMTGTENDIAN";
$LINKTYPE               = "_TMLINKTYPE";
$RELTYPE                = "_TMTGTREL";
$HOST                   = "_TMTCSHOST";
$BSL                    = "_TMBSL";

#Possible environment variables
$CPUCLASS               = "_TMTGTCPUCLASS";
$OS                     = "_TMTGTOS";
$OSCLASS                = "_TMTGTOSCLASS";
$CPUTYPE                = "_TMTGTCPUTYPE";
$DIVERSITY              = "_TMDIVERSITY";
$TOOLCHAIN              = "_TMTOOLCHAIN"; # empty by default
#Position of environment variables in the configuration.txt file
$WildposEndian          = 4;
$WildposDiversity       = 6;
$WildposRelType         = 7;
$WildposTMHost          = 8;
$WildposBsl             = 9;
$WildposLinkType        = 10;

$BuildEntryConfigFile=""; # file with configurations to be build in this component (containing wildcards)
$NrPC=0;
@PossibleConfig=();       # table with expanded configurations in this project
$NrRC=0;
@RequestedConfig=();      # table with expanded configurations requested in this entry-point
$NrBC=0;
$Exit_value         = 0;
$Exit_value_summary = 0;
$DBG                = 0;
$NOEXEC             = 0; # -noexec flag	PID-CHANGE
$CompConfigFileExists = 0;
$BuildGoals         = "all";
$RootLocations    = "";

# BuildLocation and BuildConfig are tables using the same running index
@BuildLocation=(); # table with locations to be build in this entry-point
@BuildConfig=();   # table with expanded configurations to be build in this entry-point
@BuildList=();     # lists of components to be build (from buildlist.txt or parameter)

my $Message="";
my $Message2="";

my $MyRootLocations="";
my $RootLocation="";
my $BuildGoals_target="";

@parameters = ($CPUCLASS, $OSCLASS, $OS, $ENDIAN, $CPUTYPE, $DIVERSITY, $RELTYPE, $HOST, $BSL, $LINKTYPE, $TOOLCHAIN);

#-------------------------------------------------------------------
sub DisplayUsage
{
    print  "\nUsage :\n\n";
    print  "build.pl \t[-c] [-d][noexec] [-config:<filename>] [-list:<filename>] [-dbg] \b\t\t\t[-h] [-target:<target name>]\n";
    print  "$format\n";
    print  "no positional\t: Build all entries in buildlist.txt\n\n";
    print  "positional   \t: [keywords] list of build-entries\n\n";
    print  "             \t: '-config:<FilePath/FileName>' : optional project config.file \n";
    print  "             \t: '-list:<FilePath/FileName>' : optional build list\n";
    print  "             \t: '-target:<targetname>':To specify makefile targets explicitly\n";
    print  "             \t   User can specify multiple targets with more -target:options.\n";
    print  "             \t   eg: build.pl -target:t1 -target:t2\n";
    print  "keyword      \t: '-c' :          continue make after a failing make \n";
    print  "             \t: '-d' :          suppress the DLL build \n";
    print  "             \t: '-dbg':         Print debug info during the execution.\n";
    print  "             \t: '-h' :          Print this help and exit\n";
    print  "             \t: '-l' :          only build libs, suppress the DLL build \n";               # PID-CHANGE
    print  "             \t: '-appl:<appl>:  build only application as in configurations_<appl>.txt\n"; # PID-CHANGE
    print  "             \t: '-noexec:       do not build executables\n";                               # PID-CHANGE
    print  "             \t: '-wc:<filename>:wildcard file name. (Specify absolute pathname of file)\n";          # PID-CHANGE
    print  "$format\n";
}
#-------------------------------------------------------------------
# void StripBlank()
# strip blank space from the beginning/end of a string
# (Copied from perlfaq4)

sub StripBlank
{
    my ($String) = @_;

    $String =~ s/^\s+//;

    $String =~ s/\s+$//;
    return $String;
}
#-------------------------------------------------------------------
# void StripQuotes()
# strip quotes from the beginning/end of a string
# (Copied from perlfaq4)

sub StripQuotes
{
    my ($String) = @_;

    $String =~ s/^\'//;

    $String =~ s/\'$//;
    return $String;
}
#---------------------------------------------------------------------------------------------
sub CheckParameters
{
    my $error = 0;
    my $i;
    my $j;

    (@BuildList) = ();

    $Fail        = "stop";
    if( @_ > 0 )
    {
        for( $i = 0, $j = 0; $i < @_; $i++ )
        {
            if( $_[$i] =~ /^-/ )
            {
                if( $_[$i] eq '-c' or $_[$i] eq '-C' ) { $Fail = "go"; }
                elsif( $_[$i] eq '-d' or $_[$i] eq '-D' ) { $BuildGoals = "all _sde_libs _sde_suppress_dlls"; }
                elsif( $_[$i] eq '-dbg' or $_[$i] eq '-DBG' ) { $DBG = 1; }
                elsif( $_[$i] eq '-noexec' or $_[$i] eq '-NOEXEC' ) { # PID-CHANGE
                    $NOEXEC = 1;                                      # PID-CHANGE
                    }                                                 # PID-CHANGE
                elsif( $_[$i] =~ /^-config:/ )
                {
                    print  "Configuration:$'\n";
                    $ProjectConfigFile = $';
                }
                elsif( $_[$i] =~ /^-list:/ )
                {
                    print  "Build List:$'\n";
                    $Buildlistfile = $';
                }
                elsif( $_[$i] eq '-l' or $_[$i] eq '-L' ) {                # PID-CHANGE
                    $BuildGoals = "_sde_libs";                             # PID-CHANGE
                    }                                                      # PID-CHANGE
                elsif( $_[$i] =~ /^-appl:/ )
                {                                                          # PID-CHANGE
                    if( $' ne "" )
                    {                                                      # PID-CHANGE
                        $ConfigFile = "configurations_" . $' . ".txt";     # PID-CHANGE
                        print  "ConfigFile=$ConfigFile\n";           # PID-CHANGE
                        if(!-f $ConfigFile){
                            print "Cant' open $ConfigFile: $!\n";
                            exit;
                        }

                    }                                                      # PID-CHANGE
                }                                                          # PID-CHANGE
                elsif( $_[$i] =~ /^-wc:/ )
                {                                                          # PID-CHANGE
                    if( $' ne "" )
                    {                                            # PID-CHANGE
                        $WildcardFile = $'; # PID-CHANGE
                        print  "WildcardFile=$WildcardFile\n";       # PID-CHANGE
                        if(!-f $WildcardFile){
                            print "Cant' open $WildcardFile: $!\n";
                            exit;
                        }
                    }                                                      # PID-CHANGE
                }                                                          # PID-CHANGE
                elsif( $_[$i] =~ /^-h/ )
                {
                    DisplayUsage();
                    exit 0;
                }
                elsif( $_[$i] =~ /^-target:/ )
                {
                    if( $' eq "" )
                    {
                        print  "\nNo target name specified in -target: option\n\n";
                        DisplayUsage();
                        exit 0;
                    }
                    $BuildGoals_target = $BuildGoals_target . " " . $';
                }
				elsif( $_[$i] =~ /^-comp_config:/ )
                {                                                          
                    if( $' ne "" )
                    {                                                      
                        $CompConfigFileExists = 1;
						$CompConfigFile = File::Spec->rel2abs( $' ) ;
						if (-f $CompConfigFile) {
	                        print  "Using $CompConfigFile as component configurations.txt file\n";
						}
						else
						{
							print "File: $CompConfigFile not found. \n";
							exit 1;
						}
                    }
                }
                else { $error = "keyword"; }
            }
            else
            {
                $BuildList[$j] = $_[$i];
                $j++;
            }
        }
        if( $BuildGoals_target ) { $BuildGoals = $BuildGoals_target; }
    }
    if( $error ne 0 )
    {
        print  "Wrong use of parameters.\nError in $error\n";
        DisplayUsage();
        exit 1;
    }
}
#---------------------------------------------------------------------------------------------
sub CheckEnvironment
{
    my $errors = 0;
    if( !exists $ENV {'_TMROOT'} )
    {
        print  "Environment variable \'_TMROOT\' not defined\n";
        $errors += 1;
    }
    if( !exists $ENV {'_TMPROJECT'} )
    {
        print  "Warning: \tEnvironment variable \'_TMPROJECT\' not defined\n\t\tUsing \$_TMROOT/project as \'_TMPROJECT\'\n ";
        $NoEnvPrj = 1 ;
    }
    if( !exists $ENV {'_TMREPORTS'} )
    {
        print  "Environment variable \'_TMREPORTS\' not defined\n";
        $errors += 1;
    }
    if( !exists $ENV {'MAKE'} )
    {
        print  "Environment variable \'MAKE\' not defined\n";
        $errors += 1;
    }
}
    #------------------------------------------------------------------
    # There is a difference between Unix shell (support ${env_var}, $env_var) and
    # Perl interpretation of env_var (support $(env_var)). To ensure 
    # the Unix model, a small rework of env.variables is made in this Perl script.
    # This variables are correctly interpretet from gmake, but not from Perl.

sub ReadProjectList{
	if( open(PRJLISTFILE, "<$TM_PRJLIST") )
    {
        while( defined($PrjListLine = <PRJLISTFILE>) )
        {
            chomp $PrjListLine;
            $RootLocations = $RootLocations . " " . $PrjListLine;
        }
        close PRJLISTFILE;
    }
    else { $RootLocations = $ENV {'_TMROOT'}; }
    my @reqprj = split / /, $RootLocations;
    LOOP1:
    foreach $loc( @reqprj )
    {
        if( $loc =~ /\$/ )
        {
            @locs = split /\//, $loc;
            foreach $entry( @locs )
            {
                if( $entry =~ /^\$/ )
                {
                    $entry =~ s/^\$//g;

                    $entry =~ s/[{}()]//g;
                    if( exists $ENV {$entry} ) { $entry = $ENV {$entry}; }
                    else
                    {
                        print  "Warning:\t$entry Environment not set\n\t\tSkipping the entry $loc in prjlist.txt\n";
                        next LOOP1;
                    }
                }
            }
            $loc1 = join '/', @locs;
        }
        else { $loc1 = $loc; }
        $MyRootLocations = $MyRootLocations . " " . $loc1;
    }
    print  "\nRoot locations: $MyRootLocations \n";
    print  "$format\n";
    if( $errors > 0 ) { exit 1; }
}
#---------------------------------------------------------------------------------------
#
# Read the Wildcard file 
# and wildcards per type in an array
#

sub ReadWildCards
{
    my $i = 0;
    my $Nr = 0;
    @Endian = ();
  @RelType  = ();
  @LinkType = ();
  @TMHost   = ();
  @TMBsl  = ();
    open(WILDCARDS, "<" . $WildcardFile) or die "Cant' open $WildcardFile: $!";
    WILDCARDS:
    while( $Line = <WILDCARDS> )
    {
        $Line =~ s/\t+//g;               # strip all the tabs
        chomp($Line);
        next WILDCARDS if $Line =~ /^$/; # skip empty lines
        next WILDCARDS if $Line =~ /^\#/; # skip Comment lines
        @wildcards =split(/\s+/, $Line);
		$Nr = @wildcards;
        if( $wildcards[0] =~ /$ENDIAN/ )
        {
            for( $i = 1; $i < $Nr; ++$i ) { $Endian[$i -1] = $wildcards[$i]; }
        }
        elsif( $wildcards[0] =~ /$LINKTYPE/ )
        {
            for( $i = 1; $i < $Nr; ++$i ) { $LinkType[$i -1] = $wildcards[$i]; }
        }
        elsif( $wildcards[0] =~ /$RELTYPE/ )
        {
            for( $i = 1; $i < $Nr; ++$i ) { $RelType[$i -1] = $wildcards[$i]; }

        #      print "RelTypes: @RelType \n";
        }
        elsif( $wildcards[0] =~ /$HOST/ )
        {
            for( $i = 1; $i < $Nr; ++$i ) { $TMHost[$i -1] = $wildcards[$i]; }
        }
		elsif( $wildcards[0] =~ /$BSL/ )
        {
            print  "Warning: $wildcards[0] wildcard entry in the wildcards.txt file is obsolete\n";
        }
        else
        {
            print  "Invalid parameter in Wildcard file: $wildcards[0]\n";
            exit 1;
        }
    }
  @files =  glob("$ProjectDir/*");
  foreach $makefile (@files) {
	  $makefile=~s!.*/!!g;
	  if ($makefile =~ /maketarget.+\.mk/) {
	  	$makefile =~ s/maketarget//;
	  	$makefile =~ s/\.mk$//;
	  	push(@TMBsl, $makefile);
	  }
  }
}
#---------------------------------------------------------------------------------------
#
# FindFileLocation
# Usually the components location is in a subdirectory of _TMROOT (_TMCURPRJ if it is defined)
# If not we have to look in all locations specified in _TMTGTREQPRG
#
sub FindFileLocation
{
    my ($Location) = @_;
    my @reqprj     = split / /, $MyRootLocations;
    foreach $DirName( reverse @reqprj )
    {
        $DirName =~ s/\n//;
        #    print "Looking in $DirName/$Location \n";
        if( -s "$DirName/$Location" ) { 
			return "$DirName/$Location"; }
    }
    #  print "Looking in $Location \n";
    if( -s "$Location" ) { return "$Location"; }
    return "$ENV{'_TMROOT'}/$Location";
}

sub FindDirLocation
{
    my ($Location) = @_;
    my @reqprj     = split / /, $MyRootLocations;
    foreach $DirName( reverse @reqprj )
    {
        $DirName =~ s/\n//;
        if( -d "$DirName/$Location" ) { return "$DirName/$Location"; }
    }
    if( -d "$Location" ) { return "$Location"; }
    return "$ENV{'_TMROOT'}/$Location";
}
#---------------------------------------------------------------------------------------
#
# EvaluateWildCards 
# and store possible configuration an array @Config
#
# Wildcards are only expected at locations 4, 7, 8, 9 and 10 (see variables $Wildpos....)
#
# This function is called for project and component configuarions
# $Comp = 0 - project configuarion
# $Comp = 1 - component configuarion

sub EvaluateWildCards
{
    #  my ($NrC, @Config, $Comp) = @_;
    local
    ($NrC, *Config, $Comp, $ConfigFile) = @_;
    my $i = my $j = my $k = my $l = 0;
    my $li = my $lj = my $lk = 0;
    my $multiply = 1;
    my @Type     = ();
    #my @Param    = ();
    my $LEndian  = 1, $LRelType                         = 1, $LLinkType
                                                       = 1, $LTMHost
                                                       = 1,
    $LBsl                                              = 1; # nr of actual values of wildcard parameters

    @Param = split /~/, $Config[$NrC];

    #in a case of Trimedia we have host, otherwise we do not have
    my $tm_off;
    if( $Param[0] eq "tm" ) { $tm_off = 0; }
    else { $tm_off = 1;

    #  	print "not tm, $Param[0] \n";
        }
    ;
    $Nr = $#Param +1;

    # Insert empty field at diversity position (which is not defined in ProjectConfig file)
    if( $Comp == 0 )
    {
        for( $i = $Nr - 1; $i >= $WildposDiversity - 1; --$i ) { $Param[$i +1] = $Param[$i]; }
        $Param[$WildposDiversity -1] = "";

        $Config[$NrC]                = $Param[0];
        for( $i = 1; $i < $Nr + 1; ++$i ) { $Config[$NrC] = "$Config[$NrC]~$Param[$i]"; }
        @Param = split /~/, $Config[$NrC];

        $Nr    = $#Param +1;
    }
    if( $Comp == 1 )
    {
        my @PrintSyntax = ();
        my @CompConfigSyntax
            = qw(_TMTGTCPUCLASS _TMTGTOSCLASS _TMTGTOS _TMTGTENDIAN
                       _TMTGTCPUTYPE _TMDIVERSITY _TMTGTREL _TMTCSHOST _TMBSL
					   _TMLINKTYPE _TMTOOLCHAIN);
        if( ($BuildType eq "Component") && ($tm_off == 1) )
        {
            my $tmp = splice(@CompConfigSyntax, 7, 1);
            for( $i = 0; $i < 8; $i++ ) { $PrintSyntax[$i] = "<" . $CompConfigSyntax[$i] . "=" . $Param[$i] . ">" if (exists $Param[$i]); }
        }
        elsif( ($BuildType eq "Executable") && ($tm_off == 1) )
        {
            my $tmp = splice(@CompConfigSyntax, 7, 1);
            for( $i = 0; $i < 10; $i++ ) { $PrintSyntax[$i] = "<" . $CompConfigSyntax[$i] . "=" . $Param[$i] . ">" if (exists $Param[$i]); }
        }
        elsif( ($BuildType eq "Component") && ($tm_off == 0) )
        {
            for( $i = 0; $i < 9; $i++ ) { $PrintSyntax[$i] = "<" . $CompConfigSyntax[$i] . "=" . $Param[$i] . ">" if (exists $Param[$i]); }
        }
        elsif( ($BuildType eq "Executable") && ($tm_off == 0) )
        {
            for( $i = 0; $i < 11; $i++ ) { $PrintSyntax[$i] = "<" . $CompConfigSyntax[$i] . "=" . $Param[$i] . ">" if (exists $Param[$i]); }
        }
        $Syntax = join "~", @PrintSyntax;
        if( ($BuildType
                 eq "Component" and $Nr > 8 and $tm_off == 1) or ($BuildType eq "Component" and $Nr
                                                                      > 9 and $tm_off == 0) or ($BuildType
                                                                                                    eq "Executable" and $Nr
                                                                                                    > 10 and $tm_off
                                                                                                    == 1) or ($BuildType
                                                                                                                  eq "Executable" and $Nr
                                                                                                                  > 11 and $tm_off
                                                                                                                  == 0) )
        {
            $Message
                = "Warning: Too many ($Nr) configuration parameters for $BuildType should be,\n$Syntax \nin the file: $ConfigFile\n";
            print LOGFILE $Message;
            print REPORTLOGFILE $Message;
            print  $Message;
        }

    #    if ($Nr < 7) {
    #      $Message = "Warning: Too few ($Nr) configuration parameters for $BuildType $Config[$NrC]\n";
    #      print LOGFILE $Message;
    #      print REPORTLOGFILE  $Message;
    #      print STDOUT  $Message;
    #    }
    }
    #  print "Number params (Config[$NrC]): $Nr in $Config[$NrC]\n";         # debug statement
    # for ($i = 0; $i < $Nr; ++$i) {$j=$i+1; print "$j=$Param[$i]."; }       # debug statement
    # print ": EvaluateWildCards\n";                                         # debug statement

    if( ($Nr >= $WildposEndian) and ($Param[$WildposEndian -1] eq '*') )
    {
        $LEndian  = $#Endian +1;

        $multiply = $multiply * $LEndian;
        if( $LEndian < 1 ) { $Type[0] = "$ENDIAN "; }
    }
    if( ($Nr >= $WildposRelType) and ($Param[$WildposRelType -1] eq '*') )
    {
        $LRelType = $#RelType +1;

        $multiply = $multiply * $LRelType;
        if( $LRelType < 1 ) { $Type[1] = "$RELTYPE "; }
    }
    if( ($Nr >= $WildposLinkType - $tm_off) and ($Param[$WildposLinkType -1 - $tm_off] eq '*') )
    {
        $LLinkType = $#LinkType +1;

        $multiply  = $multiply * $LLinkType;
        if( $LLinkType < 1 ) { $Type[2] = "$LINKTYPE "; }
    }
    if( ($tm_off == 0) and ($Nr >= $WildposTMHost) and ($Param[$WildposTMHost -1] eq '*') )
    {
        #    print "Trimedia mul is made ! \n";
        $LTMHost  = $#TMHost +1;

        $multiply = $multiply * $LTMHost;
        if( $LTMHost < 1 ) { $Type[3] = "$HOST "; }
    }
    if( ($Nr >= $WildposBsl - $tm_off) and ($Param[$WildposBsl -1 - $tm_off] eq '*') )
    {
        $LBsl     = $#TMBsl +1;

        #    print "BSL mul is made, No $LBsl ! \n";
        $multiply = $multiply * $LBsl;
        if( $LBsl < 1 ) { $Type[4] = "$BSL "; }
    }
	unless (exists $Param[$WildposDiversity -1]) {
	if( ($Param[$WildposDiversity -1]
             ne "") and not (($Param[$WildposDiversity -1] =~ /^_/) and ($Param[$WildposDiversity -1] =~ /$_/)) )
    {
        print  "Invalid Diversity parameter: $Param[$WildposDiversity-1]\n";
        print  "In Line: $Config[$NrC]\n";
        print  "File: $ConfigFile\n";
        exit 1;
    }
	}
    if( $multiply <= 0 )
    {
        print  "Missing Wildcard definition: @Type\n";
        print  "In Line: $Config[$NrC]\n";
        print  "File: $ConfigFile\n";
        exit 1;
    }
    if( $multiply >= 1 )
    { # PID-CHANGE (3.8.3)
        for( $i = 1; $i < $multiply; ++$i ) { $Config[$NrC +$i] = $Config[$NrC]; }
        for( $mm = 0; $mm < $LBsl; ++$mm )
        {
            for( $i = 0; $i < $LEndian; ++$i )
            {
                for( $j = 0; $j < $LRelType; ++$j )
                {
                    for( $k = 0; $k < $LLinkType; ++$k )
                    {
                        for( $l = 0; $l < $LTMHost; ++$l )
                        {
                            #            print "Host numbers=$LTMHost\n";
                            $lk = $k * $LTMHost;
            $lj                 = $j * $LLinkType * $LTMHost;
            $li                 = $i * $LRelType  * $LLinkType * $LTMHost;
                            $lm = $mm * $LEndian  * $LRelType  * $LLinkType * $LTMHost;
                            if( ($Nr >= $WildposEndian) and ($Param[$WildposEndian -1]
                                                                 eq '*') ) { $Config[$NrC +$lm + $li + $lj + $lk + $l]
                                =~ s/\*/$Endian[$i]/; }
                            if( ($Nr >= $WildposRelType) and ($Param[$WildposRelType -1]
                                                                  eq '*') ) { $Config[$NrC +$lm + $li + $lj + $lk + $l]
                                =~ s/\*/$RelType[$j]/; }
                            if( ($tm_off
                                     == 0) and ($Nr >= $WildposTMHost) and ($Param[$WildposTMHost -1]
                                                                                eq '*') ) { $Config[$NrC +$lm + $li
                                                                                                             + $lj
                                                                                                             + $lk + $l]
                                =~ s/\*/$TMHost[$l]/; }
                            if( ($Nr >= $WildposBsl - $tm_off) and ($Param[$WildposBsl -1 - $tm_off] eq '*') )
                            {
                                if( $TMBsl[$mm] eq "" ) { #we support empty BSLs also.
                                    $Config[$NrC +$lm + $li + $lj + $lk + $l] =~ s/\*//;

                                #                  print "BSL repl is made to empty.\n";
                                    }
                                else { $Config[$NrC +$lm + $li + $lj + $lk + $l] =~ s/\*/$TMBsl[$mm]/;

                                #                  print "BSL repl is made to $TMBsl[$mm].\n";
                                    }
                            }
                            if( ($Nr >= $WildposLinkType - $tm_off) and ($Param[$WildposLinkType -1 - $tm_off]
                                                                             eq '*') ) { $Config[$NrC +$lm + $li + $lj
                                                                                                          + $lk + $l]
                                =~ s/\*/$LinkType[$k]/; }

                        #           $x = $NrC+$li+$lj+$lk+$l;                                           # debug statement
                        #           print "x=$x: $NrC+$li+$lj+$lk+$l = $Config[$NrC+$li+$lj+$lk+$l] \n";        # debug statement
                        }
                    }
                }
            }
        }
    }
    $NrC = $NrC +$multiply;

    # print "Nrc=$NrC\n";
    return $NrC;
}
#---------------------------------------------------------------------------------------
#
# Read the  Buildlist file 
# and store component entry points in the @BuildList table
#
sub ReadBuildlist
{
    my $i = 0;
    open(BUILD, "<" . $Buildlistfile) or die "Cant' open $Buildlistfile: $!";
    BUILD:
    while( $Line = <BUILD> )
    {
        next BUILD if $Line =~ /^$/; # skip empty lines
        next BUILD if $Line =~ /^\#/; # skip Comment lines
        chomp($Line);
        $Line          = StripBlank($Line);

        $BuildList[$i] = $Line;
        ++$i;
    }
}
#---------------------------------------------------------------------------------------
#
# Read the  ProjectConfig file  
# expand wildcards
# and store possible or requested configuration an array @Config
#

sub ReadProjectConfig
{
    local
    ($ConfigFile, *Config) = @_;
    my $Nr = 0;
    my $NrC = 0;

    #  print "ReadProjectConfig: $ConfigFile\n";              # debug statement

    unless( open CONFIG, "<" . $ConfigFile ) # Implemented as part of CR# 499
    {
        print  "No Project Config File ($ConfigFile) Found. Define correctly _TMPROJECT env. variable.\n";
        return(0, @Config);
    }
    CONFIG:
    while( $Line = <CONFIG> )
    {
        next CONFIG if $Line =~ /^$/; # skip empty lines
        next CONFIG if $Line =~ /^\#/; # skip Comment lines
        chomp($Line);
        $Line     =~ s/\s+//g;        # strip all the spaces
    $Line         =~ s/\t+//g;        # strip all the tabs
    #    print $Line."\n";                                    # debug statement

    $Config[$NrC] = $Line;
        $NrC      = EvaluateWildCards($NrC, \ @Config, 0, $ConfigFile);
    }
    close CONFIG;
    return($NrC, @Config);
}
#---------------------------------------------------------------------------------------
#
# Read the  BuildEntry Configfile: in $ConfigFile 
# expand wildcards
# and store requested configuration an array @Config and @Location
# $ConfigBuild=0 builds libraries
# $ConfigBuild=1 builds executables

sub ReadBuildEntryConfig
{
    local
    ($ConfigFile, $ConfigBuild, *Config, *Location) = @_;
    my $NrOld = 0;
    my $NrC   = 0;
    my @params;
    $BuildType = "Component";
    my $SaveLocation;
    my $p;
    my $j;

    #  print "ReadBuildEntryConfig: $ConfigFile\n";           # debug statement
    unless( open CONFIG, "<" . $ConfigFile ) # Implemented as part of CR# 499
    {
        print "No Config File ($ConfigFile) Found\n";
        return(0, @Config);
    }
    CONFIG:
    while( $Line = <CONFIG> )
    {
        $Line =~ s/\s*//g;            # strip all the spaces
        $Line =~ s/\t*//g;            # strip all the tabs
        chomp($Line);
        next CONFIG if $Line =~ /^$/; # skip empty lines
        next CONFIG if $Line =~ /^\#/; # skip Comment lines
        #    print "$Line, NrC=$NrC \n";
        last CONFIG if (($Line eq $ConfigurationSeparator) and ($ConfigBuild == 0)); # end of this configuration spec
        if( ($Line eq $ConfigurationSeparator) and ($ConfigBuild == 1) )
        {                                                                            # next of this configuration spec
            $BuildType = "Executable";                                               #ASSIGN executable to build conf.
            next CONFIG;
        }
        next CONFIG if (($ConfigBuild == 1) and ($BuildType
                                                     ne "Executable")); # next of this configuration spec + ASSIGN executable to build conf.
        $SaveLocation = $Line;

        #    print "Save location is: $Line\n";                                    # debug statement
        $p            = 0;
        CONFIG2:
        while( $Line = <CONFIG> )
        {
			$Line =~ s/\s+//g;             # strip all the spaces

            $Line =~ s/\t+//g;             # strip all the tabs
            chomp($Line);
            next CONFIG2 if $Line =~ /^$/; # skip empty lines
            next CONFIG2 if $Line =~ /^\#/; # skip Comment lines
            #      print ">> $Line, NrC=$NrC \n";
            last CONFIG if (($Line eq $ConfigurationSeparator) and ($ConfigBuild
                                                                        == 0)); # end of this configuration spec
            if( ($Line eq $ConfigurationSeparator) and ($ConfigBuild == 1) )
            {
                $Line         = <CONFIG>;

                $SaveLocation = $Line;

                #        print "Save location_2 is: $Line\n";                                    # debug statement
                next CONFIG2;
            }
            #      print "$Line\n";                                 # debug statement
            $p++;
            $NrOld      = $NrC +$p;
 			$Location[$NrOld] = $SaveLocation;
			$Config[$NrOld]   =$Line;
            $NrC        = EvaluateWildCards($NrOld, \ @Config, 1, $ConfigFile);
            for( $j = $NrOld + 1; $j < $NrC; ++$j ) { $Location[$j] = $Location[$NrOld];

            #        print " $Location[$j] $Config[$j]\n"; #debug (print de 1e niet!)  # debug statement
                }
        }
        $BuildType = "Executable";
    }
    close CONFIG;

    #  print "BuildEntryConfig=", $NrC, "\n";
    #  foreach (@Config){
    #       print $_,"\n";
    #  };
    return($NrC, @Config);
}
#---------------------------------------------------------------------------------------
# Compare possible or requested configuration and 
# write buildable configurations to the BuildConfig and BuildLocation tables (global)
# buildtype is 0 for libraries and 1 for executables.

sub CreateBuildableConfiguration
{
    local
    ($buildtype, *PConfig, *RConfig, *RLoc) = @_;
    (my $i,my $j)=(0,0);

    #  print "CreateBuildableConfiguration\n";              # debug statement
    #$i = 0;
    #foreach $PosConfig( sort @PConfig, ) { $i++;

    #    print "$i: Possible: $PosConfig\n";                # debug statement
    #    }
    #my $i = 0;
    #foreach $ReqConfig( sort @RConfig, ) { $i++;
    #
    #    print "$i: Required: $ReqConfig\n";                # debug statement
    #    }
    $NrBC           = 0;
	$#BuildConfig     = -1;
    $#BuildLocation = -1;

CONFLOOP:    for( $i = 0; $i <= $#RConfig; ++$i )
    {
        #   Filter out the diversity parameter
        #--------------------
        #   numbers to be checked - 7 for libraries and 10 for executables
        my $nmbrs;
        my $toolchain = "";
        if( $buildtype == 0 ) { $nmbrs = 7; }
        if( $buildtype == 1 ) { $nmbrs = 10; }
		if (defined $RConfig[$i])	 {
			if ($RConfig[$i]!~/^\s*$/) {
				$ReqConfig = $RConfig[$i];	
			}
		}
		else {
			$ReqConfig = "";
		}
		next CONFLOOP if ($ReqConfig=~/^\s*$/);
        @ReqConfSet = split /~/, $ReqConfig;
        $TempReqConfig = $ReqConfSet[0];
        if( ($TempReqConfig ne "tm") && ($buildtype == 1) ) { # for tm we have one field more.
            $nmbrs--; }
        if( $nmbrs + 1 == @ReqConfSet ) { $toolchain = $ReqConfSet[$nmbrs];
        #      open (LOGFILE,">>".$Logfile); 
        #      print LOGFILE "Toolchain is $toolchain \n";
        #      close LOGFILE;
            }
        else { $toolchain = ""; }
        for( $j = 1; $j < $nmbrs; ++$j )
        {
            if( $j != ($WildposDiversity - 1) ) { 
				$ReqConfSet[$j]="" if (!exists $ReqConfSet[$j]) ;
				$TempReqConfig = "$TempReqConfig~$ReqConfSet[$j]" ; 
				}
            else { 
				$TempReqConfig = "$TempReqConfig~"; 
				}
        }
        #    open (LOGFILE,">>".$Logfile); 
        #    print LOGFILE "Temp Required: $TempReqConfig\n";                # debug statement
        #    print LOGFILE "$i: Required: $BuildLocation[$i]: $ReqConfig\n"; # debug statement
        #    close LOGFILE;
        foreach $PosConfig( @PConfig )
        {
            #       if (($PosConfig =~ /mips/) and ($TempReqConfig =~ /mips/)){
            #        	print "Check $PosConfig against $TempReqConfig.\n";
            #       }
            if( ($PosConfig
                     =~ /^$TempReqConfig/) and ($TempReqConfig
                                                    ne "") and (($PosConfig =~ /$toolchain/) or ($toolchain eq "")) )
            {
                my @PosConfSet = split /~/, $PosConfig;
                my $PosConfSetNmbr = @PosConfSet;
                my $fail_cond  = 0;
                if( ($PosConfSet[0] eq "tm") && ($PosConfSetNmbr == 11) ) { $fail_cond = 1; }
                if( ($PosConfSet[0] ne "tm") && ($PosConfSetNmbr == 10) ) { $fail_cond = 1; }
                if( ($fail_cond == 1) && ($toolchain eq "") )
                {
                    open(LOGFILE, ">>" . $Logfile);
                    print LOGFILE $PosConfig . " DO NOT match " . $TempReqConfig
                                      . ", toolchain is $toolchain and ReqConf is $ReqConfig, nmbrs= $nmbrs and pos.cfg= $PosConfSetNmbr \n";
                    close LOGFILE;
                }
                else
                {
                    open(LOGFILE, ">>" . $Logfile);
                    print LOGFILE $PosConfig . " match "
                                      . $TempReqConfig . ", toolchain is $toolchain and ReqConf is $ReqConfig \n";
                    close LOGFILE;
                    $BuildConfig[$NrBC]   = $ReqConfig;

                    $BuildLocation[$NrBC] = $RLoc[$i];

                    #        print "                      $BuildLocation[$NrBC]: $ReqConfig\n";  # debug statement
                    ++$NrBC;
                    last;
                }
            }
        }
    }
}
#------------------------------------------------------------------------------------
# call the Make for combination Component/Configuration
# Build 0 - builds library, 1 - builds executable

sub ExecMake
{
    # use Cwd;
    ( my $buildtype, $BuildLocation, my $Configuration) = @_;
    my $Command;
    my $BuildLocDir;
    my @Dirs;
    my $Makefile;
    my $i;
    my $errors;
    my $warnings;
    my $StartTime;
    my $EndTime;
    my $Elapsed;
    my @DateTime;
    (@DateTime) = localtime(time);

    $StartTime  = timelocal(@DateTime);
    @configurations=split /~/, $Configuration;
    if( $buildtype == 0 )
    { # we are building library
        for( $i = 0; $i < 7; ++$i ) { $ENV {"$parameters[$i]"} = $configurations[$i]; }
        if( 8 == @configurations )
        {
            $ENV {"_TMTOOLCHAIN"} = $configurations[7];
            print  "SDE2: _TMTOOLCHAIN added to $configurations[7] \n" if ($DBG == 1);
            print REPORTLOGFILE "SDE2: _TMTOOLCHAIN added to $configurations[7] \n" if ($DBG == 1);
        }
        else { $ENV {"_TMTOOLCHAIN"} = ""; }
    }
    else
    { # we are building executables
        for( $i = 0; $i <= $#parameters; ++$i ) { $ENV {"$parameters[$i]"} = $configurations[$i] if (exists $configurations[$i]); }
        if( $ENV {$CPUCLASS} ne "tm" )
        { # only for trimedia a host parameter is present
            delete $ENV {$HOST};
            $ENV {$BSL} = $configurations[7] if (exists $configurations[7]);

            #    print "BSL is $ENV{$BSL}\n";
            $ENV {$LINKTYPE} = $configurations[8] if (exists $configurations[8]);
            $ENV {$TOOLCHAIN} = $configurations[9] if (exists $configurations[9]);
        }
        else
        { # PID-CHANGE (3.8.4)
            # Rule for CPUCLASS -- if it is 'tm' and host = 'nohost', start/end address is present
            # 			else				, start/end address is empty
            if( $ENV {$HOST} eq 'nohost' )
            {                                                 # PID-CHANGE (3.8.4)
                $ENV {'_TMSTARTADDR'} = $DefaultStartAddress; # PID-CHANGE (3.8.4)
                $ENV {'_TMENDADDR'}   = $DefaultEndAddress;   # PID-CHANGE (3.8.4)
            }                                                 # PID-CHANGE (3.8.4)
            else
            {                                                 # PID-CHANGE (3.8.4)
                delete $ENV {'_TMSTARTADDR'};                 # PID-CHANGE (3.8.4)
                delete $ENV {'_TMENDADDR'};                   # PID-CHANGE (3.8.4)
            }                                                 # PID-CHANGE (3.8.4)
        }                                                     # PID-CHANGE (3.8.4)
    }
    # Rule for _TMDIVERSITY -- if it is empty, we read get the value of _TMDIVERSITY
    if( ($ENV {$DIVERSITY} eq "") or (!exists $ENV {$DIVERSITY}) )
    {
        $ENV {$DIVERSITY} = $DefaultDiversity;
        print  "SDE2: Default diversity is taken!\n" if ($DBG == 1);
        print REPORTLOGFILE "SDE2: Default diversity is taken!\n" if ($DBG == 1);
    }
    # $BuildLocation contains location and name of the makefile, 
    if( $BuildLocation eq "" ) { return; } # ignore empty configurations
    # separate directory-path and makefile name from BuildLocation
    (@Dirs)        = split('/', $BuildLocation);

    $BuildLocation = $Dirs[0];
    for( $i = 1; $i < $#Dirs; ++$i ) { $BuildLocation = "$BuildLocation/$Dirs[$i]"; }
    $Makefile    = $Dirs[$i];

    #  print "Makefile: $Makefile \n";
    #  print "zzzzzzz $BuildEntry/$BuildLocation xxxxxxxxx\n";
    $BuildLocDir = FindDirLocation("$BuildEntry/$BuildLocation");
    if( $^O eq "MSWin32" )
    {
        ($Drive) = split(/\:/, $BuildLocDir);

        $Command = "$Drive:";
        print  "SDE2: Executing command: $Command \n" if ($DBG == 1);
        print REPORTLOGFILE "SDE2: Executing command: $Command \n" if ($DBG == 1);
        system($Command);
    }
    if( not -e $BuildLocDir )
    {
        print  "Component/Configuration: $BuildEntry/$BuildLocation: Build Location does not exist: build_failed\n";
        print REPORTLOGFILE "Component/Configuration: $BuildEntry/$BuildLocation: Build Location does not exist: build_failed\n";
        if( $Fail eq "stop" ) { exit; }
        return;
    }
    chdir($BuildLocDir);

    $TmpLog    = "$ENV{'_TMREPORTS'}/tmp_log.log";
    $TmpErrorLog = "$ENV{'_TMREPORTS'}/tmp_error.log";
    chomp($Makefile);

    print  "${format}\nFor ${Configuration}\n${format}\n";
    $Command   = "$ENV{'MAKE'} -f $Makefile $BuildGoals > $TmpLog 2> $TmpErrorLog";

	print REPORTLOGFILE "SDE2: Executing command: $Command \n";
	print  "SDE2: Executing command: $Command \n" if ($DBG == 1);
    print REPORTLOGFILE "SDE2: Executing command: $Command \n" if ($DBG == 1);
    `$Command`;

    # Checking tmp_error.log for warnings or errors
    $Exit_value = $?;

  #  print "Exit_value=$Exit_value \n";

    $errors     = 0;
    $warnings   = 0;
    open(TMPLOGFILE, "$TmpLog");
    open(LOGFILE, ">>$Logfile");
    while( $line = <TMPLOGFILE> )
    {
        print LOGFILE $line;
        if( ($line =~ /\berror\b/i) and ($Exit_value != 0) )
        {
            $errors++;
            print  "$line \n";
        }
        elsif( ($line =~ /\bno rule\b/i) and ($Exit_value != 0) )
        {
            # This happens when a specified sourcefile does not exist.
            $errors++;
            print  "$line \n";
        }
        elsif( $line =~ /[^-]warning\b/i )
        {
            $warnings++;
            print  $line;
        }
        else { print  $line; }
    }
    if( ($Exit_value != 0) and ($errors == 0) ) { $errors = 1; }
    close LOGFILE;
    close TMPLOGFILE;
    unlink $TmpLog or warn "\n";

    open(TMPERRORLOG, "$TmpErrorLog");

    #  open (ERRORLOGFILE,">>$ErrorLogfile"); 
    while( $line = <TMPERRORLOG> )
    {
        print REPORTLOGFILE $line;
        if( ($line =~ /\berror\b/i) and ($Exit_value != 0) )
        {
            $errors++;
            print  "$line \n";
        }
        elsif( $line =~ /\bno rule\b/i )
        {
            # This happens when a specified sourcefile does not exist.
            $errors++;
            print  "$line \n";
        }
        elsif( $line =~ /[^-]warning\b/i ) { $warnings++; }
    }
    #  close ERRORLOGFILE;
    close TMPERRORLOG;

    open(LOGFILE, ">>$Logfile");

    # open (ERRORLOGFILE,">>$ErrorLogfile"); 
    (@DateTime) = localtime(time);
  $EndTime      = timelocal(@DateTime);
    $Elapsed    = $EndTime -$StartTime;
    if( $errors
            > 0 ) { $Message = "Component/Configuration: $BuildLocation $Configuration: build_failed ($Elapsed sec.)\n";

    $Exit_value              = 1; }
    elsif( $warnings > 0 ) { $Message
        = "Component/Configuration: $BuildLocation $Configuration: built with warnings ($Elapsed sec.)\n"; }
    else
    {
        $Message = "Component/Configuration: $BuildLocation $Configuration: built successfully ($Elapsed sec.)\n";
        if( $BuildGoals =~ /clean/ ) { $Message
            = "Component/Configuration: $BuildLocation $Configuration: removed successfully \n"; }
    }
    print LOGFILE $Message;
    print REPORTLOGFILE $Message;
    print  $Message;
    close LOGFILE;

#  close ERRORLOGFILE;
}

#--------------------------------------------------------------------------------------------
# Create loc_list files
# This function is not called.Hence can be removed. Another function by the same
# name is being executed
sub CreateMakelist
{
	eval {mkpath("$_TMTGTBUILDPROJECT")};
   if ($@) {
   print "Couldn't create $_TMTGTBUILDPROJECT: $@";
   }
    readDomains($TM_PRJLIST);
    findComps();
    writeLocLists();
}

#----------------------------------------------------------------------
# Exapand all $var, ${var}, $(var) environment variables
#
sub envExpand
{
    my $inp = shift;
    my $exp;
    my $var;
    my $pre;
    my $post;

    $exp = $inp;

    $var = "start";
    while( $var ne "" )
    {
        $var = "";
        if( $exp =~ m|(.*)\$(\w+)(.*)| ) { $pre = $1;
      $var                                      = $2;
        $post                                   = $3; }
        elsif( $exp =~ m|(.*)\$\{(\w+)\}(.*)| ) { $pre = $1;
      $var                                             = $2;
        $post                                          = $3; }
        elsif( $exp =~ m|(.*)\$\((\w+)\)(.*)| ) { $pre = $1;
      $var                                             = $2;
        $post                                          = $3; }
        if( $var ne "" ) { $exp = $pre . $ENV {$var} . $post; }
    }
    return $exp;
}

#----------------------------------------------------------------------
# Read project domains into internal array
#
sub readDomains
{
    my $prjlist = shift;

    # local *PH ;

    open(PH, "<$prjlist") || die("could not open $prjlist");
    local $/; # enable localized slurp mode
    #Read the entire file contents in 
    my $fileContents = <PH>;
    close PH;

    #Remove the contents if the line is commeneted 
    $fileContents =~ s/\#.*\n//g;

    #Split the file contents  on space
    my @paths = split(/\s+/, $fileContents);
    foreach my $eachPath( @paths )
    {
        chomp;
        $eachPath=~s/\s+//g;
        if( $eachPath ne "" )
        {
            #Expand the path and store it in the domain array
            $domain = envExpand($eachPath);
	    $domain =~ s/\\/\//g; 
            #Split the values on space
            my @splitValues = split(/ /, $domain);
            push @domains, @splitValues;
        }
    }
}
#----------------------------------------------------------------------
# Create hash of all comps/intfs
# Search project list from bottom to top
# Only save unique components in the hash
#
sub findComps
{
    my $domain;
    my $compMakefile;
    my @compMakefiles;
    my $intfsDir;
    my @intfsDirs;
    my $head;
    my $tail;

    #Added the appropriate path to search for the
    # files present on comps dir

    foreach $domain( reverse @domains )
    {
        my @compsDirs = glob("$domain/comps/*");
        foreach my $compsDir( @compsDirs )
        {
            if( $compsDir =~ / / ) { next; }
            if( !-d $compsDir ) { next; }

            # Get the component name and the directory path 
            #Store the value in the hash
            $compsDir =~ m|(.*)/([^/]+)$|;
			$head	= $1;
            $tail	= $2;
            if( !defined($comps {$tail}) ) { $comps {$tail} = "$head/$tail"; }
        }
        @intfsDirs = glob("$domain/intfs/*");
        foreach $intfsDir( @intfsDirs )
        {
            if( $intfsDir =~ / / ) { next; }
            if( !-d $intfsDir ) { next; }
            $intfsDir =~ m|(.*)/([^/]+)$|;
			$head	= $1;
            $tail	= $2;
            if( !defined($comps {$tail}) ) { $comps {$tail} = "$head/$tail"; }
        }
        @typesDirs = glob("$domain/types/*");
        foreach $typesDirs( @typesDirs )
        {
            if( $typesDirs =~ / / ) { next; }
            if( !-d $typesDirs ) { next; }
            $typesDirs =~ m|(.*)/([^/]+)$|;
			$head	= $1;
            $tail	= $2;
            if( !defined($comps {$tail}) ) { $comps {$tail} = "$head/$tail"; }
        }
    }
}
#----------------------------------------------------------------------
# write loc_list.mk and loc_list.txt
#
sub writeLocLists
{
    my $comp;
    my $dir;
    local * TH;
    local * MH;
    $string = qq(generating $LOC_LIST_FILENAME ...
generating $LOC_LIST_MKFILENAME ...\n$format\n);
    print($string);

    open(TH, ">$LOC_LIST_FILENAME") || die("could not open $LOC_LIST_FILENAME");
    open(MH, ">$LOC_LIST_MKFILENAME") || die("could not open $LOC_LIST_MKFILENAME");

    print MH "# $LOC_LIST_MKFILENAME\n";
    print MH "# DO NOT EDIT. This file has been generated automatically.\n";

    #: Write the contents of the hash comps into the file, loc_list.mk and loc_list.txt
    foreach $comp( sort keys %comps )
    {
        $dir = $comps {$comp};
        print TH "$comp $dir ";
        print MH "_$comp" . "_DIR := $dir\n";
    }
    print TH "\n";

    close(TH);
    close(MH);
}
#----------------------------------------------------------------------
# write prjlist.txt
sub writePrjList
{
    my $domain;
    local * PH;

    chmod(0777, $TM_PRJLIST);
    unlink($TM_PRJLIST);

    $string = qq(creating loc_list files ...
generating $TM_PRJLIST ...\n);
    write();

    open(PH, ">$TM_PRJLIST") || die("could not open $TM_PRJLIST");

    print PH "# $TM_PRJLIST\n";
    print PH "# DO NOT EDIT. This file has been generated automatically.\n";

    #: Write the contents present in domains array into the file, prjlist
    foreach $domain( @domains ) { print PH "$domain\n"; }
    close(PH);
}


################################################################################################
# Program start 
#

    print  "$format1\n";
    print  "SDE2 build.pl script version $pid_version \n\n\n";
    print  "(c) NXP Semiconductors , 2006\n";
    print  "$format1\n";
    print  "Debug mode.\n" if ($DBG == 1);
    print REPORTLOGFILE "Debug mode.\n" if ($DBG == 1);

CheckEnvironment();
#Variables used to create loc_list files
$_TMROOT             = $ENV {"_TMROOT"};
$_TMROOT             =~ s/\\/\//g; 
$_TMTGTBUILDROOT     = $ENV {"_TMTGTBUILDROOT"};
$_TMTGTBUILDROOT     =~ s/\\/\//g; 
	
if( exists $ENV {'_TMTGTBUILDROOT'} ) 
{ $_TMTGTBUILDPROJECT  = "$_TMTGTBUILDROOT/project"; }
	else
	{ $_TMTGTBUILDPROJECT  = "$_TMROOT/project"; }

if(exists $ENV{'_TMPROJECT'} && -d "$ENV{'_TMPROJECT'}"){
	if (-f "$ENV{'_TMPROJECT'}/prjlist.txt") {
		$TM_PRJLIST          = "$ENV{'_TMPROJECT'}/prjlist.txt";
	} 
	else {
   print ("File not found: $ENV{'_TMPROJECT'}/prjlist.txt\n");
   exit 1;
	}
}
else {
$TM_PRJLIST          = "$ENV{'_TMROOT'}/project/prjlist.txt";
}
	ReadProjectList();

  if ($NoEnvPrj == 1) {
  	$ProjectConfigFile   = "$ENV{'_TMROOT'}/project/$ProjectConfigFile";
  	$Buildlistfile       = "$ENV{'_TMROOT'}/project/$Buildlistfile";
    $ProjectDir		     = "$ENV{'_TMROOT'}/sde/$ENV{'_TMTGTCPUCLASS'}_$ENV{'_TMTGTOSCLASS'}" if (!exists $ENV{'_TMTOOLCHAIN'});
    $ProjectDir		     = "$ENV{'_TMROOT'}/sde/$ENV{'_TMTGTCPUCLASS'}$ENV{'_TMTOOLCHAIN'}_$ENV{'_TMTGTOSCLASS'}" if (exists $ENV{'_TMTOOLCHAIN'});
    $WildcardFile        = "$ENV{'_TMROOT'}/project/$WildcardFile";
  }
  else {
  	$ProjectConfigFile   = "$ENV{'_TMPROJECT'}/$ProjectConfigFile";
  	$Buildlistfile       = "$ENV{'_TMPROJECT'}/$Buildlistfile";
	$ProjectDir		     = "$ENV{'_TMPROJECT'}/$ENV{'_TMTGTCPUCLASS'}_$ENV{'_TMTGTOSCLASS'}" if (!exists $ENV{'_TMTOOLCHAIN'});
	$ProjectDir		     = "$ENV{'_TMPROJECT'}/$ENV{'_TMTGTCPUCLASS'}$ENV{'_TMTOOLCHAIN'}_$ENV{'_TMTGTOSCLASS'}" if (exists $ENV{'_TMTOOLCHAIN'});
	$WildcardFile      = "$ENV{'_TMPROJECT'}/$WildcardFile";
  }
  $ReportLogfile       = "$ENV{'_TMREPORTS'}/$ReportLogfile";
  $Logfile             = "$ENV{'_TMREPORTS'}/$Logfile";

  $DefaultDiversity    = "$ENV{'_TMDIVERSITY'}";
  $DefaultStartAddress = '';                          # PID-CHANGE (3.8.4)
    $DefaultEndAddress = '';                          # PID-CHANGE (3.8.4)
    if( exists $ENV {'_TMSTARTADDR'} ) {              # PID-CHANGE (3.8.4)
        $DefaultStartAddress = $ENV {'_TMSTARTADDR'}; # PID-CHANGE (3.8.4)
        }                                             # PID-CHANGE (3.8.4)
    if( exists $ENV {'_TMENDADDR'} ) {                # PID-CHANGE (3.8.4)
        $DefaultEndAddress = $ENV {'_TMENDADDR'};     # PID-CHANGE (3.8.4)
        }                                             # PID-CHANGE (3.8.4)


    CheckParameters(@ARGV);

	$LOC_LIST_FILENAME   = "$_TMTGTBUILDPROJECT/loc_list.txt";
	$LOC_LIST_MKFILENAME = "$_TMTGTBUILDPROJECT/loc_list.mk";
	
	CreateMakelist();

    if( not -d $ENV {'_TMREPORTS'} )
    {
        #mkdir $ENV{'_TMREPORTS'}, 0755;
        #$CreateDir = "mkdir -p $ENV{'_TMREPORTS'}";
        #system $CreateDir;
		eval {mkpath("$ENV{'_TMREPORTS'}")}
    }
    if( $#BuildList < 0 ) { # 1e parameter is all, so read the buildlist.txt
        ReadBuildlist(); }
    ($Sec, $Min, $Hours, $Mday, $Mon, $Year) = localtime(time);

    open(REPORTLOGFILE, ">" . $ReportLogfile);
    open(LOGFILE, ">" . $Logfile); # make file empty, output will be concatenated in function ExecBatch

    $Message = sprintf "%04d-%02d-%02d at %02d:%02d:%02d\n", ($Year + 1900), ($Mon + 1), $Mday, $Hours, $Min, $Sec;
    printf REPORTLOGFILE $Message;
    printf LOGFILE $Message;
    printf  $Message;
    close LOGFILE;

    #-------------------- Added for solving PR no 509 -----------------

    if( $BuildGoals =~ /clean_all/ )
    {
        print  "Removing the Build location completely.....\n";
        if( open(LISTFILE, "<$Buildlistfile") )
        {
            CLEAN:
            while( $line = <LISTFILE> )
            {
                next CLEAN if $line =~ /^\s*$/; # skip empty lines
                next CLEAN if $line =~ /^\#/;   # skip Comment lines
                if( $line =~ /[A-Za-z]/ ) { $line_add = $line; }
            }
            chomp($line_add);
            close LISTFILE;
        }
        my $MakeFile = "makefile";
        my $MakeDirectory = FindDirLocation($line_add);
        $Command = "$ENV{'MAKE'} -f $MakeDirectory\/$MakeFile clean_all";
        print  "SDE2: Executing command: $Command \n" if ($DBG == 1);
        print REPORTLOGFILE "SDE2: Executing command: $Command \n" if ($DBG == 1);
        `$Command`;
        $BuildGoals =~ s/clean_all//;
        if( $BuildGoals =~ /^\s*$/ ) { exit 0; }
    }
    #---------------------------------------------------------------------------------------

    ReadWildCards();
    if( $DBG == 1 )
    {
        foreach $x( @RelType )
        {
            print  "SDE2: RelType value: $x\n";
            print REPORTLOGFILE "SDE2: RelType value: $x\n";
        }                          # debug statement
    }
    $#PossibleConfig         = -1; # empty table

    ($NrPC, @PossibleConfig) = ReadProjectConfig($ProjectConfigFile, \ @PossibleConfig);
    if( $DBG == 1 )
    {
        print  "SDE2: Possible Config: \n";
        print REPORTLOGFILE "SDE2: Possible Config: \n";
        foreach $PossibleConfig( @PossibleConfig )
        {
            print  $PossibleConfig . "\n";
            print REPORTLOGFILE $PossibleConfig . "\n";
        }
        print  "SDE2: Number starting configurations: $NrPC \n";
        print REPORTLOGFILE "SDE2: Number starting configurations: $NrPC \n";
    }
    foreach $BuildEntry( @BuildList )
    { # libraries
        print  "BuildEntry: $BuildEntry, Configuration file: $ConfigFile\n" if ($DBG == 1);
        print REPORTLOGFILE "BuildEntry: $BuildEntry, Configuration file: $ConfigFile\n" if ($DBG == 1);
if ($CompConfigFileExists == 0) {
		$BuildEntryConfigFile
                                  = FindFileLocation("$BuildEntry/$ConfigFile");
}
else {
		$BuildEntryConfigFile = $CompConfigFile;
}
    $#RequestedConfig             = -1; # empty table
    $#RequestedLocation           = -1; # empty table
        ($NrRC, @RequestedConfig)
                                  =
		ReadBuildEntryConfig($BuildEntryConfigFile, 0, \ @RequestedConfig, \ @RequestedLocation);
        if( $DBG == 1 )
        {
            print  "SDE2: Requested Config: \n";
            print REPORTLOGFILE "SDE2: Requested Config: \n";
            foreach $RequestedConfig( @RequestedConfig )
            {
                print  $RequestedConfig . "\n";
                print REPORTLOGFILE $RequestedConfig . "\n";
            }
            print  "SDE2: Number requested configurations: $NrRC \n";
            print REPORTLOGFILE "SDE2: Number requested configurations: $NrRC \n";
        }
        CreateBuildableConfiguration(0, \ @PossibleConfig, \ @RequestedConfig, \ @RequestedLocation);
        if( $DBG == 1 )
        {
            print  "SDE2: Buildable Config ($NrBC configurations): \n";
            print REPORTLOGFILE "SDE2: Buildable Config ($NrBC configurations): \n";
            for( $i = 0; $i < $NrBC; ++$i )
            {
                print  "$BuildLocation[$i], $BuildConfig[$i] \n";
                print REPORTLOGFILE "$BuildLocation[$i], $BuildConfig[$i] \n";
            }
        }
        if( $NrBC > 0 )
        {
            $Message  = "$format2\n";

            $Message2 = "Building for Component " . $BuildEntry . "\n";
            if( $BuildGoals_target =~ /clean/ ) { $Message2
                = "Removing Build Location for Component " . $BuildEntry . "\n"; }
            open(LOGFILE, ">>" . $Logfile);
            print LOGFILE $Message, $Message2, $Message;
            print  $Message, $Message2, $Message;
            close LOGFILE;

            #      open (ERRORLOGFILE,">>".$ErrorLogfile); 
            #      print ERRORLOGFILE $Message, $Message2, $Message;
            #      close ERRORLOGFILE;
            print REPORTLOGFILE $Message, $Message2, $Message;
            print  "SDE2: All configurations are NrBC=$NrBC\n" if ($DBG == 1); # debug statement
            print REPORTLOGFILE "SDE2: All configurations are NrBC=$NrBC\n" if ($DBG == 1);
            for( $i = 0; $i < $NrBC; ++$i )
            {
                ExecMake(0, $BuildLocation[$i], $BuildConfig[$i]);
                last if (($Exit_value > 0) and ($Fail eq 'stop'));
            }
            last if (($Exit_value > 0) and ($Fail eq 'stop'));
        }
        else
        {
            print  "$format2\nNo configurations to be built for $BuildEntry.\n";
            print  "Please check your Project's and Component's configurations.txt.\n$format2\n";
            print REPORTLOGFILE "$format2\nNo configurations to be built for $BuildEntry.\n";
            print REPORTLOGFILE "Please check your Project's and Component's configurations.txt.\n$format2\n";
        }
    }
    if( ($Exit_value == 0) or ($Fail ne 'stop') )
    {
        foreach $BuildEntry( @BuildList )
        { # executables
            print  "BuildEntry: $BuildEntry:\n";
 if ($CompConfigFileExists == 0) {
		$BuildEntryConfigFile
                                  = FindFileLocation("$BuildEntry/$ConfigFile");
}
else {
		$BuildEntryConfigFile = $CompConfigFile;
}
    $#RequestedConfig                 = -1; # empty table
    $#RequestedLocation               = -1; # empty table
	($NrRC, @RequestedConfig)
                                      =
			ReadBuildEntryConfig($BuildEntryConfigFile, 1, \ @RequestedConfig, \ @RequestedLocation);
			CreateBuildableConfiguration(1, \ @PossibleConfig, \ @RequestedConfig, \ @RequestedLocation);
            if( $NrBC > 0 )
            {
                $Message  = "$format2\n";

	            $Message2 = "Building for Executable " . $BuildEntry . "\n";
		        if( $BuildGoals_target =~ /clean/ ) { $Message2
                = "Removing Build Location for Executable " . $BuildEntry . "\n";}
                open(LOGFILE, ">>" . $Logfile);
                print LOGFILE $Message, $Message2, $Message;
                print  $Message, $Message2, $Message;
                print REPORTLOGFILE $Message, $Message2, $Message;
                if( $DBG == 1 )
                {
                    print  "SDE2: NrBC=$NrBC\n"; # debug statement
                    print REPORTLOGFILE "SDE2: NrBC=$NrBC\n";
                    print  "SDE2: Buildable Config Executables: \n";
                    print REPORTLOGFILE "SDE2: Buildable Config Executables: \n";
                    for( $i = 0; $i < $NrBC; ++$i )
                    {
                        print  "$BuildLocation[$i], $BuildConfig[$i] \n";
                        print REPORTLOGFILE "$BuildLocation[$i], $BuildConfig[$i] \n";
                    }
                }
                if( $NOEXEC == 0 )
                { # Do not build executables if -noexec parameter is specified   -- PID-CHANGE
                    for( $i = 0; $i < $NrBC; ++$i )
                    {
                        print  "Executing for $BuildLocation[$i], $BuildConfig[$i] \n" if ($DBG == 1);
                        print REPORTLOGFILE "Executing for $BuildLocation[$i], $BuildConfig[$i] \n" if ($DBG == 1);
                        ExecMake(1, $BuildLocation[$i], $BuildConfig[$i]);
                        $Exit_value_summary += $Exit_value;
                        last if (($Exit_value > 0) and ($Fail eq 'stop'));
                    }
                }
                close LOGFILE;
                last if (($Exit_value > 0) and ($Fail eq 'stop'));
            }
        } # foreach+
    }     # if build failed
    close REPORTLOGFILE;
    exit $Exit_value_summary;
