package Makefile::AST::Rule::Implicit; use strict; use warnings; #use Smart::Comments; #use Smart::Comments '####'; use base 'Makefile::AST::Rule::Base'; use List::Util qw( first ); __PACKAGE__->mk_ro_accessors(qw{ targets }); sub as_str ($) { my $self = shift; my $order_part = ''; ## as_str: order_prereqs: $self->order_prereqs if (@{ $self->order_prereqs }) { $order_part = " | " . join(" ",@{ $self->order_prereqs }); } ### colon: $self->colon my $str = join(" ", @{ $self->targets }) . " " . $self->colon . " " . join(" ", @{ $self->normal_prereqs }) . "$order_part ; " . join("", map { "[$_]" } @{ $self->commands }); $str =~ s/\n+//g; $str =~ s/ +/ /g; $str; } # judge if $self is a match anything rule sub match_anything ($) { my $self = shift; first { $_ eq '%' } $self->targets; } sub is_terminal ($) { $_[0]->colon eq '::'; } sub match_target ($$) { my ($self, $target) = @_; for my $pat (@{ $self->targets }) { ### match_target: pattern: $pat ### match_target: target: $target my $match = Makefile::AST::StemMatch->new( { target => $target, pattern => $pat } ); return $match if $match; } return undef; } # apply the current rule to the given target sub apply ($$$@) { my ($self, $ast, $target, $opts) = @_; #### applying implicit rule to target: $target my $recursive; $recursive = $opts->{recursive} if $opts; #### $recursive my $match = $self->match_target($target); ## $match return undef if !$match; my (@other_targets, @normal_prereqs, @order_prereqs); for (@{ $self->targets }) { next if $_ eq $match->pattern; push @other_targets, $match->subs_stem($_); } for (@{ $self->normal_prereqs }) { push @normal_prereqs, $match->subs_stem($_); } for (@{ $self->order_prereqs }) { push @order_prereqs, $match->subs_stem($_); } for my $prereq (@order_prereqs, @normal_prereqs) { #### Test whether the prereq exists or ought to exist: $prereq #### target exists? : $ast->target_exists($prereq) ## file test: -e 'bar.hpp' #### Target ought to exists? : $ast->target_ought_to_exist($prereq) next if $ast->target_exists($prereq) or $ast->target_ought_to_exist($prereq); #### Failed to pass... # XXX mark intermedia files here next if $recursive and $ast->apply_implicit_rules($prereq); return undef; } return Makefile::AST::Rule->new( { target => $target, colon => $self->colon, stem => $match->stem, normal_prereqs => \@normal_prereqs, order_prereqs => \@order_prereqs, other_targets => \@other_targets, commands => $self->commands, } ); } 1;