2 # perl Makefile.PL INCDIR=/usr/src/libffi-3.0.10/include LIBDIR=/usr/src/libffi-3.0.10/lib
6 use ExtUtils::MakeMaker;
11 use subs qw|create_ctypes_limits_h get_fp_define_values|;
12 our $libffi_version = "3.0.10rc3";
14 # check the installed version of libffi and override default libdir and incdir
17 my ($libdir, $incdir);
18 my $args = join(" ", @ARGV);
19 if ($args =~ /INCDIR[ =](\S+)/) {
22 if ($args =~ /LIBDIR[ =](\S+)/) {
25 if ($libdir or $incdir) {
26 eval qq/assert_lib( lib => 'ffi', header => 'ffi.h', libpath => $libdir, incpath => $incdir )/;
28 eval q/assert_lib( lib => 'ffi', header => 'ffi.h' )/;
32 if ($^O !~ /MSWin32|msys/) {
33 warn "libffi not installed or failing. Use our own libffi $libffi_version\n";
35 my $tar = $Config{tar} ? $Config{tar} : "tar";
36 system ($tar, "xfz", "libffi.tar.gz");
39 system ($ENV{SHELL},"./configure --prefix=/");
41 system ("make install DESTDIR='$cwd'"); # abspath. install into libffi/lib, bin and include
42 $incdir = "$cwd/include";
44 if ($^O eq 'cygwin') { # copy the bin/*.dll
46 File::Copy::cp('lib/cygffi-*.dll', 'bin/');
50 warn "Using the builtin win32 binaries $libffi_version\n";
52 # install via http://sourceforge.net/projects/mingw/files/Automated%20MinGW%20Installer/mingw-get-inst/
55 $incdir = File::Spec->catfile($cwd, $libdir,"include");
56 # be sure to install the dll on site, because we link only to the import lib
58 File::Copy::cp(File::Spec->catfile($libdir, "libffi-5.dll"), "bin");
61 warn "Using system libffi.\n";
62 warn " If too old (failing _call tests) install our libffi.tar.gz and use INCDIR and LIBDIR.\n";
63 warn " tar xfz libffi.tar.gz; cd libffi; . configure --prefix=/; make && make install DESTDIR=`pwd`; cd ..\n";
64 warn " perl Makefile.PL INCDIR=libffi/include LIBDIR=libffi/lib\n";
69 VERSION_FROM => 'lib/Ctypes.pm',
70 ABSTRACT_FROM => 'lib/Ctypes.pm',
71 AUTHOR => 'Ryan Jendoubi <ryan d\x{00f6}t jendoubi at gmail d\x{00f6}t com, Reini Urban',
73 BUILD_REQUIRES => {"Regexp::Common" => 0},
74 LIBS => $libdir ? [ "-L$libdir -lffi" ] : [ "-lffi" ],
75 INC => $incdir ? "-I. -I$incdir" : "-I.",
76 realclean => {FILES => "Ctypes_float_minima.h"},
79 sub get_fp_define_values {
81 my $filename = "Ctypes_float_minima_test";
82 my @needed = qw|FLT_MIN DBL_MIN LDBL_MIN|;
83 map { $_ = 'CTYPES_' . $_ } @needed;
87 unlink ("$filename.c", "$filename$self->{EXE_EXT}",
88 "$filename$self->{OBJ_EXT}");
91 unless (open PROG, ">$filename.c") {
92 print ("Can't write $filename.c\n");
101 float f_max = FLT_MAX;
102 float f_try = -FLT_MAX + 1;
103 float f_last_try = 0;
104 float f_delta = FLT_EPSILON;
107 f_last_try = f_min = f_try;
108 f_try = f_try - f_delta;
109 if( f_try == f_last_try )
111 } while ( f_try < f_max && f_try < 0 );
112 double d_max = DBL_MAX;
113 double d_try = -DBL_MAX + 1;
114 double d_last_try = 0;
115 double d_delta = DBL_EPSILON;
118 d_last_try = d_min = d_try;
119 d_try = d_try - d_delta;
120 if( d_try == d_last_try )
122 } while ( d_try < d_max && d_try < 0 );
123 long double ld_max = LDBL_MAX;
124 long double ld_try = -LDBL_MAX + 1;
125 long double ld_last_try = 0;
126 long double ld_delta = LDBL_EPSILON;
127 long double ld_min = 0;
129 ld_last_try = ld_min = ld_try;
130 ld_try = ld_try - ld_delta;
131 if( ld_try == ld_last_try )
133 } while ( ld_try < ld_max && ld_try < 0 );
134 printf("%f\n", f_min);
135 printf("%f\n", d_min);
136 printf("%Lf\n", ld_min);
141 my $ccflags = $Config{ccflags};
143 $devnull = $^O eq 'MSWin32' ? "> NUL" : ">/dev/null 2>&1";
144 push @candidate, "$Config{cc} $Config{ccflags} -DNARF $filename.c -o $filename$self->{EXE_EXT} $devnull"
146 push @candidate, "$Config{cc} $Config{ccflags} -DNARF $filename.c -o$filename$self->{EXE_EXT} $devnull"
148 push @candidate, "$Config{cc} $Config{ccflags} -DNARF $filename.c -o $filename$self->{EXE_EXT}";
149 push @candidate, "$Config{cc} $Config{ccflags} -DNARF $filename.c -o$filename$self->{EXE_EXT}";
150 while ($self->{how_to_compile} = shift (@candidate)) {
151 unlink "$filename$self->{EXE_EXT}";
152 system ($self->{how_to_compile});
153 last if $? == 0 && -x "$filename$self->{EXE_EXT}";
155 &$cleanup && return undef unless $self->{how_to_compile};
157 push @candidate, "./$filename$self->{EXE_EXT} $devnull"
159 push @candidate, "$filename$self->{EXE_EXT} $devnull"
161 push @candidate, "$filename$self->{EXE_EXT}";
162 push @candidate, "./$filename$self->{EXE_EXT}";
163 push @candidate, "run $filename$self->{EXE_EXT}";
164 while ($self->{how_to_run} = shift (@candidate)) {
165 my @output = qx/$self->{how_to_run}/;
166 if( $? == 0 && @output ) {
167 $self->{Ctypes_limits}->{$_} = shift @output
170 return $self->{Ctypes_limits};
177 sub create_ctypes_limits_h {
179 croak "Couldn't get limits!"
180 unless my $vals = get_fp_define_values;
181 croak "Can't write Ctypes_float_minima.h"
182 unless (open HEADER, ">Ctypes_float_minima.h");
183 print HEADER <<"HEADER";
184 /*###########################################################################
185 ## Name: Ctypes_float_minima.h
186 ## Purpose: Generated by Ctypes.pm Makefile.PL to define minimum
187 ## (-ve) value alternatives to FLT_MIN, DBL_MIN etc
188 ## Author: Ryan Jendoubi
189 ## Based on: C::DynaLib's Makefile.PL
190 ## Created: 2012-06-28
191 ## Copyright: (c) 2012 Ryan Jendoubi
192 ## Licence: This program is free software; you can redistribute it and/or
193 ## modify it under the Artistic License 2.0. For details see
194 ## http://www.opensource.org/licenses/artistic-license-2.0.php
195 ###########################################################################*/
196 #ifndef _INC_CTYPES_FLOAT_MINIMA_H
197 #define _INC_CTYPES_FLOAT_MINIMA_H
199 #define CTYPES_FLT_MIN $vals->{CTYPES_FLT_MIN}
200 #define CTYPES_DBL_MIN $vals->{CTYPES_DBL_MIN}
201 #define CTYPES_LDBL_MIN $vals->{CTYPES_LDBL_MIN}
208 if (eval {require ExtUtils::Constant; 1}) {
209 # If you edit these definitions to change the constants used by this module,
210 # you will need to use the generated const-c.inc and const-xs.inc
211 # files to replace their "fallback" counterparts before distributing your
213 my @names = (qw|FFI_LONG_LONG_MAX FFI_SIZEOF_ARG FFI_SIZEOF_JAVA_RAW
214 FFI_TYPE_DOUBLE FFI_TYPE_FLOAT FFI_TYPE_INT FFI_TYPE_LAST
215 FFI_TYPE_LONGDOUBLE FFI_TYPE_POINTER FFI_TYPE_SINT16
216 FFI_TYPE_SINT32 FFI_TYPE_SINT64 FFI_TYPE_SINT8 FFI_TYPE_STRUCT
217 FFI_TYPE_UINT16 FFI_TYPE_UINT32 FFI_TYPE_UINT64 FFI_TYPE_UINT8
218 FFI_TYPE_VOID PERL_SHORT_MIN PERL_SHORT_MAX PERL_USHORT_MIN
219 PERL_USHORT_MAX PERL_INT_MIN PERL_INT_MAX PERL_UINT_MIN
220 PERL_UINT_MAX PERL_LONG_MIN PERL_LONG_MAX PERL_ULONG_MIN
221 PERL_ULONG_MAX PERL_UCHAR_MIN PERL_UCHAR_MAX CHAR_MIN CHAR_MAX
222 FLT_MAX CTYPES_FLT_MIN FLT_EPSILON
223 DBL_MAX CTYPES_DBL_MIN DBL_EPSILON
224 LDBL_MAX CTYPES_LDBL_MIN LDBL_EPSILON|,
225 {name=>"FFI_BAD_ABI", macro=>"1"},
226 {name=>"FFI_BAD_TYPEDEF", macro=>"1"},
227 {name=>"FFI_OK", macro=>"1"});
228 ExtUtils::Constant::WriteConstants(
231 C_FILE => 'const-c.inc',
232 XS_FILE => 'const-xs.inc',
233 DEFAULT_TYPE => 'NV',
238 foreach my $file ('const-c.inc', 'const-xs.inc') {
239 my $fallback = File::Spec->catfile('win32', $file);
240 File::Copy::cp ($fallback, $file) or die "Can't copy $fallback to $file: $!";
246 create_ctypes_limits_h;
248 const-xs.inc: $0 \$(CONFIGDEP)
250 const-c.inc: $0 \$(CONFIGDEP)
252 Ctypes.c: \$(XSUBPPDEPS) const-xs.inc \$(XS_FILES) util.c obj_util.c
254 README : lib/Ctypes.pm
255 pod2text lib/Ctypes.pm > README
257 gcov : Ctypes.c.gcov Ctypes.xs.gcov cover_db/Ctypes-xs.html
259 Ctypes.c.gcov Ctypes.xs.gcov : Ctypes.xs
260 \$(MAKE) CCFLAGS=\"\$(CCFLAGS) -fprofile-arcs -ftest-coverage\" LDDLFLAGS=\"\$(LDDLFLAGS) -fprofile-arcs -ftest-coverage\"
261 gcov Ctypes.c Ctypes.xs
263 cover_db/Ctypes-xs.html : Ctypes.xs.gcov
264 -PERL5OPT=-MDevel::Cover make test
265 -$^X -S gcov2perl Ctypes.c.gcov Ctypes.xs.gcov
269 \$(MAKE) CCFLAGS=\"\$(CCFLAGS) -pg\" LDDLFLAGS=\"\$(LDDLFLAGS) -pg\"