File Coverage

blib/lib/Alien/Build/Plugin/Build/Autoconf.pm
Criterion Covered Total %
statement 60 76 78.9
branch 8 18 44.4
condition n/a
subroutine 11 12 91.6
pod 1 1 100.0
total 80 107 74.7


line stmt bran cond sub pod time code
1             package Alien::Build::Plugin::Build::Autoconf;
2              
3 4     4   2271 use strict;
  4         9  
  4         123  
4 4     4   21 use warnings;
  4         10  
  4         129  
5 4     4   79 use 5.008004;
  4         13  
6 4     4   384 use Alien::Build::Plugin;
  4         11  
  4         33  
7 4     4   30 use constant _win => $^O eq 'MSWin32';
  4         8  
  4         313  
8 4     4   31 use Path::Tiny ();
  4         13  
  4         78  
9 4     4   35 use File::Temp ();
  4         7  
  4         4091  
10              
11             # ABSTRACT: Autoconf plugin for Alien::Build
12             our $VERSION = '2.47'; # VERSION
13              
14              
15             has with_pic => 1;
16             has ffi => 0;
17             has msys_version => undef;
18             has config_site => sub {
19              
20             my $config_site = "# file automatically generated by @{[ __FILE__ ]}\n";
21             $config_site .= ". $ENV{CONFIG_SITE}\n" if defined $ENV{CONFIG_SITE};
22             $config_site .= ". $ENV{ALIEN_BUILD_SITE_CONFIG}\n" if defined $ENV{ALIEN_BUILD_SITE_CONFIG};
23              
24             # on some platforms autofools sorry I mean autotools likes to install into
25             # exec_prefix/lib64 or even worse exec_prefix/lib/64 but that messes everything
26             # else up so we try to nip that in the bud.
27             $config_site .= "libdir='\${prefix}/lib'\n";
28             $config_site;
29             };
30              
31             sub init
32             {
33 7     7 1 27 my($self, $meta) = @_;
34              
35 7 50       23 $meta->apply_plugin('Build::MSYS',
36             (defined $self->msys_version ? (msys_version => $self->msys_version) : ()),
37             );
38              
39 7         21 $meta->prop->{destdir} = 1;
40 7         17 $meta->prop->{autoconf} = 1;
41              
42 7         20 my $intr = $meta->interpolator;
43              
44             my $set_autoconf_prefix = sub {
45 2     2   7 my($build) = @_;
46 2         14 my $prefix = $build->install_prop->{prefix};
47 2 50       9 die "Prefix is not set. Did you forget to run 'make alien_prefix'?"
48             unless $prefix;
49 2         4 if(_win)
50             {
51             $prefix = Path::Tiny->new($prefix)->stringify;
52             $prefix =~ s!^([a-z]):!/$1!i if _win;
53             }
54 2         10 $build->install_prop->{autoconf_prefix} = $prefix;
55 7         31 };
56              
57 7         27 $meta->before_hook(
58             build_ffi => $set_autoconf_prefix,
59             );
60              
61             # FFI mode undocumented for now...
62              
63 7 50       28 if($self->ffi)
64             {
65 0         0 $meta->add_requires('configure', 'Alien::Build::Plugin::Build::Autoconf' => '0.41');
66 0         0 $meta->default_hook(
67             build_ffi => [
68             '%{configure} --enable-shared --disable-static --libdir=%{.install.autoconf_prefix}/dynamic',
69             '%{make}',
70             '%{make} install',
71             ]
72             );
73              
74 0 0       0 if($^O eq 'MSWin32')
75             {
76             # for whatever reason autohell puts the .dll files in bin, even if you
77             # point --bindir somewhere else.
78             $meta->after_hook(
79             build_ffi => sub {
80 0     0   0 my($build) = @_;
81 0         0 my $prefix = $build->install_prop->{autoconf_prefix};
82 0         0 my $bin = Path::Tiny->new($ENV{DESTDIR})->child($prefix)->child('bin');
83 0         0 my $lib = Path::Tiny->new($ENV{DESTDIR})->child($prefix)->child('dynamic');
84 0 0       0 if(-d $bin)
85             {
86 0         0 foreach my $from (grep { $_->basename =~ /.dll$/i } $bin->children)
  0         0  
87             {
88 0         0 $lib->mkpath;
89 0         0 my $to = $lib->child($from->basename);
90 0         0 $build->log("copy $from => $to");
91 0         0 $from->copy($to);
92             }
93             }
94             }
95 0         0 );
96             }
97             }
98              
99             $meta->around_hook(
100             build => sub {
101 1     1   12 my $orig = shift;
102 1         7 my $build = shift;
103              
104 1         6 $set_autoconf_prefix->($build);
105 1         8 my $prefix = $build->install_prop->{autoconf_prefix};
106 1 50       4 die "Prefix is not set. Did you forget to run 'make alien_prefix'?"
107             unless $prefix;
108              
109 1         5 local $ENV{CONFIG_SITE} = do {
110 1         12 my $site_config = Path::Tiny->new(File::Temp::tempdir( CLEANUP => 1 ))->child('config.site');
111 1         479 $site_config->spew($self->config_site);
112 1         562 "$site_config";
113             };
114              
115             $intr->replace_helper(
116             configure => sub {
117 1         2 my $configure;
118              
119 1 50       5 if($build->meta_prop->{out_of_source})
120             {
121 1         3 my $extract = $build->install_prop->{extract};
122 1         4 $configure = _win ? "sh $extract/configure" : "$extract/configure";
123             }
124             else
125             {
126 0         0 $configure = _win ? 'sh ./configure' : './configure';
127             }
128 1         5 $configure .= ' --prefix=' . $prefix;
129 1 50       13 $configure .= ' --with-pic' if $self->with_pic;
130 1         6 $configure;
131             }
132 1         84 );
133              
134 1         7 my $ret = $orig->($build, @_);
135              
136 1         1138 if(_win)
137             {
138             my $real_prefix = Path::Tiny->new($build->install_prop->{prefix});
139             my @pkgconf_dirs;
140             push @pkgconf_dirs, Path::Tiny->new($ENV{DESTDIR})->child($prefix)->child("$_/pkgconfig") for qw(lib share);
141              
142             # for any pkg-config style .pc files that are dropped, we need
143             # to convert the MSYS /C/Foo style paths to C:/Foo
144             for my $pkgconf_dir (@pkgconf_dirs) {
145             if(-d $pkgconf_dir)
146             {
147             foreach my $pc_file ($pkgconf_dir->children)
148             {
149             $pc_file->edit(sub {s/\Q$prefix\E/$real_prefix->stringify/eg;});
150             }
151             }
152             }
153             }
154              
155 1         13 $ret;
156             },
157 7         42 );
158              
159              
160             $intr->add_helper(
161             configure => sub {
162 3     3   7 my $configure = _win ? 'sh configure' : './configure';
163 3 100       13 $configure .= ' --with-pic' if $self->with_pic;
164 3         13 $configure;
165             },
166 7         61 );
167              
168 7         32 $meta->default_hook(
169             build => [
170             '%{configure} --disable-shared',
171             '%{make}',
172             '%{make} install',
173             ]
174             );
175              
176 7         17 $self;
177             }
178              
179             1;
180              
181             __END__