File Coverage

blib/lib/FFI/Build/File/VMod.pm
Criterion Covered Total %
statement 69 98 70.4
branch 9 30 30.0
condition 1 6 16.6
subroutine 16 17 94.1
pod 3 3 100.0
total 98 154 63.6


line stmt bran cond sub pod time code
1 1     1   338770 use warnings;
  1         2  
  1         80  
2 1     1   25 use 5.020;
  1         5  
3 1     1   7 use experimental qw( signatures );
  1         2  
  1         9  
4 1     1   1197 use stable qw( postderef );
  1         659  
  1         6  
5 1     1   105 use true;
  1         2  
  1         10  
6              
7             package FFI::Build::File::VMod 0.03 {
8              
9             # ABSTRACT: Class to track V source in FFI::Build
10              
11 1     1   2806 use parent qw( FFI::Build::File::Base );
  1         2  
  1         7  
12 1     1   90 use constant default_suffix => '.mod';
  1         3  
  1         87  
13 1     1   11 use constant default_encoding => ':utf8';
  1         3  
  1         98  
14 1     1   688 use File::Which qw( which );
  1         1802  
  1         82  
15 1     1   695 use PerlX::Maybe qw( maybe );
  1         4020  
  1         5  
16 1     1   1181 use Path::Tiny 0.130 ();
  1         21471  
  1         46  
17 1     1   762 use File::chdir;
  1         2900  
  1         1782  
18              
19              
20             sub accept_suffix {
21 3     3 1 8940 (qr/\/v\.mod\z/)
22             }
23              
24 1     1 1 540 sub build_all ($self, $) {
  1         2  
  1         2  
25 1         4 $self->build_item;
26             }
27              
28 1     1 1 3 sub build_item ($self) {
  1         2  
  1         3  
29              
30 1         8 my $vmod = Path::Tiny->new($self->path);
31              
32 1         68 my $platform;
33             my $buildname;
34 1         0 my $lib;
35              
36 1 100       9 my($name) = map { /name:\s*'(.*)'/ ? ($1) : () } $vmod->lines_utf8;
  4         3501  
37 1 50       6 die "unable to find name in $vmod" unless defined $name;
38              
39 1 50       15 if($self->build) {
40 1         9 $platform = $self->build->platform;
41 1         9 $buildname = $self->build->buildname;
42 1         10 $lib = $self->build->file;
43             } else {
44 0         0 $platform = FFI::Build::Platform->new;
45 0         0 $buildname = "_build";
46              
47 0         0 $lib = FFI::Build::File::Library->new(
48             $vmod->sibling("$name" . scalar($platform->library_suffix))->stringify,
49             platform => $self->platform,
50             );
51             }
52              
53 1 50       8 if($self->_have_v_compiler) {
54              
55 0 0 0     0 return $lib if -f $lib->path && !$lib->needs_rebuild($self->_deps($vmod->parent));
56              
57 0         0 my $lib_path = Path::Tiny->new($lib->path)->relative($vmod->parent);
58 0         0 say "+cd @{[ $vmod->parent ]}";
  0         0  
59 0         0 local $CWD = $vmod->parent;
60 0         0 say "+mkdir -p @{[ $lib_path->parent->mkdir ]}";
  0         0  
61 0         0 $lib_path->parent->mkdir;
62 0         0 $platform->run('v', '-prod', '-shared', -o => "$lib_path", '.');
63 0 0       0 die "command failed" if $?;
64 0 0       0 die "no shared library" unless -f $lib_path;
65 0         0 say "+cd -";
66              
67             } else {
68              
69 1         7 my $c_source = $vmod->sibling("$name.c");
70 1 50       161 die "module requires v compiler" unless -f $c_source;
71 1 50 33     41 return $lib if -f $lib->path && !$lib->needs_rebuild($c_source->stringify);
72 1         91 require FFI::Build;
73              
74 1         3 my @args;
75 1 50       18 if($self->build) {
76 1         9 foreach my $key (qw( alien buildname cflags export file libs verbose )) {
77 7         52 push @args, $key => $self->build->$key;
78             }
79             } else {
80 0         0 push @args,
81             buildname => $buildname,
82             file => $lib,
83             ;
84             }
85              
86 1         13 warn "c_source = $c_source";
87              
88 1         100 my $bx = FFI::Build->new(
89             $name,
90             source => ["$c_source"],
91             platform => $platform,
92             dir => $vmod->parent->stringify,
93             @args,
94             );
95              
96 1         257 return $bx->build;
97              
98             }
99              
100 0         0 return $lib;
101              
102             }
103              
104 0         0 sub _deps ($self, $path)
105 0     0   0 {
  0         0  
  0         0  
106 0         0 my @ret;
107 0         0 foreach my $path ($path->children) {
108 0 0       0 next if -l $path; # skip symlinks to avoid recursion
109 0 0       0 push @ret, $self->_deps($path) if -d $path;
110 0 0       0 push @ret, $path->stringify if $path->basename =~ /^(.*\.(v|c|h)|v\.mod)\z/;
111             }
112 0         0 return @ret;
113             }
114              
115 1     1   3 sub _have_v_compiler ($self) {
  1         2  
  1         2  
116 1 50       7 return 0 if $ENV{FFI_PLATYPUS_LANG_VMOD_SKIP_V};
117 0 0         return 1 if which 'v';
118 0           return 0;
119             }
120              
121             }
122              
123             __END__