Rev 5709 | Blame | Compare with Previous | Last modification | View Log | RSS feed
######################################################################### COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.## Module name : ToolsetPrinter.pm# Module type : Perl Module# Compiler(s) : Perl# Environment(s): jats## Description : Common toolset utils# Toolset I/O stream for creating makefile rules and recipes# Usage:## New Create a new stream## Prt Print a raw line## PrtLn Print a raw line and a new line## PrtPart Print a raw line that will be extended. Contains continuation charaters and a new line## Newline Print a single new line## Tag Tagged line print.## Cmd Command line print, tagged with meta quoted and terminates.## SetTag Set the "tag", default none.## SetTerm Set the command line "terminator", default "\\n\n".## Label Print generalised label## StartDef Create a Definition# Def Accumulate# EndDef Print it out## ObjList Generate a object list, using the specified recipe.## LibList Generate a library list, using the specified recipe.## DepRules Generate library dependency rules################################################################################use strict;use warnings;package ToolsetPrinter;sub New{my ($tag, $cmdterm) = @_;$tag = "" if ( !defined($tag) ); # default tag$cmdterm = "\\n\n" # and terminatorif ( !defined($cmdterm) );my ($self) = {TAG => $tag,CMDTERM => $cmdterm};return bless $self, __PACKAGE__;}sub Reset{my ($self) = shift;delete $self->{DEPEND_target};delete $self->{DEPEND_list};delete $self->{DEPEND_dir};delete $self->{DEPEND_file};}sub Prt{my ($self) = shift;::MakePrint ("@_");}sub PrtLn{my ($self) = shift;::MakePrint ("@_\n");}sub PrtPart{my ($self) = shift;::MakePrint ("@_ \\\n");}sub Entry{my ($self) = shift;::MakeEntry( @_ );}sub Newline{my ($self) = shift;::MakePrint ("\n");}sub SetTag{my ($self) = shift;my ($tag) = @_;$tag = "" if ( !defined($tag) );$self->{TAG} = $tag;}sub SetTerm{my ($self) = shift;my ($cmdterm) = @_;$cmdterm = "\\n\n" # default terminatorif ( !defined($cmdterm) );$self->{CMDTERM} = $cmdterm;}sub Cmd{my ($self) = shift;::MakeQuote ("$self->{TAG}\t+=@_$self->{CMDTERM}");}sub Tag{my ($self) = shift;::MakePrint ("$self->{TAG}\t+=@_\n");}sub Label{my ($self) = shift;my ($desc, $target) = @_;$self->Prt( "#.. $desc ($target)\n\n" );}sub ObjList{my ($self) = shift;my ($target, $objs, $genrecipe, @uargs) = @_;foreach (@$objs){&$genrecipe( $self, $target, $_, @uargs );}}sub StartDef{my ($self) = shift;my ($tag) = @_;$tag = "" if ( !defined($tag) );$self->{DEF} = $tag;$self->{DEFS} = [];}sub Def{my ($self) = shift;push @{$self->{DEFS}}, "@_";}sub EndDef{my ($self) = shift;::MakeDefEntry ( $self->{DEF}, '=' , $self->{DEFS} );delete $self->{DEFS};}#privatesub CondParse{my ($target, $cond) = @_;if ($cond =~ /^--ifdef=(.*)/) { # .. ifdef XXX$cond = "ifdef $1";} elsif ($cond =~ /^--ifndef=(.*)/) { # .. ifndef XXX$cond = "ifndef $1";} elsif ($cond =~ /^--ifdebug$/) { # .. if DEBUG$cond = "ifeq \"\$(DEBUG)\" \"1\"";} elsif ($cond =~ /^--ifprod$/) { # .. if PRODUCTION$cond = "ifeq \"\$(DEBUG)\" \"0\"";} elsif ($cond =~ /^--ifeq=(.*):(.*)$/) { # .. ifeq XXXX:YYYY$cond = "ifeq \"\$($1)\" \"$2\"";} elsif ($cond =~ /^--ifneq=(.*):(.*)$/) { # .. ifneq XXXX:YYYY$cond = "ifneq \"\$($1)\" \"$2\"";} else { # .. unknown::Error( "$target: unknown conditional construct '$cond'" );$cond = "";}return $cond;}#privatesub CondOpen{my ($self) = shift;@{$self->{CONDSTACK}} = ();}#privatesub CondModify{my ($self) = shift;my ($newstack) = @_;my ($oldstack) = \@{$self->{CONDSTACK}};my ($idx, $cond);# Diff the two stacks#$idx = 0;while ( $idx <= $#$newstack &&$idx <= $#$oldstack &&$$newstack[$idx] eq $$oldstack[$idx] ) {$idx++;}# Pop diff#while ($idx <= $#$oldstack) {$cond = pop @$oldstack;$self->Prt( " " x ($#$oldstack+1) . "endif\n" );}# Push diff#while ($idx <= $#$newstack) {$self->Prt( " " x $idx . "$$newstack[$idx]\n" );$idx++;}@{$self->{CONDSTACK}} = @$newstack;}#privatesub CondClose{my ($self) = shift;my (@newstack) = ();$self->CondModify( \@newstack ); # pop any stacked conditionals}sub LibList{my ($self) = shift;my ($target, $libs, $genrecipe, @uargs) = @_;my (@cond, $t_cond) = ();$self->CondOpen(); # open a conditional sessionforeach (@$libs){if (/^--if/) # inlined conditionals{push @cond, $t_condif (($t_cond = CondParse( $target, $_ )) ne "");}elsif (/^--/) # arguments{&$genrecipe( $self, $target, $_, @uargs );}else # library{my (@args) = split( "\n\t\t", $_ ); # see makeif.plmy ($lib) = shift @args;# Associated conditionals (if any)#foreach (@args) {push @cond, $t_condif (($t_cond = CondParse( $target, $_ )) ne "");}$self->CondModify( \@cond ); # modify@cond = ();# Generate recipe#&$genrecipe( $self, $target, $lib, @uargs );}}$self->CondClose(); # close session}#-------------------------------------------------------------------------------# Function : SetShldTarget## Description : Set up the Shared Library target information# Main function is to calculate the name of the# dependency file so that it can be used## Must be called before SHLDDEPEND or DepRules## Inputs : $self# $target - Name of the target library# May or may not have $(GBE_TYPE)# $dir - Optional alternate directory# Default: LIBDIR## Returns : Full name of the dependency file#sub SetShldTarget{my ($self, $target, $dir ) = @_;::Warning("Internal: SetShldTarget already specified") if ( defined $self->{DEPEND_target} );# Create a 'tag' to be used within the makefile#$self->{DEPEND_target} = $target;$self->{DEPEND_list} = $target . '_shdp';## Set up the name of the dependency file#$dir = 'LIBDIR' unless ( defined $dir );$self->{DEPEND_dir} = $dir;my $depfile = "\$($dir)/${target}";$depfile .= '$(GBE_TYPE)' unless ( $depfile =~ m~\$\(GBE_TYPE\)~ );$depfile .= '.dep';$self->{DEPEND_file} = $depfile;::Verbose3("SetShldTarget","DepDir: $self->{DEPEND_dir}","DepFile: $self->{DEPEND_file}","DepList: $self->{DEPEND_list}" );return $depfile;}#-------------------------------------------------------------------------------# Function : SHLDDEPEND## Description : Create a set of rules and recipes to handle the creation# of dependency files used in the creation of shared# libraries### Inputs : $self# $base - SHBASE: Defines the shared library name (eg: lib)# $name - SHNAME: Defines the base library name (eg: lib.so.1.1)#sub SHLDDEPEND{my ($self) = shift;my ($base, $name) = @_;## Sanity test: The name of the list must have been setup#my $depfile = $self->{DEPEND_file} || ::Error ("Internal error: SetShldTarget not called before SHLDDEPEND");$self->Newline();$self->Label( "Include Shared Library Dependency Rules", $self->{DEPEND_target} );$self->Prt("${depfile}:\tSHBASE=${base}${depfile}:\tSHNAME=${name}${depfile}:\tDPLIST=$self->{DEPEND_list}${depfile}:\t\$(GBE_$self->{DEPEND_dir}) \$(SCM_MAKEFILE)\$(SHLDDEPEND)ifneq \"\$(findstring \$(IFLAG),23)\" \"\"-include\t${depfile}endif" );# Mark file as generated by the toolset#::ToolsetGenerate( $depfile );}#-------------------------------------------------------------------------------# Function : SetLdTarget## Description : Set up the Program target information# Main function is to calculate the name of the# dependency file so that it can be used## Must be called before LDDEPEND or DepRules## Inputs : $self# $target - Name of the target program# $dir - Optional alternate directory# Default: BINDIR## Returns : Full name of the dependency file#sub SetLdTarget{my ($self, $target, $dir ) = @_;::Warning("Internal: SetLdTarget already specified") if ( defined $self->{DEPEND_target} );# Create a 'tag' to be used within the makefile#$self->{DEPEND_target} = $target;$self->{DEPEND_list} = $target . '_dp';## Set up the name of the dependency file#$dir = 'BINDIR' unless ( defined $dir );$self->{DEPEND_dir} = $dir;my $depfile = "\$($dir)/${target}.dep";$self->{DEPEND_file} = $depfile;::Verbose3("SetLdTarget","DepDir: $self->{DEPEND_dir}","DepFile: $self->{DEPEND_file}","DepList: $self->{DEPEND_list}" );return $depfile;}#-------------------------------------------------------------------------------# Function : LDDEPEND## Description : Create a set of rules and recipes to handle the creation# of dependency files used in the creation of a program### Inputs : $self#sub LDDEPEND{my ($self) = shift;## Sanity test: The name of the list must have been setup#my $depfile = $self->{DEPEND_file} || ::Error ("Internal error: SetLdTarget not called before LDDEPEND");$self->Newline();$self->Label( "Include Library Dependency Rules", $self->{DEPEND_target} );$self->Prt("${depfile}:\tDPLIST=$self->{DEPEND_list}${depfile}:\t\$(GBE_$self->{DEPEND_dir}) \$(SCM_MAKEFILE)\$(LDDEPEND)ifeq \"\$(IFLAG)\" \"3\"-include\t${depfile}endif" );# Mark file as generated by the toolset#::ToolsetGenerate( $depfile );}#-------------------------------------------------------------------------------# Function : DepRules## Description : Create the list of dependency rules used# within the dependency include file## Inputs : $libs - Ref to a list of libraries# $librecipe - Ref to code to create the library recipe# @uargs - User arguments, passed to the librecipe function## Returns : Nothing#sub DepRules{my ($self) = shift;my ( $libs, $librecipe, @uargs) = @_;## Sanity test: The name of the list must have been setup#my $target = $self->{DEPEND_target} || ::Error ("Internal error: SetShldTarget/SetLdTarget not called before DepRules");$self->SetTag( $self->{DEPEND_list}); # command tag$self->SetTerm();unless ( $self->{DepRulesHeaderDone}{$target} ){$self->{DepRulesHeaderDone}{$target} = 1;$self->Label( "Linker Dependencies", $target ); # label# library depends$self->Tag( "\\# DO NOT REMOVE - dependencies\\\\n" );$self->Tag( "\\#\\\\n" );}$self->LibList( $target, $libs, $librecipe, @uargs );}1;