Clean up the NTuple, Statistics and Sum subsystems. Got rid of Precision.i .
[Math-GSL.git] / Build.PL
blobc2ff6800920bc9354915127c89be530b625bae94
1 #!/usr/bin/perl -w
3 # This script has been heavily modified from the Device::Cdio Build.PL
4 # Jonathan Leto <jonathan@leto.net>
6 # Copyright (C) 2006 Rocky Bernstein <rocky@cpan.org>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 use strict;
22 use warnings;
23 use Config;
24 use Data::Dumper;
26 BEGIN {
27 eval {
28 require Module::Build;
29 require ExtUtils::PkgConfig;
31 die "Math::GSL requires Module::Build and ExtUtils::PkgConfig, please install these first.\n" if $@;
34 my $code = <<'EOC';
35 use Config;
36 use File::Copy;
37 use File::Spec::Functions qw/:ALL/;
39 sub process_swig_files {
40 my $self = shift;
41 my $p = $self->{properties};
42 return unless $p->{swig_source};
43 my $files_ref = $p->{swig_source};
44 foreach my $file (@$files_ref) {
45 $self->process_swig($file->[0], $file->[1]);
49 # Check check dependencies for $main_swig_file. These are the
50 # %includes. If needed, arrange to run swig on $main_swig_file to
51 # produce a xxx_wrap.c C file.
53 sub process_swig {
54 my ($self, $main_swig_file, $deps_ref) = @_;
55 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
57 # File name. e.g, perlcdio.swg -> perlcdio_wrap.c
58 (my $file_base = $main_swig_file) =~ s/\.[^.]+$//;
59 my $c_file = "${file_base}_wrap.c";
61 if ($p->{swig_installed}) {
62 # .swg -> .c
63 $self->add_to_cleanup($c_file);
65 # If any of the swig files that the main swig depends is newer
66 # then rebuild.
67 foreach my $depends_on ($main_swig_file, @$deps_ref) {
68 unless ($self->up_to_date($depends_on, $c_file)) {
69 $self->compile_swig($main_swig_file, $c_file);
70 # Only need to build $c_file once no matter how many
71 # includes there are.
72 last;
77 # .c -> .o
78 my $obj_file = $self->compile_c($c_file);
79 $self->add_to_cleanup($obj_file);
81 # The .so files don't go in blib/lib/, they go in blib/arch/auto/.
82 # Unfortunately we have to pre-compute the whole path.
83 my $archdir;
85 my @dirs = splitdir($file_base);
86 $archdir = catdir($self->blib,'arch', @dirs[1..$#dirs]);
89 # .o -> .so
90 $self->link_c($archdir, $file_base, $obj_file);
93 # Invoke swig with -perl -outdir and other options.
94 sub compile_swig {
95 my ($self, $file, $c_file) = @_;
96 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
98 # File name, minus the suffix
99 (my $file_base = $file) =~ s/\.[^.]+$//;
101 my @swig;
102 if (defined($p->{swig})) {
103 @swig = $self->split_like_shell($p->{swig});
104 } else {
105 @swig = ('swig');
107 if (defined($p->{swig_flags})) {
108 @swig_flags = $self->split_like_shell($p->{swig_flags});
109 } else {
110 @swig_flags = ();
113 push @swig_flags, $self->split_like_shell( qq{-module Math::GSL::$file_base} );
115 my $blib_lib = catfile(qw/blib lib/);
117 mkdir catfile($blib_lib, qw/Math GSL/);
118 my $outdir = catfile($blib_lib, qw/Math GSL/);
120 $self->do_system(@swig, '-o', $c_file,
121 '-outdir', $outdir,
122 '-perl5', @swig_flags, $file)
123 or die "error building $c_file file from '$file'";
125 my $pm_file = "${file_base}.pm";
126 my $from = catfile($blib_lib, qw/Math GSL/, $pm_file);
127 my $to = catfile(qw/lib Math GSL/,$pm_file);
129 print "Copying from: $from, to: $to; it makes the CPAN indexer happy.\n";
130 copy($from,$to);
131 return $c_file;
134 # From Base.pm but modified for a SWIG conventions.
135 # We just pass a $obj_file parameter
136 # SWIG objects have a get created with _wrap added. For example
137 # perlcdio.swg produces perlcdio_wrap.c, and perlcdio_wrap.o.
138 # But the shared object is still perlcdio.so.
139 # Also we modified the die to report the full file name.
140 sub link_c {
141 my ($self, $to, $file_base, $obj_file) = @_;
142 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
144 my $lib_file = catfile($to, File::Basename::basename("$file_base.so"));
146 $self->add_to_cleanup($lib_file);
147 my $objects = $p->{objects} || [];
149 unless ($self->up_to_date([$obj_file, @$objects], $lib_file)) {
150 my @linker_flags = $self->split_like_shell($p->{extra_linker_flags});
151 my @lddlflags = $self->split_like_shell($cf->{lddlflags});
152 my @shrp = $self->split_like_shell($cf->{shrpenv});
153 my @ld = $self->split_like_shell($cf->{ld}) || "gcc";
154 $self->do_system(@shrp, @ld, @lddlflags, @user_libs, '-o', $lib_file,
155 $obj_file, @$objects, @linker_flags)
156 or die "error building $lib_file file from '$obj_file'";
159 return $lib_file;
162 # From Base.pm but modified to put package cflags *after*
163 # installed c flags so warning-removal will have an effect.
165 sub compile_c {
166 my ($self, $file) = @_;
167 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
169 # File name, minus the suffix
170 (my $file_base = $file) =~ s/\.[^.]+$//;
171 my $obj_file = "$file_base.so";
172 $self->add_to_cleanup($obj_file);
173 return $obj_file if $self->up_to_date($file, $obj_file);
176 $cf->{installarchlib} = $Config{archlib};
178 my @include_dirs = @{$p->{include_dirs}}
179 ? map {"-I$_"} (@{$p->{include_dirs}}, catdir($cf->{installarchlib}, 'CORE'))
180 : map {"-I$_"} ( catdir($cf->{installarchlib}, 'CORE') ) ;
182 my @extra_compiler_flags = $self->split_like_shell($p->{extra_compiler_flags});
184 my @cccdlflags = $self->split_like_shell($cf->{cccdlflags});
186 my @ccflags = $self->split_like_shell($cf->{ccflags});
187 my @optimize = $self->split_like_shell($cf->{optimize});
189 # Whoah! There seems to be a bug in gcc 4.1.0 and optimization
190 # and swig. I'm not sure who's at fault. But for now the simplest
191 # thing is to turn off all optimization. For the kinds of things that
192 # SWIG does - do conversions between parameters and transfers calls
193 # I doubt optimization makes much of a difference. But if it does,
194 # it can be added back via @extra_compiler_flags.
196 my @flags = (@include_dirs, @cccdlflags, '-c', @ccflags, @extra_compiler_flags, );
198 my @cc = $self->split_like_shell($cf->{cc});
199 @cc = "gcc" unless @cc;
201 $self->do_system(@cc, @flags, '-o', $obj_file, $file)
202 or die "error building $cf->{obj_ext} file from '$file'";
204 return $obj_file;
210 sub try_compile {
211 my ($c, %args) = @_;
213 my $ok = 0;
214 my $tmp = "tmp$$";
215 local(*TMPC);
217 my $obj_ext = $Config{obj_ext} || ".o";
218 unlink("$tmp.c", "$tmp$obj_ext");
220 if (open(TMPC, ">", "$tmp.c")) {
221 print TMPC $c;
222 close(TMPC);
224 my $cccmd = $args{cccmd};
225 my $errornull;
226 my $ccflags = $Config{'ccflags'};
227 $ccflags .= " $args{ccflags}" if $args{ccflags};
229 if ($args{silent} ) {
230 $errornull = "2>/dev/null" unless defined $errornull;
231 } else {
232 $errornull = '';
235 $cccmd = "$Config{'cc'} -o $tmp $ccflags $tmp.c $errornull"
236 unless defined $cccmd;
238 printf "cccmd = $cccmd\n" if $args{verbose};
239 my $res = system($cccmd);
240 $ok = defined($res) && $res == 0;
242 if ( !$ok ) {
243 my $errno = $? >> 8;
244 local $! = $errno;
245 print "
247 *** The test compile of '$tmp.c' failed: status $?
248 *** (the status means: errno = $errno or '$!')
249 *** DO NOT PANIC: this just means that *some* you may get some innocuous
250 *** compiler warnings.
253 unlink("$tmp.c");
256 return $ok;
259 sub try_cflags ($) {
260 my ($ccflags) = @_;
261 my $c_prog = "int main () { return 0; }\n";
262 print "Checking if $Config{cc} supports \"$ccflags\"...";
263 my $result = try_compile($c_prog, ccflags=>$ccflags);
264 if ($result) {
265 print "yes\n";
266 return " $ccflags";
268 print "no\n";
269 return '';
273 print "Checking for GSL..";
274 my %gsl_pkgcfg = ExtUtils::PkgConfig->find ('gsl');
276 use constant MIN_GSL_VERSION => "1.11";
277 my $gv = $gsl_pkgcfg{'modversion'};
279 if (defined $gv) {
280 if ($gv =~ m{\A(\d+(?:\.\d+)+)}) {
281 my @current= split /\./, $1;
282 my @min= split /\./, MIN_GSL_VERSION;
283 unless ($current[0] >= $min[0] && $current[1] >= $min[1]) {
284 printf "
285 ***
286 *** You need to have GSL %s or greater installed. (You have $gv).
287 *** Get GSL at http://www.gnu.org/software/gsl
288 ", MIN_GSL_VERSION;
289 exit 1;
290 } else {
291 print "Found GSL version $gv\n";
294 } else {
295 print "
296 ***
297 *** Can't parse GSL version $gv.
298 *** Will continue and keep my fingers crossed for luck.
301 } else {
302 print "
303 ***
304 *** Can't find GSL configuration info. Is GSL installed?
305 *** Get GSL at http://www.gnu.org/software/gsl
307 exit 1;
310 print "Checking for SWIG...";
311 my @swig_version = `swig -version 2>&1`;
312 my $swig_installed = 0;
313 if ($?) {
314 my $errno = $? >> 8;
315 print "I don't see SWIG installed. Please install SWIG from http://www.swig.org .\n";
316 print "*** Output was:\n @swig_version\n" if @swig_version;
317 exit(0);
318 } else {
319 $swig_installed = 1;
320 print qq{Found $swig_version[1]};
323 my $ccflags = $gsl_pkgcfg{cflags};
325 ## Swig produces a number of GCC warnings. Turn them off if we can.
326 $ccflags .= try_cflags("-Wno-strict-aliasing");
327 $ccflags .= try_cflags("-Wno-unused-function");
328 $ccflags .= try_cflags("-Wno-unused-value");
329 $ccflags .= try_cflags("-Wno-unused-function");
330 $ccflags .= try_cflags("-Wno-unused-variable");
332 my $ldflags = "$gsl_pkgcfg{libs} -gsl";
333 my $swig_flags='-Wall';
334 if ('cygwin' eq $Config{osname} &&
335 $Config{shrpenv} =~ m{\Aenv LD_RUN_PATH=(.*)\Z} ) {
336 $ldflags .= " -L$1 -lperl";
337 # Should we check the 32-ness?
338 $swig_flags = '-DNEED_LONG';
339 } elsif ('darwin' eq $Config{osname}) {
340 $ldflags .= " -bundle -flat_namespace";
343 my $class = Module::Build->subclass( code => $code );
344 my @Subsystems = sort qw/
345 BLAS Diff Machine Statistics Wavelet
346 Block Eigen Matrix Poly Wavelet2D
347 BSpline Errno PowInt Sys
348 CBLAS FFT Min
349 CDF Fit Mode QRNG
350 Chebyshev Monte RNG
351 Heapsort Multifit Randist Sum
352 Combination Histogram Multimin Roots
353 Complex Histogram2D Multiroots SF
354 Const Siman IEEEUtils
355 DFT Integration NTuple Sort
356 DHT Interp ODEIV Vector
357 Deriv Linalg Permutation Spline
359 my $cleanup = qq{*.core Makefile Math-GSL-* tmp* *_wrap.c *.pm pod2ht*.tmp _build blib *.so *.orig } .
360 join (" ", map { qq{lib/Math/GSL/$_.pm} } @Subsystems);
362 my $builder = $class->new(
363 module_name => 'Math::GSL',
364 add_to_cleanup => [ $cleanup ],
365 create_makefile_pl => 'passthrough',
366 dist_abstract => 'Interface to the GNU Scientific Library using SWIG',
367 dist_author => 'Jonathan Leto <jonathan@leto.net>',
368 dist_version_from => 'lib/Math/GSL.pm',
369 include_dirs => q{},
370 extra_linker_flags => '-shared -I./lib -I../lib -I/usr/local/include/ ' . $ldflags,
371 extra_compiler_flags=> q{-shared -Wall -fpic -Dbool=char -I/usr/local/include/ } . $ccflags,
372 swig_flags => $swig_flags,
373 swig_installed => $swig_installed,
374 license => 'gpl',
375 requires => {
376 'ExtUtils::PkgConfig' => '1.03',
377 'Scalar::Util' => 0,
378 'Test::More' => 0,
379 'Test::Exception' => 0.21,
380 'Test::Class' => 0.12,
381 version => 0,
382 perl => '5.6.0',
384 sign => 1,
385 swig_source => [
386 map { [ "$_.i" ] } @Subsystems
389 $builder->add_build_element('swig');
390 $builder->create_build_script();
391 print "Have a great day!\n";