File Coverage

blib/lib/Module/Build/FFI/Pascal.pm
Criterion Covered Total %
statement 24 101 23.7
branch 0 38 0.0
condition 0 6 0.0
subroutine 8 10 80.0
pod 2 2 100.0
total 34 157 21.6


line stmt bran cond sub pod time code
1             package Module::Build::FFI::Pascal;
2              
3 2     2   253483 use strict;
  2         10  
  2         81  
4 2     2   12 use warnings;
  2         4  
  2         49  
5 2     2   29 use Config;
  2         4  
  2         89  
6 2     2   10 use File::Glob qw( bsd_glob );
  2         4  
  2         240  
7 2     2   1078 use File::Which qw( which );
  2         2444  
  2         122  
8 2     2   1104 use File::chdir;
  2         7321  
  2         266  
9 2     2   544 use File::Copy qw( move );
  2         2474  
  2         143  
10 2     2   23 use base qw( Module::Build::FFI );
  2         4  
  2         1593  
11              
12             # ABSTRACT: (Deprecated) Build Perl extensions in Free Pascal with FFI
13             our $VERSION = '0.54'; # VERSION
14              
15              
16             __PACKAGE__->add_property( ffi_pascal_extra_compiler_flags =>
17             default => [],
18             );
19              
20             __PACKAGE__->add_property( ffi_pascal_extra_linker_flags =>
21             default => [],
22             );
23              
24             __PACKAGE__->add_property( ffi_pascal_lib =>
25             default => ['ffi.pas','test.pas'],
26             );
27              
28              
29             sub ffi_have_compiler
30             {
31 0     0 1   my($self) = @_;
32              
33 0           my $fpc = which('fpc');
34 0           my $ppumove = which('ppumove');
35              
36 0   0       return (!!$fpc) && (!!$ppumove);
37             }
38              
39              
40             sub ffi_build_dynamic_lib
41             {
42 0     0 1   my($self, $src_dir, $name, $target_dir) = @_;
43              
44 0 0         die "multiple directories not supported by ", __PACKAGE__
45             if @$src_dir > 1;
46              
47 0           $src_dir = $src_dir->[0];
48 0           my $lib;
49 0           my %lib = map { $_ => 1 } @{ $self->ffi_pascal_lib };
  0            
  0            
50              
51 0           do {
52 0           local $CWD = $src_dir;
53 0           print "cd $CWD\n";
54              
55 0 0         $target_dir = $src_dir unless defined $target_dir;
56 0           my @sources = bsd_glob("*.pas");
57              
58 0 0         return unless @sources;
59              
60 0           my $fpc = which('fpc');
61 0           my $ppumove = which('ppumove');
62              
63 0           my @compiler_flags;
64             my @linker_flags;
65              
66             # TODO: OSX not sure if checking ptrsize will actually work
67             # % arch -arch i386 /usr/bin/perl -V:ptrsize
68             # ptrsize='8';
69             # but the system perl is a universal binary
70             # or maybe I am using arch wrong. who knows.
71             # TODO: OSX make a universal binary if possible?
72             # Fortunately most people are probably using OS X 64 bit intel by now anyway
73 0 0 0       push @compiler_flags, '-Px86_64' if $^O eq 'darwin' && $Config{ptrsize} == 8;
74              
75 0           my @ppu;
76              
77 0           foreach my $src (@sources)
78             {
79 0 0         if($lib{$src})
80             {
81 0 0         die "Two or more libraries in $CWD" if defined $lib;
82 0           $lib = $src;
83 0           next;
84             }
85              
86             my @cmd = (
87             $fpc,
88             @compiler_flags,
89 0           @{ $self->ffi_pascal_extra_compiler_flags },
  0            
90             $src
91             );
92              
93 0           print "@cmd\n";
94 0           system @cmd;
95 0 0         exit 2 if $?;
96              
97 0           my $ppu = $src;
98 0           $ppu =~ s{\.pas$}{.ppu};
99              
100 0 0         unless(-r $ppu)
101             {
102 0           print STDERR "unable to find $ppu after compile\n";
103 0           exit 2;
104             }
105              
106 0           push @ppu, $ppu;
107             }
108              
109 0 0         if($lib)
110             {
111             my @cmd = (
112             $fpc,
113             @compiler_flags,
114 0           @{ $self->ffi_pascal_extra_compiler_flags },
  0            
115             $lib,
116             );
117 0           print "@cmd\n";
118 0           system @cmd;
119 0 0         exit 2 if $?;
120 0           my @so = map { bsd_glob("*.$_") } Module::Build::FFI->ffi_dlext;
  0            
121 0 0         die "multiple dylibs in $CWD" if @so > 1;
122 0 0         die "no dylib in $CWD" if @so < 1;
123             }
124             else
125             {
126 0           my @cmd;
127              
128 0 0         if($^O eq 'darwin')
129             {
130 0           my @obj = map { s/\.ppu/\.o/; $_ } @ppu;
  0            
  0            
131             @cmd = (
132             'ld',
133 0 0         $Config{dlext} eq 'bundle' ? '-bundle' : '-dylib',
134             '-o' => "libmbFFIPlatypusPascal.$Config{dlext}",
135             @obj,
136             );
137             }
138             else
139             {
140             @cmd = (
141             $ppumove,
142             @linker_flags,
143 0           @{ $self->ffi_pascal_extra_linker_flags },
  0            
144             -o => 'mbFFIPlatypusPascal',
145             -e => 'ppl',
146             @ppu,
147             );
148             }
149 0           print "@cmd\n";
150 0           system @cmd;
151 0 0         exit 2 if $?;
152             }
153              
154             };
155              
156 0           print "cd $CWD\n";
157              
158 0           my($from) = map { bsd_glob("$src_dir/*.$_") } Module::Build::FFI->ffi_dlext;
  0            
159              
160 0 0         unless(defined $from)
161             {
162 0           print STDERR "unable to find shared library\n";
163 0           exit 2;
164             }
165              
166 0           print "chmod 0755 $from\n";
167 0           chmod 0755, $from;
168              
169 0           my $ext = $Config{dlext};
170 0           foreach my $try (Module::Build::FFI->ffi_dlext)
171             {
172 0 0         $ext = $1 if $from =~ /\.($try)/;
173             }
174              
175 0           my $dll = File::Spec->catfile($target_dir, "$name.$ext");
176              
177 0 0         if($from ne $dll)
178             {
179 0           print "mv $from $dll\n";
180 0 0         move($from => $dll) || do {
181 0           print "error copying file $!";
182 0           exit 2;
183             };
184             }
185              
186 0           $dll;
187             }
188              
189             1;
190              
191             __END__