Alien-Build

 view release on metacpan or  search on metacpan

lib/Alien/Base/Wrapper.pm  view on Meta::CPAN

package Alien::Base::Wrapper;

use strict;
use warnings;
use 5.006;
use Config;
use Text::ParseWords qw( shellwords );

# NOTE: Although this module is now distributed with Alien-Build,
# it should have NO non-perl-core dependencies for all Perls
# 5.6.0-5.30.1 (as of this writing, and any Perl more recent).
# You should be able to extract this module from the rest of
# Alien-Build and use it by itself.  (There is a dzil plugin
# for this [AlienBase::Wrapper::Bundle]

# ABSTRACT: Compiler and linker wrapper for Alien
our $VERSION = '2.88'; # VERSION


sub _version_parts
{
  my($version) = @_;
  $version = '0' unless defined $version;

  # dotted-decimal style, e.g. 1.2.3 or v1.2.3: compare each part
  # separately, as integers.
  if($version =~ /^v?[0-9]+(\.[0-9]+){2,}$/)
  {
    $version =~ s/^v//;
    return [ split /\./, $version ];
  }

  # plain decimal style, e.g. 1.00 or 6.52: compare numerically as
  # a single number, so that (say) 6.6 is newer than 6.52.
  my($number) = $version =~ /^([0-9]+(?:\.[0-9]+)?)/;
  $number = 0 unless defined $number;
  return [ $number ];
}

sub _version_cmp
{
  my($v1, $v2) = @_;
  my $p1 = _version_parts($v1);
  my $p2 = _version_parts($v2);

  for my $i (0 .. (@$p1 > @$p2 ? $#$p1 : $#$p2))
  {
    my $n1 = defined $p1->[$i] ? $p1->[$i] : 0;
    my $n2 = defined $p2->[$i] ? $p2->[$i] : 0;
    my $cmp = $n1 <=> $n2;
    return $cmp if $cmp;
  }

  return 0;
}

# returns whichever of the two version numbers is newer (either may
# be undef, in which case the other, possibly also undef, is returned).
sub _version_max
{
  my($v1, $v2) = @_;
  return $v2 unless defined $v1;
  return $v1 unless defined $v2;
  return _version_cmp($v1, $v2) >= 0 ? $v1 : $v2;
}

sub _join
{
  join ' ',
    map {
      my $x = $_;
      $x =~ s/(\s)/\\$1/g;
      $x;
    } @_;
}

sub new
{
  my($class, @aliens) = @_;

  my $export = 1;
  my $writemakefile = 0;

  my @cflags_I;
  my @cflags_other;
  my @ldflags_L;
  my @ldflags_l;
  my @ldflags_other;
  my %requires = (
    'ExtUtils::MakeMaker'  => '6.52',
    'Alien::Base::Wrapper' => '1.97',
  );

lib/Alien/Base/Wrapper.pm  view on Meta::CPAN


=head2 ld

 % perl -MAlien::Base::Wrapper=Alien::Foo -e ld -- ldflags

Invoke the linker with the appropriate flags from C<Alien::Foo> and what
is provided on the command line.

=head2 mm_args

 my %args = $abw->mm_args;
 my %args = Alien::Base::Wrapper->mm_args;

Returns arguments that you can pass into C<WriteMakefile> to compile/link against
the specified Aliens.  Note that this does not set  C<CONFIGURE_REQUIRES>.  You
probably want to use C<mm_args2> below instead for that reason.

=head2 mm_args2

 my %args = $abw->mm_args2(%args);
 my %args = Alien::Base::Wrapper->mm_args2(%args);

Returns arguments that you can pass into C<WriteMakefile> to compile/link against.  It works
a little differently from C<mm_args> above in that you can pass in arguments.  It also adds
the appropriate C<CONFIGURE_REQUIRES> for you so you do not have to do that explicitly.

[version 2.87]

If you pass in your own C<CONFIGURE_REQUIRES> with a version for a module that this class
also requires (currently L<ExtUtils::MakeMaker> and C<Alien::Base::Wrapper> itself, plus any
Alien that you specify a minimum version for), then the newer of the two version numbers
will be used, so that neither requirement is weakened.  Version numbers may be given in
either decimal (C<1.23>) or dotted-decimal (C<1.2.3>) form.

=head2 checklib_args2

 my %args = $abw->checklib_args2(%args);
 my %args = Alien::Base::Wrapper->checklib_args2(%args);

Returns arguments that you can pass into C<assert_lib>, C<check_lib> or C<check_lib_or_exit> from
L<Devel::CheckLib> in order to compile/link against the Aliens specified.  It works a little like
C<mm_args2> above, except that instead of being applied to a hash of L<ExtUtils::MakeMaker>
arguments, it is applied to a hash of L<Devel::CheckLib> arguments.

 use Devel::CheckLib qw( check_lib_or_exit );
 use Alien::Base::Wrapper ();

 check_lib_or_exit(
   Alien::Base::Wrapper->new('Alien::Foo')->checklib_args2(
     lib    => 'foo',
     header => 'foo.h',
   ),
 );

The Alien's include paths are merged into C<incpath>, its other compiler flags (such as
C<-D> defines) are merged into C<ccflags>, its library paths are merged into C<libpath>, and
its libraries and other linker flags are merged into C<ldflags>, so that the C<lib> and
C<header> that you are checking for can be found using the environment provided by the Alien.

Since L<Devel::CheckLib> also allows you to specify C<INC> and C<LIBS> in the
L<ExtUtils::MakeMaker> style, and merging those styles with the Alien flags is ambiguous,
C<checklib_args2> will throw an exception if you attempt to specify either of those.  Use
C<incpath> / C<ccflags> and C<libpath> / C<ldflags> instead.

=head2 mb_args

 my %args = $abw->mb_args;
 my %args = Alien::Base::Wrapper->mb_args;

Returns arguments that you can pass into the constructor to L<Module::Build>.

=head2 WriteMakefile

 use Alien::Base::Wrapper qw( WriteMakefile );
 WriteMakefile(%args, alien_requires => \%aliens);
 WriteMakefile(%args, alien_requires => \@aliens);

This is a thin wrapper around C<WriteMakefile> from L<ExtUtils::MakeMaker>, which adds the
given aliens to the configure requirements and sets the appropriate compiler and linker
flags.

If the aliens are specified as a hash reference, then the keys are the module names and the
values are the versions.  For a list it is just the name of the aliens.

For the list form you can specify a version by appending C<=version> to the name of the
Aliens, that is:

 WriteMakefile(
   alien_requires => [ 'Alien::libfoo=1.23', 'Alien::libbar=4.56' ],
 );

The list form is recommended if the ordering of the aliens matter.  The aliens are sorted in
the hash form to make it consistent, but it may not be the order that you want.

=head1 ENVIRONMENT

Alien::Base::Wrapper responds to these environment variables:

=over 4

=item ALIEN_BASE_WRAPPER_QUIET

If set to true, do not print the command before executing

=back

=head1 SEE ALSO

L<Alien::Base>, L<Alien::Base>

=head1 AUTHOR

Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>

Contributors:

Diab Jerius (DJERIUS)

Roy Storey (KIWIROY)

Ilya Pavlov



( run in 0.612 second using v1.01-cache-2.11-cpan-b554fb43c41 )