package Make::Target;
use strict;
use warnings;
## no critic (ValuesAndExpressions::ProhibitConstantPragma)
use constant DEBUG => $ENV{MAKE_DEBUG};
## use critic
our $VERSION = '2.011';
# Intermediate 'target' package
# There is an instance of this for each 'target' that apears on
# the left hand side of a rule i.e. for each thing that can be made.
sub new {
my ( $class, $name, $info ) = @_;
return bless {
NAME => $name, # name of thing
MAKEFILE => $info, # Makefile context
RULES => [],
RULE_TYPE => undef, # undef, :, ::
HAS_RECIPE => undef, # undef, boolean
Pass => 0, # Used to determine if 'done' this sweep
}, $class;
}
sub date {
my $self = shift;
my $info = $self->Info;
return $info->date( $self->Name );
}
sub phony {
my $self = shift;
return $self->Info->phony( $self->Name );
}
sub has_recipe {
my ($self) = @_;
return $self->{HAS_RECIPE} if defined $self->{HAS_RECIPE};
## no critic (BuiltinFunctions::RequireBlockGrep)
return $self->{HAS_RECIPE} = grep @{ $_->recipe }, @{ $self->{RULES} };
## use critic
}
sub rules {
my ($self) = @_;
if ( !$self->phony && !$self->has_recipe ) {
my $rule = $self->Info->patrule( $self->Name, $self->{RULE_TYPE} || ':' );
DEBUG and print STDERR "Implicit rule (", $self->Name, "): @{ $rule ? $rule->prereqs : ['none'] }\n";
$self->add_rule($rule) if $rule;
}
return $self->{RULES};
}
sub add_rule {
my ( $self, $rule ) = @_;
my $new_kind = $rule->kind;
my $kind = $self->{RULE_TYPE} ||= $new_kind;
die "Target '$self->{NAME}' had '$kind' but tried to add '$new_kind'"
if $kind ne $new_kind;
$self->{HAS_RECIPE} ||= undef; # reset if was no or unknown
return push @{ shift->{RULES} }, $rule;
}
sub Name {
return shift->{NAME};
}
sub Base {
my $name = shift->{NAME};
$name =~ s/\.[^.]+$//;
return $name;
}
sub Info {
return shift->{MAKEFILE};
}
sub done {
my $self = shift;
my $pass = $self->Info->pass;
return 1 if ( $self->{Pass} == $pass );
$self->{Pass} = $pass;
return 0;
}
# as part of "out of date" processing, if any child is remade, I need too
sub recurse {
my ( $self, $method ) = @_;
return if $self->done;
my $info = $self->Info;
my @results;
DEBUG and print STDERR "Build " . $self->Name, "\n";
foreach my $rule ( @{ $self->rules } ) {
## no critic (BuiltinFunctions::RequireBlockMap)
push @results, map $info->target($_)->recurse($method), @{ $rule->prereqs };
## use critic
push @results, $rule->$method($self);
}
return @results;
}
1;