Rev 261 | Rev 4728 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
######################################################################### Copyright (C) 2008 ERG Limited, 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## 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 Prt{my ($self) = shift;::MakePrint ("@_");}sub PrtLn{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}sub SHLDDEPEND{my ($self) = shift;my ($target, $base, $name, $dir) = @_;$self->Label( "Include Shared Library Dependency Rules", $target );$dir = "LIBDIR" unless ( defined $dir );$self->Prt( "\$($dir)/${target}.dep:\tSHBASE=${base}\$($dir)/${target}.dep:\tSHNAME=${name}\$($dir)/${target}.dep:\t\$(GBE_$dir)\$($dir)/${target}.dep:\t\$(SCM_MAKEFILE)\$(SHLDDEPEND)ifneq \"\$(findstring \$(IFLAG),23)\" \"\"-include\t\$($dir)/${target}.dependif" );}sub LDDEPEND{my ($self) = shift;my ($target, $dir) = @_;$self->Label( "Include Library Dependency Rules", $target );$dir = "BINDIR" unless ( defined $dir );$self->Prt( "\$($dir)/${target}.dep:\t\$(GBE_$dir)\$($dir)/${target}.dep:\t\$(SCM_MAKEFILE)\$(LDDEPEND)ifeq \"\$(IFLAG)\" \"3\"-include\t\$($dir)/${target}.dependif" );}sub DepRules{my ($self) = shift;my ($target, $libs, $librecipe, @uargs) = @_;unless ( $self->{DepRulesHeaderDone}{$target} ){$self->{DepRulesHeaderDone}{$target} = 1;$self->Label( "Dependencies", $target ); # label# library depends$self->Tag( "\\# DO NOT REMOVE - dependencies\\\\n" );$self->Tag( "\\#\\\\n" );}$self->LibList( $target, $libs, $librecipe, @uargs );}1;