Changing the fopen function in docs for gsl_fopen
[Math-GSL.git] / Build.PL
blobe5aca1ce11c037cdf84c78bc9e4de60a6429485d
1 #!/usr/bin/perl -w
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
20 use strict;
21 use warnings;
22 use Config;
23 use Data::Dumper;
24 use Module::Build;
25 use ExtUtils::PkgConfig;
27 my $code = <<'EOC';
28 use Config;
29 use File::Copy;
30 use File::Spec::Functions qw/:ALL/;
32 sub process_swig_files {
33 my $self = shift;
34 my $p = $self->{properties};
35 return unless $p->{swig_source};
36 my $files_ref = $p->{swig_source};
37 foreach my $file (@$files_ref) {
38 $self->process_swig($file->[0], $file->[1]);
42 # Check check dependencies for $main_swig_file. These are the
43 # %includes. If needed, arrange to run swig on $main_swig_file to
44 # produce a xxx_wrap.c C file.
46 sub process_swig {
47 my ($self, $main_swig_file, $deps_ref) = @_;
48 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
50 # File name. e.g, perlcdio.swg -> perlcdio_wrap.c
51 (my $file_base = $main_swig_file) =~ s/\.[^.]+$//;
52 my $c_file = "${file_base}_wrap.c";
54 # .swg -> .c
55 $self->add_to_cleanup($c_file);
57 # If any of the swig files that the main swig depends is newer
58 # then rebuild.
59 foreach my $depends_on ($main_swig_file, @$deps_ref) {
60 unless ($self->up_to_date($depends_on, $c_file)) {
61 $self->compile_swig($main_swig_file, $c_file);
62 # Only need to build $c_file once no matter how many
63 # includes there are.
64 last;
68 # .c -> .o
69 my $obj_file = $self->compile_c($c_file);
70 $self->add_to_cleanup($obj_file);
72 # The .so files don't go in blib/lib/, they go in blib/arch/auto/.
73 # Unfortunately we have to pre-compute the whole path.
74 my $archdir;
76 my @dirs = splitdir($file_base);
77 $archdir = catdir($self->blib,'arch', @dirs[1..$#dirs]);
80 # .o -> .so
81 $self->link_c($archdir, $file_base, $obj_file);
84 # Invoke swig with -perl -outdir and other options.
85 sub compile_swig {
86 my ($self, $file, $c_file) = @_;
87 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
89 # File name, minus the suffix
90 (my $file_base = $file) =~ s/\.[^.]+$//;
92 my @swig;
93 if (defined($p->{swig})) {
94 @swig = $self->split_like_shell($p->{swig});
95 } else {
96 @swig = ('swig');
98 if (defined($p->{swig_flags})) {
99 @swig_flags = $self->split_like_shell($p->{swig_flags});
100 } else {
101 @swig_flags = ();
104 my $blib_lib = catfile(qw/blib lib/);
106 mkdir catfile($blib_lib, qw/Math GSL/);
107 my $outdir = catfile($blib_lib, qw/Math GSL/);
108 my $pm_file = "${file_base}.pm";
109 my $from = catfile($blib_lib, qw/Math GSL/, $pm_file);
110 my $to = catfile(qw/lib Math GSL/,$pm_file);
111 chmod 0644, $from, $to;
113 $self->do_system(@swig, '-o', $c_file,
114 '-outdir', $outdir,
115 '-perl5', @swig_flags, $file)
116 or die "error building $c_file file from '$file'";
119 print "Copying from: $from, to: $to; it makes the CPAN indexer happy.\n";
120 copy($from,$to);
121 return $c_file;
123 sub is_windows { $^O =~ /MSWin32/i }
125 # Windows fixes courtesy of <sisyphus@cpan.org>
126 sub link_c {
127 my ($self, $to, $file_base, $obj_file) = @_;
128 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
130 my $lib_file = catfile($to, File::Basename::basename("$file_base.$Config{dlext}"));
132 $self->add_to_cleanup($lib_file);
133 my $objects = $p->{objects} || [];
135 unless ($self->up_to_date([$obj_file, @$objects], $lib_file)) {
136 my @linker_flags = $self->split_like_shell($p->{extra_linker_flags});
138 push @linker_flags, $Config{archlib} . '/CORE/' . $Config{libperl} if is_windows();
140 my @lddlflags = $self->split_like_shell($cf->{lddlflags});
141 my @shrp = $self->split_like_shell($cf->{shrpenv});
142 my @ld = $self->split_like_shell($cf->{ld}) || "gcc";
143 $self->do_system(@shrp, @ld, @lddlflags, @user_libs, '-o', $lib_file,
144 $obj_file, @$objects, @linker_flags)
145 or die "error building $lib_file file from '$obj_file'";
148 return $lib_file;
151 # From Base.pm but modified to put package cflags *after*
152 # installed c flags so warning-removal will have an effect.
154 sub compile_c {
155 my ($self, $file) = @_;
156 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
158 # File name, minus the suffix
159 (my $file_base = $file) =~ s/\.[^.]+$//;
160 my $obj_file = $file_base . $Config{_o};
162 $self->add_to_cleanup($obj_file);
163 return $obj_file if $self->up_to_date($file, $obj_file);
166 $cf->{installarchlib} = $Config{archlib};
168 my @include_dirs = @{$p->{include_dirs}}
169 ? map {"-I$_"} (@{$p->{include_dirs}}, catdir($cf->{installarchlib}, 'CORE'))
170 : map {"-I$_"} ( catdir($cf->{installarchlib}, 'CORE') ) ;
172 my @extra_compiler_flags = $self->split_like_shell($p->{extra_compiler_flags});
174 my @cccdlflags = $self->split_like_shell($cf->{cccdlflags});
176 my @ccflags = $self->split_like_shell($cf->{ccflags});
177 my @optimize = $self->split_like_shell($cf->{optimize});
179 # Whoah! There seems to be a bug in gcc 4.1.0 and optimization
180 # and swig. I'm not sure who's at fault. But for now the simplest
181 # thing is to turn off all optimization. For the kinds of things that
182 # SWIG does - do conversions between parameters and transfers calls
183 # I doubt optimization makes much of a difference. But if it does,
184 # it can be added back via @extra_compiler_flags.
186 my @flags = (@include_dirs, @cccdlflags, '-c', @ccflags, @extra_compiler_flags, );
188 my @cc = $self->split_like_shell($cf->{cc});
189 @cc = "gcc" unless @cc;
191 $self->do_system(@cc, @flags, '-o', $obj_file, $file)
192 or die "error building $Config{_o} file from '$file'";
194 return $obj_file;
200 sub try_compile {
201 my ($c, %args) = @_;
203 my $ok = 0;
204 my $tmp = "tmp$$";
205 local(*TMPC);
207 my $obj_ext = $Config{_o} || ".o";
208 unlink("$tmp.c", "$tmp$obj_ext");
210 if (open(TMPC, ">", "$tmp.c")) {
211 print TMPC $c;
212 close(TMPC);
214 my $cccmd = $args{cccmd};
215 my $errornull;
216 my $ccflags = $Config{'ccflags'};
217 $ccflags .= " $args{ccflags}" if $args{ccflags};
219 if ($args{silent} ) {
220 $errornull = "2>/dev/null" unless defined $errornull;
221 } else {
222 $errornull = '';
225 $cccmd = "$Config{'cc'} -o $tmp $ccflags $tmp.c $errornull"
226 unless defined $cccmd;
228 printf "cccmd = $cccmd\n" if $args{verbose};
229 my $res = system($cccmd);
230 $ok = defined($res) && $res == 0;
232 if ( !$ok ) {
233 my $errno = $? >> 8;
234 local $! = $errno;
235 print "
237 *** The test compile of '$tmp.c' failed: status $?
238 *** (the status means: errno = $errno or '$!')
239 *** DO NOT PANIC: this just means that *some* you may get some innocuous
240 *** compiler warnings.
243 unlink("$tmp.c");
246 return $ok;
249 sub try_cflags ($) {
250 my ($ccflags) = @_;
251 my $c_prog = "int main () { return 0; }\n";
252 print "Checking if $Config{cc} supports \"$ccflags\"...";
253 my $result = try_compile($c_prog, ccflags=>$ccflags);
254 if ($result) {
255 print "yes\n";
256 return " $ccflags";
258 print "no\n";
259 return '';
263 print "Checking for GSL..";
264 my %gsl_pkgcfg = ExtUtils::PkgConfig->find ('gsl');
266 my $MIN_GSL_VERSION = "1.11";
267 my $gv = $gsl_pkgcfg{'modversion'};
269 if (defined $gv) {
270 if ($gv =~ m{\A(\d+(?:\.\d+)+)}) {
271 my @current= split /\./, $1;
272 my @min= split /\./, $MIN_GSL_VERSION;
273 unless ($current[0] >= $min[0] && $current[1] >= $min[1]) {
274 printf "
275 ***
276 *** You need to have GSL %s or greater installed. (You have $gv).
277 *** Get GSL at http://www.gnu.org/software/gsl\n", $MIN_GSL_VERSION;
278 exit 1;
279 } else {
280 print "Found GSL version $gv\n";
283 } else {
284 print "
285 ***
286 *** Can't parse GSL version $gv.
287 *** Will continue and keep my fingers crossed for luck.
290 } else {
291 print "
292 ***
293 *** Can't find GSL configuration info. Is GSL installed?
294 *** Get GSL at http://www.gnu.org/software/gsl
296 exit 1;
300 my $ccflags = $gsl_pkgcfg{cflags};
302 ## Swig produces a number of GCC warnings. Turn them off if we can.
303 $ccflags .= try_cflags("-Wno-strict-aliasing");
304 $ccflags .= try_cflags("-Wno-unused-function");
305 $ccflags .= try_cflags("-Wno-unused-value");
306 $ccflags .= try_cflags("-Wno-unused-function");
307 $ccflags .= try_cflags("-Wno-unused-variable");
309 my $ldflags = "$gsl_pkgcfg{libs} -gsl";
310 my $swig_flags='-Wall ' . $gsl_pkgcfg{cflags};
312 if ('cygwin' eq $Config{osname} &&
313 $Config{shrpenv} =~ m{\Aenv LD_RUN_PATH=(.*)\Z} ) {
314 $ldflags .= " -L$1 -lperl";
315 # Should we check the 32-ness?
316 $swig_flags = '-DNEED_LONG';
317 } elsif ('darwin' eq $Config{osname}) {
318 $ldflags .= " -bundle -flat_namespace";
321 my $class = Module::Build->subclass( code => $code );
322 my @Subsystems = sort qw/
323 BLAS Diff Machine Statistics
324 Eigen Matrix Poly Wavelet2D
325 BSpline Errno PowInt Wavelet
326 CBLAS FFT Min
327 CDF Fit QRNG
328 Chebyshev Monte RNG
329 Heapsort Multifit Randist Sum
330 Combination Histogram Multimin Roots
331 Complex Histogram2D Multiroots SF
332 Const Siman IEEEUtils Sys
333 Integration NTuple Sort
334 DHT Interp ODEIV Vector
335 Deriv Linalg Permutation Spline
337 my $cleanup = qq{core *.core Makefile Math-GSL-* tmp* pod2ht*.tmp _build blib *.so *.orig };
339 my $builder = $class->new(
340 module_name => 'Math::GSL',
341 add_to_cleanup => [ $cleanup ],
342 create_makefile_pl => 'passthrough',
343 dist_abstract => 'Interface to the GNU Scientific Library using SWIG',
344 dist_author => 'Jonathan Leto <jonathan@leto.net>',
345 dist_version_from => 'lib/Math/GSL.pm',
346 include_dirs => q{},
347 extra_linker_flags => '-shared -I./lib -I../lib ' . $ldflags,
348 extra_compiler_flags=> q{-shared -fpic } . $ccflags,
349 swig_flags => $swig_flags,
350 license => 'gpl',
351 requires => {
352 'ExtUtils::PkgConfig' => '1.03',
353 'Scalar::Util' => 0,
354 'Test::More' => 0,
355 'Test::Exception' => 0.21,
356 'Test::Class' => 0.12,
357 version => 0,
358 perl => '5.8.8',
360 sign => 0,
361 swig_source => [
362 map { [ "$_.i" ] } @Subsystems
365 $builder->add_build_element('swig');
366 $builder->create_build_script();
367 print "Have a great day!\n";