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 require Module
::Build
;
28 require ExtUtils
::PkgConfig
;
30 die "Math::GSL requires Module::Build and ExtUtils::PkgConfig, please install these first.\n" if $@
;
36 use File::Spec::Functions qw/:ALL/;
38 sub process_swig_files {
40 my $p = $self->{properties};
41 return unless $p->{swig_source};
42 my $files_ref = $p->{swig_source};
43 foreach my $file (@$files_ref) {
44 $self->process_swig($file->[0], $file->[1]);
48 # Check check dependencies for $main_swig_file. These are the
49 # %includes. If needed, arrange to run swig on $main_swig_file to
50 # produce a xxx_wrap.c C file.
53 my ($self, $main_swig_file, $deps_ref) = @_;
54 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
56 # File name. e.g, perlcdio.swg -> perlcdio_wrap.c
57 (my $file_base = $main_swig_file) =~ s/\.[^.]+$//;
58 my $c_file = "${file_base}_wrap.c";
60 if ($p->{swig_installed}) {
62 $self->add_to_cleanup($c_file);
64 # If any of the swig files that the main swig depends is newer
66 foreach my $depends_on ($main_swig_file, @$deps_ref) {
67 unless ($self->up_to_date($depends_on, $c_file)) {
68 $self->compile_swig($main_swig_file, $c_file);
69 # Only need to build $c_file once no matter how many
77 my $obj_file = $self->compile_c($c_file);
78 $self->add_to_cleanup($obj_file);
80 # The .so files don't go in blib/lib/, they go in blib/arch/auto/.
81 # Unfortunately we have to pre-compute the whole path.
84 my @dirs = splitdir($file_base);
85 $archdir = catdir($self->blib,'arch', @dirs[1..$#dirs]);
89 $self->link_c($archdir, $file_base, $obj_file);
92 # Invoke swig with -perl -outdir and other options.
94 my ($self, $file, $c_file) = @_;
95 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
97 # File name, minus the suffix
98 (my $file_base = $file) =~ s/\.[^.]+$//;
101 if (defined($p->{swig})) {
102 @swig = $self->split_like_shell($p->{swig});
106 if (defined($p->{swig_flags})) {
107 @swig_flags = $self->split_like_shell($p->{swig_flags});
112 push @swig_flags, $self->split_like_shell( qq{-module Math::GSL::$file_base} );
114 my $blib_lib = catfile(qw/blib lib/);
116 mkdir catfile($blib_lib, qw/Math GSL/);
117 my $outdir = catfile($blib_lib, qw/Math GSL/);
119 $self->do_system(@swig, '-o', $c_file,
121 '-perl5', @swig_flags, $file)
122 or die "error building $c_file file from '$file'";
124 my $pm_file = "${file_base}.pm";
125 my $from = catfile($blib_lib, qw/Math GSL/, $pm_file);
126 my $to = catfile(qw/lib Math GSL/,$pm_file);
128 print "Copying from: $from, to: $to; it makes the CPAN indexer happy.\n";
133 # From Base.pm but modified for a SWIG conventions.
134 # We just pass a $obj_file parameter
135 # SWIG objects have a get created with _wrap added. For example
136 # perlcdio.swg produces perlcdio_wrap.c, and perlcdio_wrap.o.
137 # But the shared object is still perlcdio.so.
138 # Also we modified the die to report the full file name.
140 my ($self, $to, $file_base, $obj_file) = @_;
141 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
143 my $lib_file = catfile($to, File::Basename::basename("$file_base.so"));
145 $self->add_to_cleanup($lib_file);
146 my $objects = $p->{objects} || [];
148 unless ($self->up_to_date([$obj_file, @$objects], $lib_file)) {
149 my @linker_flags = $self->split_like_shell($p->{extra_linker_flags});
150 my @lddlflags = $self->split_like_shell($cf->{lddlflags});
151 my @shrp = $self->split_like_shell($cf->{shrpenv});
152 my @ld = $self->split_like_shell($cf->{ld}) || "gcc";
153 $self->do_system(@shrp, @ld, @lddlflags, @user_libs, '-o', $lib_file,
154 $obj_file, @$objects, @linker_flags)
155 or die "error building $lib_file file from '$obj_file'";
161 # From Base.pm but modified to put package cflags *after*
162 # installed c flags so warning-removal will have an effect.
165 my ($self, $file) = @_;
166 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
168 # File name, minus the suffix
169 (my $file_base = $file) =~ s/\.[^.]+$//;
170 my $obj_file = $file_base . $Config{_o};
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 $Config{_o} file from '$file'";
217 my $obj_ext = $Config{_o
} || ".o";
218 unlink("$tmp.c", "$tmp$obj_ext");
220 if (open(TMPC
, ">", "$tmp.c")) {
224 my $cccmd = $args{cccmd
};
226 my $ccflags = $Config{'ccflags'};
227 $ccflags .= " $args{ccflags}" if $args{ccflags
};
229 if ($args{silent
} ) {
230 $errornull = "2>/dev/null" unless defined $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;
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.
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);
273 print "Checking for GSL..";
274 my %gsl_pkgcfg = ExtUtils
::PkgConfig
->find ('gsl');
276 my $MIN_GSL_VERSION = "1.11";
277 my $gv = $gsl_pkgcfg{'modversion'};
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]) {
286 *** You need to have GSL %s or greater installed. (You have $gv).
287 *** Get GSL at http://www.gnu.org/software/gsl\n", $MIN_GSL_VERSION;
290 print "Found GSL version $gv\n";
296 *** Can't parse GSL version $gv.
297 *** Will continue and keep my fingers crossed for luck.
303 *** Can't find GSL configuration info. Is GSL installed?
304 *** Get GSL at http://www.gnu.org/software/gsl
309 print "Checking for SWIG...";
310 my $MIN_SWIG_VERSION = "1.3.30";
311 my @swig_version = `swig -version 2>&1`;
312 my $swig_installed = 0;
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;
320 chomp $swig_version[1];
321 $swig_version[1] =~ s/[^\d\.]//g;
322 my ($big,$med,$small)=split /\./, $swig_version[1];
323 my ($big_min,$med_min,$small_min) = split /\./, $MIN_SWIG_VERSION;
324 unless ( $big >= $big_min && $med >= $med_min && $small >= $small_min ){
325 print qq{Found SWIG
$swig_version[1] but
$MIN_SWIG_VERSION is required
\n};
326 print "Please install a more recent SWIG from http://www.swig.org .\n";
329 print qq{Found SWIG
$swig_version[1] which seems recent enough
, awesome
!\n};
332 my $ccflags = $gsl_pkgcfg{cflags
};
334 ## Swig produces a number of GCC warnings. Turn them off if we can.
335 $ccflags .= try_cflags
("-Wno-strict-aliasing");
336 $ccflags .= try_cflags
("-Wno-unused-function");
337 $ccflags .= try_cflags
("-Wno-unused-value");
338 $ccflags .= try_cflags
("-Wno-unused-function");
339 $ccflags .= try_cflags
("-Wno-unused-variable");
341 my $ldflags = "$gsl_pkgcfg{libs} -gsl";
342 my $swig_flags='-Wall ' . $gsl_pkgcfg{cflags
};
344 if ('cygwin' eq $Config{osname
} &&
345 $Config{shrpenv
} =~ m{\Aenv LD_RUN_PATH=(.*)\Z} ) {
346 $ldflags .= " -L$1 -lperl";
347 # Should we check the 32-ness?
348 $swig_flags = '-DNEED_LONG';
349 } elsif ('darwin' eq $Config{osname
}) {
350 $ldflags .= " -bundle -flat_namespace";
353 my $class = Module
::Build
->subclass( code
=> $code );
354 my @Subsystems = sort qw
/
355 BLAS Diff Machine Statistics Wavelet
356 Block Eigen Matrix Poly Wavelet2D
357 BSpline Errno PowInt Sys
361 Heapsort Multifit Randist Sum
362 Combination Histogram Multimin Roots
363 Complex Histogram2D Multiroots SF
364 Const Siman IEEEUtils
365 DFT Integration NTuple Sort
366 DHT Interp ODEIV Vector
367 Deriv Linalg Permutation Spline
369 my $cleanup = qq{*.core Makefile Math
-GSL
-* tmp
* *_wrap
.c
*.pm pod2ht
*.tmp _build blib
*.so
*.orig
} .
370 join (" ", map { qq{lib
/Math/GSL
/$_.pm
} } @Subsystems);
372 my $builder = $class->new(
373 module_name
=> 'Math::GSL',
374 add_to_cleanup
=> [ $cleanup ],
375 create_makefile_pl
=> 'passthrough',
376 dist_abstract
=> 'Interface to the GNU Scientific Library using SWIG',
377 dist_author
=> 'Jonathan Leto <jonathan@leto.net>',
378 dist_version_from
=> 'lib/Math/GSL.pm',
380 extra_linker_flags
=> '-shared -I./lib -I../lib ' . $ldflags,
381 extra_compiler_flags
=> q{-shared -Wall -fpic -Dbool=char } . $ccflags,
382 swig_flags
=> $swig_flags,
383 swig_installed
=> $swig_installed,
386 'ExtUtils::PkgConfig' => '1.03',
389 'Test::Exception' => 0.21,
390 'Test::Class' => 0.12,
396 map { [ "$_.i" ] } @Subsystems
399 $builder->add_build_element('swig');
400 $builder->create_build_script();
401 print "Have a great day!\n";