Skip Menu |

This queue is for tickets about the Math-GSL CPAN distribution.

Report information
The Basics
Id: 38131
Status: resolved
Priority: 0/
Queue: Math-GSL

People
Owner: jonathan [...] leto.net
Requestors: sisyphus [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 0.07
Fixed in: (no value)



Subject: Math-GSL-0.07 won't build on Win32
I have Win32 (Vista), perl-5.10.0, using MinGW (port of gcc) compiler and gsl-1.11. We come to a stage very early on in the Build process where the following command gets run: gcc -o blib\arch\BLAS.so BLAS_wrap.o -shared -I./lib -I../lib - LC:/_32/msys/local/lib -lgsl -lgslcblas -lm -gsl First thing to note is that the output file we're attempting to build there is 'BLAS.so', but for Win32 that file should be named 'BLAS.dll'. For portability, we need to be building "BLAS.$Config{dlext}". But that's not what stops the command from succeeding. On Windows (unlike linux) all symbols need to be resolved at build time - and there's nothing in that command that's going to resolve the perl symbols. Consequently I get a string of "undefined reference" errors beginning with: BLAS_wrap.o:BLAS_wrap.c:(.text+0xb42): undefined reference to `Perl_get_context' BLAS_wrap.o:BLAS_wrap.c:(.text+0xb53): undefined reference to `Perl_mg_get' BLAS_wrap.o:BLAS_wrap.c:(.text+0xb58): undefined reference to `Perl_get_context' BLAS_wrap.o:BLAS_wrap.c:(.text+0xb67): undefined reference to `Perl_sv_isobject' . . And the build process terminates. I don't know whether this is a bug in the Math::GSL Build.PL file, or a bug in Module::Build itself. (I'm not very familiar with Module::Build.) Do you happen to have a Makefile.PL that will enable the build to work using ExtUtils::MakeMaker ? I'm not very strong on MakeMaker either, but it was a fairly simple task to write a Makefile.PL that enabled the 'make' process to compile all of the C source files without any troubles. (I gather from the various "multiple definition" warnings I ultimately got that one is not supposed to build each and every one of those C files.) Of course, there's more to building the module than simply being able to compile the C files. I've had some experience with creating Makefile.PL's where an XS source file is involved, but no experience in writing Makefile.PL's that have to deal with multiple C source files. Cheers, Rob
On Sat Aug 02 21:09:38 2008, SISYPHUS wrote: . . Show quoted text
> We come to a stage very early on in the Build process where the > following command gets run: > > gcc -o blib\arch\BLAS.so BLAS_wrap.o -shared -I./lib -I../lib - > LC:/_32/msys/local/lib -lgsl -lgslcblas -lm -gsl >
The following patch to Build.PL portably fixes that command (and hence removes the ensuing errors that it caused): ------------------------------------- --- Build.PL_orig Sun Aug 3 18:20:42 2008 +++ Build.PL Sun Aug 3 18:03:27 2008 @@ -131,13 +131,14 @@ my ($self, $to, $file_base, $obj_file) = @_; my ($cf, $p) = ($self->{config}, $self->{properties}); # For convenience - my $lib_file = catfile($to, File::Basename::basename ("$file_base.so")); + my $lib_file = catfile($to, File::Basename::basename ("$file_base.$Config{dlext}")); $self->add_to_cleanup($lib_file); my $objects = $p->{objects} || []; unless ($self->up_to_date([$obj_file, @$objects], $lib_file)) { my @linker_flags = $self->split_like_shell($p-> {extra_linker_flags}); + push @linker_flags, $Config{archlib} . '/CORE/' . $Config{libperl} if $^O =~ /MSWin32/i; my @lddlflags = $self->split_like_shell($cf->{lddlflags}); my @shrp = $self->split_like_shell($cf->{shrpenv}); my @ld = $self->split_like_shell($cf->{ld}) || "gcc"; ------------------------------------- However, in building blib\arch\Block.dll file from 'Block_wrap.o', the following errors are produced: ------------------------------------- Block_wrap.o:Block_wrap.c:(.text+0xd0e7): undefined reference to `gsl_block_complex_long_double_fscanf' Block_wrap.o:Block_wrap.c:(.text+0xd45e): undefined reference to `gsl_block_complex_long_double_fprintf' Block_wrap.o:Block_wrap.c:(.text+0xe071): undefined reference to `gsl_block_complex_long_double_raw_fscanf' Block_wrap.o:Block_wrap.c:(.text+0xe529): undefined reference to `gsl_block_complex_long_double_raw_fprintf' Block_wrap.o:Block_wrap.c:(.text+0x1cd0d): undefined reference to `gsl_block_long_double_fscanf' Block_wrap.o:Block_wrap.c:(.text+0x1d084): undefined reference to `gsl_block_long_double_fprintf' Block_wrap.o:Block_wrap.c:(.text+0x1dc97): undefined reference to `gsl_block_long_double_raw_fscanf' Block_wrap.o:Block_wrap.c:(.text+0x1e14f): undefined reference to `gsl_block_long_double_raw_fprintf' ------------------------------------- Those symbols are certainly present in the header files, but not in the library files. At first glance, this would appear to be a bug in the gsl-1.11 build. I'll investigate as time permits. Cheers, Rob
Show quoted text
> At first glance, this would appear to be a bug in the > gsl-1.11 build. I'll investigate as time permits.
No, it doesn't seem to be a bug in the gsl-1.11 build. I think it's simply a case of those functions being unworkable on Win32. The following patch to Block_wrap.c portably addresses this problem by having those functions simply croak when called on Win32: --------------------------------------- --- Block_wrap.c_orig Thu Aug 7 00:32:16 2008 +++ Block_wrap.c Thu Aug 7 21:12:34 2008 @@ -4263,7 +4263,7 @@ } } - +#ifndef WIN32 XS(_wrap_gsl_block_complex_long_double_fscanf) { { FILE *arg1 = (FILE *) 0 ; @@ -4349,7 +4349,10 @@ SWIG_croak_null(); } } - +#else +XS(_wrap_gsl_block_complex_long_double_fscanf) {croak ("gsl_block_complex_long_double_fscanf not implemented on Win32");} +XS(_wrap_gsl_block_complex_long_double_fprintf) {croak ("gsl_block_complex_long_double_fprintf not implemented on Win32");} +#endif XS(_wrap_gsl_block_complex_long_double_raw_fread) { { @@ -4466,7 +4469,7 @@ } } - +#ifndef WIN32 XS(_wrap_gsl_block_complex_long_double_raw_fscanf) { { FILE *arg1 = (FILE *) 0 ; @@ -4592,7 +4595,10 @@ SWIG_croak_null(); } } - +#else +XS(_wrap_gsl_block_complex_long_double_raw_fscanf) {croak ("gsl_block_complex_long_double_raw_fscanf not implemented on Win32");} +XS(_wrap_gsl_block_complex_long_double_raw_fprintf) {croak ("gsl_block_complex_long_double_raw_fprintf not implemented on Win32");} +#endif XS(_wrap_gsl_block_complex_long_double_size) { { @@ -7863,7 +7869,7 @@ } } - +#ifndef WIN32 XS(_wrap_gsl_block_long_double_fscanf) { { FILE *arg1 = (FILE *) 0 ; @@ -7949,7 +7955,10 @@ SWIG_croak_null(); } } - +#else +XS(_wrap_gsl_block_long_double_fscanf) {croak ("gsl_block_long_double_fscanf not implemented on Win32");} +XS(_wrap_gsl_block_long_double_fprintf) {croak ("gsl_block_long_double_fprintf not implemented on Win32");} +#endif XS(_wrap_gsl_block_long_double_raw_fread) { { @@ -8066,7 +8075,7 @@ } } - +#ifndef WIN32 XS(_wrap_gsl_block_long_double_raw_fscanf) { { FILE *arg1 = (FILE *) 0 ; @@ -8192,7 +8201,10 @@ SWIG_croak_null(); } } - +#else +XS(_wrap_gsl_block_long_double_raw_fscanf) {croak ("gsl_block_long_double_raw_fscanf not implemented on Win32");} +XS(_wrap_gsl_block_long_double_raw_fprintf) {croak ("gsl_block_long_double_raw_fprintf not implemented on Win32");} +#endif XS(_wrap_gsl_block_long_double_size) { { --------------------------------------- Next up, we strike a problem in Poly_wrap.c with the way that Perl_sv_dump() is called on Win32. The portable solution to that problem is to apply the following patch: --------------------------------------- --- Poly_wrap.c_orig Thu Aug 7 00:31:26 2008 +++ Poly_wrap.c Wed Aug 6 20:51:28 2008 @@ -2544,10 +2544,10 @@ if( *helem == NULL) croak("Structure does not contain 'dat' element\n"); printf("helem is:\n"); - Perl_sv_dump(*helem); + sv_dump(*helem); if( i == 0){ svtmp = (SV*)SvRV(*helem); - Perl_sv_dump(svtmp); + sv_dump(svtmp); } printf("re z = %f\n", GSL_REAL(z) ); printf("im z = %f\n", GSL_IMAG(z) ); --------------------------------------- With those changes in place, the build proceeds successfully. On Win32, 'nan' and 'inf' are represented as '1.#NAN' and '1.#INF' respectively. This accounts for the failure of the CDF.t tests. The following patch to lib/Math/GSL.pm addresses this bug: --------------------------------------- --- GSL.pm_orig Thu Aug 7 00:32:40 2008 +++ GSL.pm Thu Aug 7 00:17:32 2008 @@ -294,6 +294,8 @@ } my $res = abs($x - $expected); if ($x =~ /nan|inf/i ){ + $^O =~ /MSWin32/i ? + ok((($expected =~ /nan/i && $x =~ /nan/i) || ($expected =~ /inf/i && $x =~ /inf/i) && ($expected =~/\-/ == $x =~ /\- / )), "'$expected' ?='$x'") : ok( $expected eq $x, "'$expected' ?='$x'" ); } else { ok( $res <= $eps, "$code ?= $x,\nres= +-$res, eps=$eps" ); --------------------------------------- One of the PowInt.t tests also fails because of 'inf' and 'nan' handling - but I haven't yet worked out what needs to be done about that. The Histogram.t test suite fails with a segfault because of "ERROR: histogram bin extremes must be in increasing order" and Histogram2D.t fails in a similar way with a similar error. RNG.t segfaults with "ERROR: fread failed" and SF.t segfaults with "ERROR: domain error". So there's still a bit to keep prodding at. Other than that, all tests pass. Cheers, Rob
Show quoted text
> One of the PowInt.t tests also fails because of 'inf' and 'nan' > handling - but I haven't yet worked out what needs to be done about > that.
Here's a patch to PowInt.t that addresses that bug: ------------------------------------ --- PowInt.t_orig Sat Aug 9 11:44:48 2008 +++ PowInt.t Sat Aug 9 15:54:13 2008 @@ -6,6 +6,8 @@ use warnings; use Test::Exception; +my $inf = $^O =~ /MSWin32/i ? 99 ** 99 ** 99 : 'inf'; +my $nan = $^O =~ /MSWin32/i ? unpack 'd', scalar reverse pack 'H*', '7FF8000000000000' : 'nan'; { ok( gsl_pow_4(2) == gsl_pow_2(4) , q{%EXPORT_TAGS works} ); @@ -30,12 +32,12 @@ 'gsl_pow_7(8)' , 'gsl_pow_8(-4)' , 'gsl_pow_9(4)' , - q{gsl_pow_2('nan')} , - q{gsl_pow_2('inf')} , + q{gsl_pow_2($nan)} , + q{gsl_pow_2($inf)} , 'gsl_pow_int(5,10)' , ) ], [ (3.14) ** 2, 3 ** 2, 0 ** 2, (-1) ** 2, 4 ** 3, 5 ** 4, 6 ** 5, 7 ** 6, - 8 ** 7, (-4) ** 8, 4 ** 9, q{nan}, q{inf}, 5 ** 10, + 8 ** 7, (-4) ** 8, 4 ** 9, $nan, $inf, 5 ** 10, ], "basic power tests", ); ------------------------------------ Cheers, Rob
Show quoted text
> RNG.t segfaults with "ERROR: fread failed"
Here's a patch (to RNG/Test.pm) that addresses that bug: ----------------------------- --- Test.PM_orig Sun Aug 10 17:48:36 2008 +++ \_32\comp\Math-GSL-0.07\blib\lib\Math\GSL\RNG\Test.pm Sun Aug 10 18:00:23 2008 @@ -122,13 +122,15 @@ sub GSL_RNG_FWRITE_FREAD : Tests { my $self = shift; + my $write = $^O =~ /MSWin32/i ? "w + b" : "w"; + my $read = $^O =~ /MSWin32/i ? "r + b" : "r"; my $rng = gsl_rng_alloc($gsl_rng_default); - my $fh = fopen("rng" , "w"); + my $fh = fopen("rng" , $write); is(gsl_rng_fwrite($fh, $self->{rng}), 0); fclose($fh); - $fh = fopen("rng", "r"); + $fh = fopen("rng", $read); is(gsl_rng_fread($fh, $rng),0); is(gsl_rng_get($rng), gsl_rng_get($self->{rng})); fclose($fh); ----------------------------- Cheers, Rob
On Sun Aug 10 04:08:56 2008, SISYPHUS wrote: . . Show quoted text
> + my $write = $^O =~ /MSWin32/i ? "w + b" : "w"; > + my $read = $^O =~ /MSWin32/i ? "r + b" : "r";
For the record, that worked ok on Windows Vista, but not Windows XP. (Yeah ... I don't know why, either.) The correct fix, of course, is to replace "w + b" and "r + b" in the above patch with "w+b" and "r+b". Cheers, Rob
This has been resolved, Math::GSL compiles and all tests pass on windows as of 0.12 .