File Coverage

blib/lib/FFI/Build/MM.pm
Criterion Covered Total %
statement 143 148 96.6
branch 24 36 66.6
condition 13 30 43.3
subroutine 32 32 100.0
pod 3 15 20.0
total 215 261 82.3


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