—————# Build::Hopen::Gen::Make - generator for a generic make(1).
package
Build::Hopen::Gen::Make;
use
Build::Hopen::Base;
our
$VERSION
=
'0.000008'
;
# TRIAL
use
Hash::Ordered;
use
Class::Tiny {
targets
=>
sub
{ Hash::Ordered->new() }
};
use
Build::Hopen::Arrrgs;
# Docs {{{1
=head1 NAME
Build::Hopen::Gen::Make - hopen generator for simple Makefiles
=head1 SYNOPSIS
This generator makes a Makefile that does its best to run on cmd.exe or sh(1).
=head1 ATTRIBUTES
=head2 targets
A L<Hash::Ordered> of the targets, in the order encountered.
=head1 FUNCTIONS
=cut
# }}}1
=head2 visit_goal
Add a target corresponding to the name of the goal.
=cut
sub
visit_goal {
my
$self
=
shift
or croak
'Need an instance'
;
my
$goal
=
shift
or croak
'Need a goal'
;
$self
->targets->set(
$goal
->name,
$goal
);
}
#visit_goal()
#=head2 visit_node
#
#TODO
#
#=cut
#
#sub visit_node {
# my $self = shift or croak 'Need an instance';
# ...
#} #visit_node()
=head2 finalize
Write out the Makefile.
=cut
sub
finalize {
my
(
$self
,
%args
) = parameters(
'self'
, [
qw(phase dag data)
],
@_
);
hlog {
Finalizing
=> __PACKAGE__ ,
'- phase'
,
$args
{phase} };
return
unless
is_last_phase
$args
{phase};
# During the Gen phase, create the Makefile
open
my
$fh
,
'>'
,
$self
->dest_dir->file(
'Makefile'
) or
die
"Couldn't create Makefile"
;
$fh
<<EOT;
# Makefile generated by hopen (https://github.com/cxw42/hopen)
# at @{[scalar gmtime]} GMT
# From ``@{[$self->proj_dir->absolute]}'' into ``@{[$self->dest_dir->absolute]}''
EOT
my
$iter
=
$self
->targets->iterator;
# TODO make this more robust and flexible
while
(
my
(
$name
,
$goal
) =
$iter
->() ) {
hlog { __PACKAGE__,
'goal'
,
$name
} 2;
say
$fh
"### Goal $name ###"
;
unless
(
eval
{
scalar
@{
$goal
->outputs->{work}} }) {
warn
"No work for goal $name"
unless
$QUIET
;
next
;
}
my
@work
= @{
$goal
->outputs->{work}};
unshift
@work
, {
to
=> [
$name
],
from
=>
$work
[0]->{to},
how
=>
undef
};
# Make a fake record for the goal. TODO move this to visit_goal?
hlog {
'Work to do'
, Dumper(\
@work
) } 3;
foreach
my
$item
(
@work
) {
next
unless
@{
$item
->{from}};
# no prerequisites => assume it's a file
say
$fh
$item
->{to}->[0],
': '
,
join
(
' '
, @{
$item
->{from}});
say
$fh
(_expand(
$item
) =~ s/^/\t/gmr);
say
$fh
''
;
}
}
#foreach goal
close
$fh
;
}
#finalize()
=head2 default_toolset
Returns the package name of the default toolset for this generator,
which is C<Gnu> (i.e., L<Build::Hopen::T::Gnu>).
=cut
sub
default_toolset {
'Gnu'
}
=head1 INTERNALS
=head2 _expand
Produce the command line or lines associated with a work item. Used by
L</finalize>.
=cut
sub
_expand {
my
$item
=
shift
or croak
'Need a work item'
;
hlog { __PACKAGE__ .
'::expand()'
, Dumper(
$item
) } 2;
my
$out
=
$item
->{how} or
return
''
;
# no `how` => no output; not an error
$out
=~ s{
#first\b}{$item->{from}->[0] // ''}ge; # first input
$out
=~ s{
#all\b}{join(' ', @{$item->{from}})}ge; # all inputs
$out
=~ s{
#out\b}{$item->{to}->[0] // ''}ge;
return
$out
;
}
#_expand()
1;
__END__
# vi: set fdm=marker: #