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