File Coverage

blib/lib/FFI/Build/MM.pm
Criterion Covered Total %
statement 146 151 96.6
branch 24 36 66.6
condition 13 30 43.3
subroutine 33 33 100.0
pod 3 15 20.0
total 219 265 82.6


line stmt bran cond sub pod time code
1             package FFI::Build::MM;
2              
3 2     2   78384 use strict;
  2         11  
  2         51  
4 2     2   8 use warnings;
  2         4  
  2         41  
5 2     2   36 use 5.008001;
  2         6  
6 2     2   8 use Carp ();
  2         2  
  2         24  
7 2     2   677 use FFI::Build;
  2         6  
  2         56  
8 2     2   1214 use JSON::PP ();
  2         23606  
  2         51  
9 2     2   15 use File::Glob ();
  2         4  
  2         25  
10 2     2   8 use File::Basename ();
  2         3  
  2         22  
11 2     2   9 use File::Path ();
  2         4  
  2         21  
12 2     2   926 use File::Copy ();
  2         3926  
  2         53  
13 2     2   1318 use ExtUtils::MakeMaker 7.24;
  2         180597  
  2         2648  
14              
15             # ABSTRACT: FFI::Build installer code for ExtUtils::MakeMaker
16             our $VERSION = '0.11'; # VERSION
17              
18              
19             sub new
20             {
21 5     5 1 8616 my($class) = @_;
22            
23 5         23 my $self = bless {}, $class;
24 5         31 $self->load_prop;
25            
26 5         18 $self;
27             }
28              
29              
30             sub mm_args
31             {
32 2     2 1 529 my($self, %args) = @_;
33            
34 2 50       8 if($args{DISTNAME})
35             {
36 2   33     15 $self->{prop}->{distname} ||= $args{DISTNAME};
37 2   33     9 $self->{prop}->{share} ||= "blib/lib/auto/share/dist/@{[ $self->distname ]}";
  2         7  
38 2   33     11 $self->{prop}->{arch} ||= "blib/arch/auto/@{[ join '/', split /-/, $self->distname ]}";
  2         7  
39 2         6 $self->save_prop;
40             }
41             else
42             {
43 0         0 Carp::croak "DISTNAME is required";
44             }
45              
46              
47 2 100       10 if(my $build = $self->build)
48             {
49 1         4 foreach my $alien (@{ $build->alien })
  1         5  
50             {
51 0 0       0 next if ref $alien;
52 0   0     0 $args{BUILD_REQUIRES}->{$alien} ||= 0;
53             }
54             }
55            
56 2 100       9 if(my $test = $self->test)
57             {
58 1         2 foreach my $alien (@{ $test->alien })
  1         4  
59             {
60 0 0       0 next if ref $alien;
61 0   0     0 $args{TEST_REQUIRES}->{$alien} ||= 0;
62             }
63             }
64            
65 2         14 %args;
66             }
67              
68 9     9 0 69 sub distname { shift->{prop}->{distname} }
69              
70             sub sharedir
71             {
72 7     7 0 747 my($self, $new) = @_;
73            
74 7 100       18 if(defined $new)
75             {
76 1         4 $self->{prop}->{share} = $new;
77 1         11 $self->save_prop;
78             }
79            
80 7         40 $self->{prop}->{share};
81             }
82              
83             sub archdir
84             {
85 7     7 0 19 my($self, $new) = @_;
86            
87 7 100       20 if(defined $new)
88             {
89 1         3 $self->{prop}->{arch} = $new;
90 1         4 $self->save_prop;
91             }
92            
93 7         605 $self->{prop}->{arch};
94             }
95              
96             sub load_build
97             {
98 10     10 0 1788 my($self, $dir, $name, $install) = @_;
99 10 100       167 return unless -d $dir;
100 8         512 my($fbx) = File::Glob::bsd_glob("./$dir/*.fbx");
101            
102 8         26 my $options;
103 8         93 my $platform = FFI::Build::Platform->default;
104            
105 8 100       22 if($fbx)
106             {
107 1         63 $name = File::Basename::basename($fbx);
108 1         5 $name =~ s/\.fbx$//;
109 1         2 $options = do {
110             package FFI::Build::MM::FBX;
111 1         2 our $DIR = $dir;
112 1         3 our $PLATFORM = $platform;
113 1         366 do $fbx;
114             };
115             }
116             else
117             {
118 7   66     33 $name ||= $self->distname;
119 7         58 $options = {
120             source => ["$dir/*.c", "$dir/*.cxx", "$dir/*.cpp"],
121             };
122             }
123            
124 8   33     67 $options->{platform} ||= $platform;
125 8 100 66     66 $options->{dir} ||= ref $install ? $install->($options) : $install;
126 8 50       28 $options->{verbose} = 1 unless defined $options->{verbose};
127 8         62 FFI::Build->new($name, %$options);
128             }
129              
130             sub build
131             {
132 4     4 0 18 my($self) = @_;
133 4   66     75 $self->{build} ||= $self->load_build('ffi', undef, $self->sharedir . "/lib");
134             }
135              
136             sub test
137             {
138 4     4 0 18 my($self) = @_;
139             $self->{test} ||= $self->load_build('t/ffi', 'test', sub {
140 3     3   9 my($opt) = @_;
141 3   50     19 my $buildname = $opt->{buildname} || '_build';
142 3         12 "t/ffi/$buildname";
143 4   66     82 });
144             }
145              
146             sub save_prop
147             {
148 1     1 0 3 my($self) = @_;
149 1         100 open my $fh, '>', 'fbx.json';
150 1         25 print $fh JSON::PP::encode_json($self->{prop});
151 1         348 close $fh;
152             }
153              
154             sub load_prop
155             {
156 5     5 0 11 my($self) = @_;
157 5 100       98 unless(-f 'fbx.json')
158             {
159 2         15 $self->{prop} = {};
160 2         4 return;
161             }
162 3         107 open my $fh, '<', 'fbx.json';
163 3         9 $self->{prop} = JSON::PP::decode_json(do { local $/; <$fh> });
  3         14  
  3         121  
164 3         2986 close $fh;
165             }
166              
167             sub clean
168             {
169 1     1 0 7 my($self) = @_;
170 1         12 foreach my $stage (qw( build test ))
171             {
172 2         50 my $build = $self->$stage;
173 2 50       27 $build->clean if $build;
174             }
175 1 50       60 unlink 'fbx.json' if -f 'fbx.json';
176             }
177              
178              
179             sub mm_postamble
180             {
181 1     1 1 3 my($self) = @_;
182            
183 1         2 my $postamble = '';
184              
185             # make fbx_realclean ; make clean
186 1         3 $postamble .= "realclean :: fbx_clean\n" .
187             "\n" .
188             "fbx_clean:\n" .
189             "\t\$(FULLPERL) -MFFI::Build::MM=cmd -e fbx_clean\n\n";
190            
191             # make fbx_build; make
192 1         3 $postamble .= "pure_all :: fbx_build\n" .
193             "\n" .
194             "fbx_build:\n" .
195             "\t\$(FULLPERL) -MFFI::Build::MM=cmd -e fbx_build\n\n";
196              
197             # make fbx_test; make test
198 1         2 $postamble .= "subdirs-test_dynamic subdirs-test_static subdirs-test :: fbx_test\n" .
199             "\n" .
200             "fbx_test:\n" .
201             "\t\$(FULLPERL) -MFFI::Build::MM=cmd -e fbx_test\n\n";
202            
203 1         2 $postamble;
204             }
205              
206             sub action_build
207             {
208 1     1 0 3 my($self) = @_;
209 1         4 my $build = $self->build;
210 1 50       4 if($build)
211             {
212 1         5 my $lib = $build->build;
213 1 50       24 if($self->archdir)
214             {
215 1         8 File::Path::mkpath($self->archdir, 0, 0755);
216 1         6 my $archfile = File::Spec->catfile($self->archdir, File::Basename::basename($self->archdir) . ".txt");
217 1         74 open my $fh, '>', $archfile;
218 1         16 my $lib_path = $lib->path;
219 1         24 $lib_path =~ s/^blib\/lib\///;
220 1         9 print $fh "FFI::Build\@$lib_path\n";
221 1         26 close $fh;
222             }
223             }
224 1         31 return;
225             }
226              
227             sub action_test
228             {
229 1     1 0 4 my($self) = @_;
230 1         11 my $build = $self->test;
231 1 50       10 $build->build if $build;
232             }
233              
234             sub action_clean
235             {
236 1     1 0 7 my($self) = @_;
237 1         10 my $build = $self->clean;
238 1         8 ();
239             }
240              
241             sub import
242             {
243 3     3   3164 my(undef, @args) = @_;
244 3         57 foreach my $arg (@args)
245             {
246 1 50       53 if($arg eq 'cmd')
247             {
248             package main;
249            
250             my $mm = sub {
251 3     3   10 my($action) = @_;
252 3         55 my $build = FFI::Build::MM->new;
253 3         22 $build->$action;
254 1         6 };
255              
256 2     2   19 no warnings 'once';
  2         4  
  2         303  
257            
258             *fbx_build = sub {
259 1     1   5139 $mm->('action_build');
260 1         6 };
261            
262             *fbx_test = sub {
263 1     1   51779 $mm->('action_test');
264 1         5 };
265            
266             *fbx_clean = sub {
267 1     1   7305 $mm->('action_clean');
268 1         6 };
269             }
270             }
271             }
272              
273             1;
274              
275             __END__