Alien-ROOT

 view release on metacpan or  search on metacpan

inc/inc_Module-Build/Module/Build/Compat.pm  view on Meta::CPAN

         INSTALLARCHLIB  INSTALLSITEARCH     INSTALLVENDORARCH
         INSTALLPRIVLIB  INSTALLSITELIB      INSTALLVENDORLIB
         INSTALLBIN      INSTALLSITEBIN      INSTALLVENDORBIN
         INSTALLSCRIPT   INSTALLSITESCRIPT   INSTALLVENDORSCRIPT
         INSTALLMAN1DIR  INSTALLSITEMAN1DIR  INSTALLVENDORMAN1DIR
         INSTALLMAN3DIR  INSTALLSITEMAN3DIR  INSTALLVENDORMAN3DIR
       )
   ),

   # Some names they have in common
   map {$_, lc($_)} qw(DESTDIR PREFIX INSTALL_BASE UNINST),
  );

my %macro_to_build = %makefile_to_build;
# "LIB=foo make" is not the same as "perl Makefile.PL LIB=foo"
delete $macro_to_build{LIB};

sub _merge_prereq {
  my ($req, $breq) = @_;
  $req ||= {};
  $breq ||= {};

  # validate formats
  for my $p ( $req, $breq ) {
    for my $k (keys %$p) {
      next if $k eq 'perl';

      my $v_obj = eval { Module::Build::Version->new($p->{$k}) };
      if ( ! defined $v_obj ) {
          die "A prereq of the form '$p->{$k}' for '$k' is not supported by Module::Build::Compat ( use a simpler version like '0.05' or 'v1.4.25' )\n";
      }

      # It seems like a lot of people trip over "0.1.2" stuff, so we help them here...
      if ( $v_obj->is_qv ) {
        my $proper_ver = $v_obj->numify;
        warn "Dotted-decimal prereq '$p->{$k}' for '$k' is not portable - converting it to '$proper_ver'\n";
        $p->{$k} = $proper_ver;
      }
    }
  }
  # merge
  my $merge = { %$req };
  for my $k ( keys %$breq ) {
    my $v1 = $merge->{$k} || 0;
    my $v2 = $breq->{$k};
    $merge->{$k} = $v1 > $v2 ? $v1 : $v2;
  }
  return %$merge;
}


sub create_makefile_pl {
  my ($package, $type, $build, %args) = @_;

  die "Don't know how to build Makefile.PL of type '$type'"
    unless $type =~ /^(small|passthrough|traditional)$/;

  if ($type eq 'passthrough') {
    $build->log_warn(<<"HERE");

IMPORTANT NOTE: The '$type' style of Makefile.PL is deprecated and
may be removed in a future version of Module::Build in favor of the
'configure_requires' property.  See Module::Build::Compat
documentation for details.

HERE
  }

  my $fh;
  if ($args{fh}) {
    $fh = $args{fh};
  } else {
    $args{file} ||= 'Makefile.PL';
    local $build->{properties}{quiet} = 1;
    $build->delete_filetree($args{file});
    $fh = IO::File->new("> $args{file}") or die "Can't write $args{file}: $!";
  }

  print {$fh} "# Note: this file was auto-generated by ", __PACKAGE__, " version $VERSION\n";

  # Minimum perl version should be specified as "require 5.XXXXXX" in
  # Makefile.PL
  my $requires = $build->requires;
  if ( my $minimum_perl = $requires->{perl} ) {
    my $min_ver = Module::Build::Version->new($minimum_perl)->numify;
    print {$fh} "require $min_ver;\n";
  }

  # If a *bundled* custom subclass is being used, make sure we add its
  # directory to @INC.  Also, lib.pm always needs paths in Unix format.
  my $subclass_load = '';
  if (ref($build) ne "Module::Build") {
    my $subclass_dir = $package->subclass_dir($build);

    if (File::Spec->file_name_is_absolute($subclass_dir)) {
      my $base_dir = $build->base_dir;

      if ($build->dir_contains($base_dir, $subclass_dir)) {
	$subclass_dir = File::Spec->abs2rel($subclass_dir, $base_dir);
	$subclass_dir = $package->unixify_dir($subclass_dir);
        $subclass_load = "use lib '$subclass_dir';";
      }
      # Otherwise, leave it the empty string

    } else {
      $subclass_dir = $package->unixify_dir($subclass_dir);
      $subclass_load = "use lib '$subclass_dir';";
    }
  }

  if ($type eq 'small') {
    printf {$fh} <<'EOF', $subclass_load, ref($build), ref($build);
    use Module::Build::Compat 0.02;
    %s
    Module::Build::Compat->run_build_pl(args => \@ARGV);
    require %s;
    Module::Build::Compat->write_makefile(build_class => '%s');
EOF

  } elsif ($type eq 'passthrough') {
    printf {$fh} <<'EOF', $subclass_load, ref($build), ref($build);

inc/inc_Module-Build/Module/Build/Compat.pm  view on Meta::CPAN

  close $fh;

  my %merged = _merge_prereq( $prereqs->{requires}, $prereqs->{build_requires} );
  my @prereq;
  foreach (sort keys %merged) {
    next if $_ eq 'perl';
    push @prereq, "$_=>q[$merged{$_}]";
  }
  return unless @prereq;
  return "#     PREREQ_PM => { " . join(", ", @prereq) . " }\n\n";
}


sub write_makefile {
  my ($pack, %in) = @_;

  unless (exists $in{build_class}) {
    warn "Unknown 'build_class', defaulting to 'Module::Build'\n";
    $in{build_class} = 'Module::Build';
  }
  my $class = $in{build_class};
  $in{makefile} ||= $pack->_is_vms_mms ? 'Descrip.MMS' : 'Makefile';

  open  MAKE, "> $in{makefile}" or die "Cannot write $in{makefile}: $!";
  print MAKE $pack->fake_prereqs;
  print MAKE $pack->fake_makefile(%in);
  close MAKE;
}

sub _is_vms_mms {
  return Module::Build->is_vmsish && ($Config{make} =~ m/MM[SK]/i);
}

1;
__END__

=for :stopwords passthrough

=head1 NAME

Module::Build::Compat - Compatibility with ExtUtils::MakeMaker

=head1 SYNOPSIS

  # In a Build.PL :
  use Module::Build;
  my $build = Module::Build->new
    ( module_name => 'Foo::Bar',
      license     => 'perl',
      create_makefile_pl => 'traditional' );
  ...


=head1 DESCRIPTION

Because C<ExtUtils::MakeMaker> has been the standard way to distribute
modules for a long time, many tools (CPAN.pm, or your system
administrator) may expect to find a working F<Makefile.PL> in every
distribution they download from CPAN.  If you want to throw them a
bone, you can use C<Module::Build::Compat> to automatically generate a
F<Makefile.PL> for you, in one of several different styles.

C<Module::Build::Compat> also provides some code that helps out the
F<Makefile.PL> at runtime.


=head1 METHODS

=over 4

=item create_makefile_pl($style, $build)

Creates a F<Makefile.PL> in the current directory in one of several
styles, based on the supplied C<Module::Build> object C<$build>.  This is
typically controlled by passing the desired style as the
C<create_makefile_pl> parameter to C<Module::Build>'s C<new()> method;
the F<Makefile.PL> will then be automatically created during the
C<distdir> action.

The currently supported styles are:

=over 4

=item traditional

A F<Makefile.PL> will be created in the "traditional" style, i.e. it will
use C<ExtUtils::MakeMaker> and won't rely on C<Module::Build> at all.
In order to create the F<Makefile.PL>, we'll include the C<requires> and
C<build_requires> dependencies as the C<PREREQ_PM> parameter.

You don't want to use this style if during the C<perl Build.PL> stage
you ask the user questions, or do some auto-sensing about the user's
environment, or if you subclass C<Module::Build> to do some
customization, because the vanilla F<Makefile.PL> won't do any of that.

=item small

A small F<Makefile.PL> will be created that passes all functionality
through to the F<Build.PL> script in the same directory.  The user must
already have C<Module::Build> installed in order to use this, or else
they'll get a module-not-found error.

=item passthrough (DEPRECATED)

This is just like the C<small> option above, but if C<Module::Build> is
not already installed on the user's system, the script will offer to
use C<CPAN.pm> to download it and install it before continuing with
the build.

This option has been deprecated and may be removed in a future version
of Module::Build.  Modern CPAN.pm and CPANPLUS will recognize the
C<configure_requires> metadata property and install Module::Build before
running Build.PL if Module::Build is listed and Module::Build now
adds itself to configure_requires by default.

Perl 5.10.1 includes C<configure_requires> support.  In the future, when
C<configure_requires> support is deemed sufficiently widespread, the
C<passthrough> style will be removed.

=back

=item run_build_pl(args => \@ARGV)

This method runs the F<Build.PL> script, passing it any arguments the
user may have supplied to the C<perl Makefile.PL> command.  Because
C<ExtUtils::MakeMaker> and C<Module::Build> accept different arguments, this
method also performs some translation between the two.

C<run_build_pl()> accepts the following named parameters:

=over 4

=item args

The C<args> parameter specifies the parameters that would usually
appear on the command line of the C<perl Makefile.PL> command -
typically you'll just pass a reference to C<@ARGV>.

=item script

This is the filename of the script to run - it defaults to C<Build.PL>.

=back

=item write_makefile()

This method writes a 'dummy' F<Makefile> that will pass all commands
through to the corresponding C<Module::Build> actions.

C<write_makefile()> accepts the following named parameters:

=over 4

=item makefile

The name of the file to write - defaults to the string C<Makefile>.

=back

=back


=head1 SCENARIOS

So, some common scenarios are:

=over 4

=item 1.

Just include a F<Build.PL> script (without a F<Makefile.PL>
script), and give installation directions in a F<README> or F<INSTALL>
document explaining how to install the module.  In particular, explain
that the user must install C<Module::Build> before installing your
module.

Note that if you do this, you may make things easier for yourself, but
harder for people with older versions of CPAN or CPANPLUS on their



( run in 1.196 second using v1.01-cache-2.11-cpan-0068ddc7af1 )