Fix typos of lenght to length in Vector.pod
[Math-GSL.git] / inc / GSLBuilder.pm
blobe5875c5406db91a886d6e48495df90a096abba7b
1 package GSLBuilder;
2 use Config;
3 use File::Copy;
4 use File::Path qw/mkpath/;
5 use File::Spec::Functions qw/:ALL/;
6 use Data::Dumper;
7 use base 'Module::Build';
9 sub is_release {
10 return -e '.git' ? 0 : 1;
12 sub subsystems {
13 sort qw/
14 Diff Machine Statistics BLAS
15 Eigen Matrix Poly MatrixComplex
16 BSpline Errno PowInt VectorComplex
17 CBLAS FFT Min IEEEUtils
18 CDF Fit QRNG
19 Chebyshev Monte RNG Vector
20 Heapsort Multifit Randist Roots
21 Combination Histogram Multimin Wavelet
22 Complex Histogram2D Multiroots Wavelet2D
23 Const Siman Sum Sys
24 NTuple Integration Sort Test
25 DHT Interp ODEIV SF
26 Deriv Linalg Permutation Spline
30 sub process_swig_files {
31 my $self = shift;
32 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});
50 (my $file_base = $main_swig_file) =~ s/\.[^.]+$//;
51 $file_base =~ s!swig/!!g;
52 my $c_file = catdir('xs',"${file_base}_wrap.c");
54 my @deps = defined $deps_ref ? @$deps_ref : ();
56 # don't bother with swig if this is a CPAN release
57 unless ( is_release() ) {
58 $self->compile_swig($main_swig_file, $c_file)
59 unless($self->up_to_date( [$main_swig_file, @deps],$c_file));
61 # .c -> .o
62 my $obj_file = $self->compile_c($c_file);
63 $self->add_to_cleanup($obj_file);
65 my $archdir = catdir($self->blib, qw/arch auto Math GSL/, $file_base);
66 mkpath $archdir unless -d $archdir;
68 # .o -> .so
69 $self->link_c($archdir, $file_base, $obj_file);
72 # Invoke swig with -perl -outdir and other options.
73 sub compile_swig {
74 my ($self, $file, $c_file) = @_;
75 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
77 # File name, minus the suffix
78 (my $file_base = $file) =~ s/\.[^.]+$//;
80 # get rid of the swig name
81 $file_base =~ s!swig/!!g;
83 my $pm_file = "${file_base}.pm";
85 my @swig = qw/swig/, defined($p->{swig}) ? ($self->split_like_shell($p->{swig})) : ();
86 my @swig_flags = defined($p->{swig_flags}) ? $self->split_like_shell($p->{swig_flags}) : ();
88 my $blib_lib = catfile(qw/blib lib/);
89 my $gsldir = catfile($blib_lib, qw/Math GSL/);
90 mkdir $gsldir unless -e $gsldir;
93 my $from = catfile($gsldir, $pm_file);
94 my $to = catfile(qw/lib Math GSL/,$pm_file);
95 chmod 0644, $from, $to;
97 $self->do_system(@swig, '-o', $c_file ,
98 '-outdir', $gsldir,
99 '-perl5', @swig_flags, $file)
100 or die "error : $! while building ( @swig_flags ) $c_file in $gsldir from '$file'";
101 print "Copying from: $from, to: $to; it makes the CPAN indexer happy.\n";
102 copy($from,$to);
103 return $c_file;
105 sub is_windows { $^O =~ /MSWin32/i }
106 sub is_darwin { $^O =~ /darwin/i }
108 # Windows fixes courtesy of <sisyphus@cpan.org>
109 sub link_c {
110 my ($self, $to, $file_base, $obj_file) = @_;
111 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
113 my $lib_file = catfile($to, File::Basename::basename("$file_base.$Config{dlext}"));
114 # this is so Perl can look for things in the standard directories
115 $lib_file =~ s!swig/!!g;
117 $self->add_to_cleanup($lib_file);
118 my $objects = $p->{objects} || [];
120 unless ($self->up_to_date([$obj_file, @$objects], $lib_file)) {
121 my @linker_flags = $self->split_like_shell($p->{extra_linker_flags});
123 push @linker_flags, $Config{archlib} . '/CORE/' . $Config{libperl} if (is_windows() or is_darwin());
125 my @lddlflags = $self->split_like_shell($cf->{lddlflags});
126 my @shrp = $self->split_like_shell($cf->{shrpenv});
127 my @ld = $self->split_like_shell($cf->{ld}) || "gcc";
129 # Strip binaries if we are compiling on windows
130 push @ld, "-s" if (is_windows() && $Config{cc} eq 'gcc');
132 $self->do_system(@shrp, @ld, @lddlflags, @user_libs, '-o', $lib_file ,
133 $obj_file, @$objects, @linker_flags)
134 or die "error building $lib_file file from '$obj_file'";
137 return $lib_file;
140 # From Base.pm but modified to put package cflags *after*
141 # installed c flags so warning-removal will have an effect.
143 sub compile_c {
144 my ($self, $file) = @_;
145 my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience
147 # File name, minus the suffix
148 (my $file_base = $file) =~ s/\.[^.]+$//;
149 my $obj_file = $file_base . $Config{_o};
151 $self->add_to_cleanup($obj_file);
152 return $obj_file if $self->up_to_date($file, $obj_file);
155 $cf->{installarchlib} = $Config{archlib};
157 my @include_dirs = @{$p->{include_dirs}}
158 ? map {"-I$_"} (@{$p->{include_dirs}}, catdir($cf->{installarchlib}, 'CORE'))
159 : map {"-I$_"} ( catdir($cf->{installarchlib}, 'CORE') ) ;
161 my @extra_compiler_flags = $self->split_like_shell($p->{extra_compiler_flags});
163 my @cccdlflags = $self->split_like_shell($cf->{cccdlflags});
165 my @ccflags = $self->split_like_shell($cf->{ccflags});
166 push @ccflags, $self->split_like_shell($Config{cppflags});
168 my @optimize = $self->split_like_shell($cf->{optimize});
170 # Whoah! There seems to be a bug in gcc 4.1.0 and optimization
171 # and swig. I'm not sure who's at fault. But for now the simplest
172 # thing is to turn off all optimization. For the kinds of things that
173 # SWIG does - do conversions between parameters and transfers calls
174 # I doubt optimization makes much of a difference. But if it does,
175 # it can be added back via @extra_compiler_flags.
177 my @flags = (@include_dirs, @cccdlflags, '-c', @ccflags, @extra_compiler_flags, );
179 my @cc = $self->split_like_shell($cf->{cc});
180 @cc = "gcc" unless @cc;
182 $self->do_system(@cc, @flags, '-o', $obj_file, $file)
183 or die "error building $Config{_o} file from '$file'";
185 return $obj_file;
188 3.14;