3 # This script has been heavily modified from the Device::Cdio Build.PL
4 # Jonathan Leto <jonathan@leto.net>
5 # Copyright (C) 2006 Rocky Bernstein <rocky@cpan.org>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 eval { require ExtUtils
::PkgConfig
};
29 print "\nI see that you are a CPANTester, you really should install ExtUtils::PkgConfig !\n"
30 if $ENV{AUTOMATED_TESTING
};
32 ExtUtils::PkgConfig is currently needed to find GSL for the compilation of this module.
33 It may be bundled with Math::GSL in the future.
42 use File::Spec::Functions qw/:ALL/;
44 sub process_swig_files {
46 my $p = $self->{properties};
47 return unless $p->{swig_source};
48 my $files_ref = $p->{swig_source};
49 foreach my $file (@$files_ref) {
50 $self->process_swig($file->[0], $file->[1]);
54 # Check check dependencies for $main_swig_file. These are the
55 # %includes. If needed, arrange to run swig on $main_swig_file to
56 # produce a xxx_wrap.c C file.
59 my ($self, $main_swig_file, $deps_ref) = @_;
60 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
62 # File name. e.g, perlcdio.swg -> perlcdio_wrap.c
63 (my $file_base = $main_swig_file) =~ s/\.[^.]+$//;
64 my $c_file = "${file_base}_wrap.c";
67 $self->add_to_cleanup($c_file);
69 # If any of the swig files that the main swig depends is newer
71 foreach my $depends_on ($main_swig_file, @$deps_ref) {
72 unless ($self->up_to_date($depends_on, $c_file)) {
73 $self->compile_swig($main_swig_file, $c_file);
74 # Only need to build $c_file once no matter how many
81 my $obj_file = $self->compile_c($c_file);
82 $self->add_to_cleanup($obj_file);
84 # The .so files don't go in blib/lib/, they go in blib/arch/auto/.
85 # Unfortunately we have to pre-compute the whole path.
88 my @dirs = splitdir($file_base);
89 $archdir = catdir($self->blib,'arch', @dirs[1..$#dirs]);
93 $self->link_c($archdir, $file_base, $obj_file);
96 # Invoke swig with -perl -outdir and other options.
98 my ($self, $file, $c_file) = @_;
99 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
101 # File name, minus the suffix
102 (my $file_base = $file) =~ s/\.[^.]+$//;
105 if (defined($p->{swig})) {
106 @swig = $self->split_like_shell($p->{swig});
110 if (defined($p->{swig_flags})) {
111 @swig_flags = $self->split_like_shell($p->{swig_flags});
116 my $blib_lib = catfile(qw/blib lib/);
118 mkdir catfile($blib_lib, qw/Math GSL/);
119 my $outdir = catfile($blib_lib, qw/Math GSL/);
120 my $pm_file = "${file_base}.pm";
121 my $from = catfile($blib_lib, qw/Math GSL/, $pm_file);
122 my $to = catfile(qw/lib Math GSL/,$pm_file);
123 chmod 0644, $from, $to;
125 $self->do_system(@swig, '-o', $c_file,
127 '-perl5', @swig_flags, $file)
128 or die "error building $c_file file from '$file'";
131 print "Copying from: $from, to: $to; it makes the CPAN indexer happy.\n";
135 sub is_windows { $^O =~ /MSWin32/i }
137 # Windows fixes courtesy of <sisyphus@cpan.org>
139 my ($self, $to, $file_base, $obj_file) = @_;
140 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
142 my $lib_file = catfile($to, File::Basename::basename("$file_base.$Config{dlext}"));
144 $self->add_to_cleanup($lib_file);
145 my $objects = $p->{objects} || [];
147 unless ($self->up_to_date([$obj_file, @$objects], $lib_file)) {
148 my @linker_flags = $self->split_like_shell($p->{extra_linker_flags});
150 push @linker_flags, $Config{archlib} . '/CORE/' . $Config{libperl} if is_windows();
152 my @lddlflags = $self->split_like_shell($cf->{lddlflags});
153 my @shrp = $self->split_like_shell($cf->{shrpenv});
154 my @ld = $self->split_like_shell($cf->{ld}) || "gcc";
156 # Strip binaries if we are compiling on windows
157 push @ld, "-s" if (is_windows() && $Config{cc} eq 'gcc');
159 $self->do_system(@shrp, @ld, @lddlflags, @user_libs, '-o', $lib_file,
160 $obj_file, @$objects, @linker_flags)
161 or die "error building $lib_file file from '$obj_file'";
167 # From Base.pm but modified to put package cflags *after*
168 # installed c flags so warning-removal will have an effect.
171 my ($self, $file) = @_;
172 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
174 # File name, minus the suffix
175 (my $file_base = $file) =~ s/\.[^.]+$//;
176 my $obj_file = $file_base . $Config{_o};
178 $self->add_to_cleanup($obj_file);
179 return $obj_file if $self->up_to_date($file, $obj_file);
182 $cf->{installarchlib} = $Config{archlib};
184 my @include_dirs = @{$p->{include_dirs}}
185 ? map {"-I$_"} (@{$p->{include_dirs}}, catdir($cf->{installarchlib}, 'CORE'))
186 : map {"-I$_"} ( catdir($cf->{installarchlib}, 'CORE') ) ;
188 my @extra_compiler_flags = $self->split_like_shell($p->{extra_compiler_flags});
190 my @cccdlflags = $self->split_like_shell($cf->{cccdlflags});
192 my @ccflags = $self->split_like_shell($cf->{ccflags});
193 push @ccflags, $self->split_like_shell($Config{cppflags});
195 my @optimize = $self->split_like_shell($cf->{optimize});
197 # Whoah! There seems to be a bug in gcc 4.1.0 and optimization
198 # and swig. I'm not sure who's at fault. But for now the simplest
199 # thing is to turn off all optimization. For the kinds of things that
200 # SWIG does - do conversions between parameters and transfers calls
201 # I doubt optimization makes much of a difference. But if it does,
202 # it can be added back via @extra_compiler_flags.
204 my @flags = (@include_dirs, @cccdlflags, '-c', @ccflags, @extra_compiler_flags, );
206 my @cc = $self->split_like_shell($cf->{cc});
207 @cc = "gcc" unless @cc;
209 $self->do_system(@cc, @flags, '-o', $obj_file, $file)
210 or die "error building $Config{_o} file from '$file'";
225 my $obj_ext = $Config{_o
} || ".o";
226 unlink("$tmp.c", "$tmp$obj_ext");
228 if (open(TMPC
, ">", "$tmp.c")) {
232 my $cccmd = $args{cccmd
};
234 my $ccflags = $Config{'ccflags'};
235 $ccflags .= " $args{ccflags}" if $args{ccflags
};
237 if ($args{silent
} ) {
238 $errornull = "2>/dev/null" unless defined $errornull;
243 $cccmd = "$Config{'cc'} -o $tmp $ccflags $tmp.c $errornull"
244 unless defined $cccmd;
246 printf "cccmd = $cccmd\n" if $args{verbose
};
247 my $res = system($cccmd);
248 $ok = defined($res) && $res == 0;
255 *** The test compile of '$tmp.c' failed: status $?
256 *** (the status means: errno = $errno or '$!')
257 *** DO NOT PANIC: this just means that *some* you may get some innocuous
258 *** compiler warnings.
269 my $c_prog = "int main () { return 0; }\n";
270 print "Checking if $Config{cc} supports \"$ccflags\"...";
271 my $result = try_compile
($c_prog, ccflags
=>$ccflags);
281 print "Checking for GSL..";
282 my %gsl_pkgcfg = ExtUtils
::PkgConfig
->find ('gsl');
284 my $MIN_GSL_VERSION = "1.8";
285 my $gv = $gsl_pkgcfg{'modversion'};
286 my $current_minor_version;
289 if ($gv =~ m{\A(\d+(?:\.\d+)+)}) {
290 my @current= split /\./, $1;
291 my @min= split /\./, $MIN_GSL_VERSION;
292 $current_minor_version = $current[1];
293 unless ($current[0] >= $min[0] && $current[1] >= $min[1]) {
296 *** You need to have GSL %s or greater installed. (You have $gv).
297 *** Get GSL at http://www.gnu.org/software/gsl\n", $MIN_GSL_VERSION;
300 print "Found GSL version $gv\n";
306 *** Can't parse GSL version $gv.
307 *** Will continue and keep my fingers crossed for luck.
313 *** Can't find GSL configuration info. Is GSL installed?
314 *** Get GSL at http://www.gnu.org/software/gsl
320 my $ccflags = $gsl_pkgcfg{cflags
};
322 ## Swig produces a number of GCC warnings. Turn them off if we can.
323 $ccflags .= try_cflags
("-Wno-strict-aliasing");
324 $ccflags .= try_cflags
("-Wno-unused-function");
325 $ccflags .= try_cflags
("-Wno-unused-value");
326 $ccflags .= try_cflags
("-Wno-unused-function");
327 $ccflags .= try_cflags
("-Wno-unused-variable");
329 my $ldflags = "$gsl_pkgcfg{libs} -gsl";
330 my $swig_flags='-Wall ' . $gsl_pkgcfg{cflags
};
332 if ('cygwin' eq $Config{osname
} &&
333 $Config{shrpenv
} =~ m{\Aenv LD_RUN_PATH=(.*)\Z} ) {
334 $ldflags .= " -L$1 -lperl";
335 # Should we check the 32-ness?
336 $swig_flags = '-DNEED_LONG';
337 } elsif ('darwin' eq $Config{osname
}) {
338 $ldflags .= " -bundle -flat_namespace";
341 my $class = Module
::Build
->subclass( code
=> $code );
342 my @Subsystems = sort qw
/
343 BLAS Diff Machine Statistics
344 Eigen Matrix Poly Wavelet2D
345 BSpline Errno PowInt Wavelet
349 Heapsort Multifit Randist Sum
350 Combination Histogram Multimin Roots
351 Complex Histogram2D Multiroots SF
352 Const Siman IEEEUtils Sys
353 Integration NTuple Sort
354 DHT Interp ODEIV Vector
355 Deriv Linalg Permutation Spline
358 # BSplines appeared in 1.9
359 if ($current_minor_version < 9 ) {
360 @Subsystems = grep { ! /BSpline/ } @Subsystems;
362 my $cleanup = qq{core
*.core Makefile Math
-GSL
-* tmp
* pod2ht
*.tmp _build blib
*.so
*.orig
};
364 my $builder = $class->new(
365 module_name
=> 'Math::GSL',
366 add_to_cleanup
=> [ $cleanup ],
367 create_makefile_pl
=> 'passthrough',
368 dist_abstract
=> 'Interface to the GNU Scientific Library using SWIG',
369 dist_author
=> 'Jonathan Leto <jonathan@leto.net>',
370 dist_version_from
=> 'lib/Math/GSL.pm',
372 extra_linker_flags
=> '-shared -I./lib -I../lib ' . $ldflags,
373 extra_compiler_flags
=> q{-shared -fpic } . $ccflags,
374 swig_flags
=> $swig_flags,
377 'ExtUtils::PkgConfig' => '1.03',
380 'Test::Exception' => 0.21,
381 'Test::Class' => 0.12,
387 map { [ "$_.i" ] } @Subsystems
390 $builder->add_build_element('swig');
391 $builder->create_build_script();
392 print "Have a great day!\n";