#! /usr/local/bin/perl use strict; use warnings; no warnings 'redefine'; use Data::Dumper; use FileHandle; use ExtUtils::MakeMaker; use Module::Build; my %convert; our $INTEND; my $DEBUG = 0; my $MAKEFILE = 'Makefile.PL'; my $BUILD_PL = 'Build.PL'; my $LEN_INTEND = 4; *ExtUtils::MakeMaker::WriteMakefile = \&_convert; _run_makefile(); sub _run_makefile { -e $MAKEFILE ? do $MAKEFILE : die "No $MAKEFILE found\n"; } sub _convert { _get_conversion_table(); print "Converting $MAKEFILE -> $BUILD_PL\n"; _output(_dump(&_args_build)); } sub _get_conversion_table { local $/ = ''; local $_ = ; %convert = split; } sub _args_build { my %args_make = @_; my @args_build; for my $arg (keys %args_make) { next unless $convert{$arg}; # HASH CONVERSION if (ref $args_make{$arg} eq 'HASH') { _debug("$convert{$arg} => \{ "); my(%subargs, $subargs_count); my $subargs_size = %{$args_make{$arg}}; $subargs_size = chop($subargs_size); for my $subarg (keys %{$args_make{$arg}}) { _debug("$subarg => $args_make{$arg}{$subarg}"); _debug(', ') if (++$subargs_count < $subargs_size); $subargs{$subarg} = $args_make{$arg}{$subarg}; } _debug(" },\n"); my %tmphash; %{$tmphash{$convert{$arg}}} = %subargs; push @args_build, \%tmphash; } # ARRAY CONVERSION elsif (ref $args_make{$arg} eq 'ARRAY') { warn "Warning: $arg - array conversion not supported\n"; } # SCALAR CONVERSION # # One-dimensional hash values (scalars), # don't justify as SCALARS. elsif (ref $args_make{$arg} eq '') { _debug("$convert{$arg} => \'$args_make{$arg}\',\n"); my %tmphash; $tmphash{$convert{$arg}} = $args_make{$arg}; push @args_build, \%tmphash; } else { warn "Warning: $arg - unknown type of argument"; } } return \@args_build; } sub _dump { my($args) = @_; $Data::Dumper::Indent = 2; $Data::Dumper::Quotekeys = 0; $Data::Dumper::Sortkeys = 1; $Data::Dumper::Terse = 1; my $d = Data::Dumper->new([ @$args ]); return [ $d->Dump ]; } sub _output { local $INTEND = ' ' x $LEN_INTEND; local *F_BUILD; _open_build_pl(); _output_header(); &_output_args; _output_footer(); _close_build_pl(); } sub _open_build_pl { open F_BUILD, ">$BUILD_PL" or die "Couldn't open $BUILD_PL: $!"; select F_BUILD; } sub _close_build_pl { close F_BUILD or die "Couldn't close $BUILD_PL: $!"; select STDOUT; } sub _output_header { local $INTEND = $INTEND; chop($INTEND); print <<"EOT"; use Module::Build; my \$b = Module::Build->new $INTEND( EOT } sub _output_args { my($args) = @_; for my $arg (@$args) { if ($arg =~ m#=> \{#s) { $arg =~ s#\{ .*?\n (.*? \}) \s+ \}#$1#osx; my @arg = @{_split_arg($arg)}; my($whitespace) = $arg[0] =~ m#(\s+)\w+#o; my $shorten = length($whitespace); for my $arg (@arg) { chomp($arg); $arg =~ s/\s{$shorten}(.*)/$1/o; $arg .= ',' if ($arg =~ m#\d$# || $arg =~ m#\}#); print "$INTEND$arg\n"; } } else { $arg =~ s#\{ \s+ (.*) \s+ \}#$1#ox; chomp($arg); print "$INTEND$arg,\n"; } } } sub _output_footer { local $INTEND = $INTEND; chop($INTEND); print <<"EOT"; $INTEND create_makefile_pl => 'traditional', ); \$b->create_build_script; EOT } sub _split_arg { my($arg) = @_; my @arg; while ($arg =~ s#(.*?\n) (.*)#$2#osx) { push @arg, $1; } return \@arg; } sub _debug { print @_ if $DEBUG; } __DATA__ NAME module_name PREREQ_PM requires 1;