Hi Ken,

I've done some more testing under windows, and corrected some problems in the test script for the Borland and MinGW compilers. I broke up some of the code in the test script into a couple of subroutines (do_compile & do_link) to clean up the mess I made in the main testing routine jumping through all those hoops to satisfy the 3 supported compilers on that platform...

On 2/11/2003 11:02 PM, Ken Williams wrote:
On Tuesday, February 11, 2003, at 05:25  PM, Randy W. Sims wrote:

( It would be nice if there were a module specifically for invoking the compiler & linker. There are quite a few modules I can think of that would benifit from it. )

Absolutely. I've gotten surprisingly good results in Module::Build with just straightforward system() calls, or at least people haven't submitted bug reports. But it would be cool to abstract this away somewhere.
Bug Report:
===========

M::B does not work on MSWin32. ;)

It needs to do pretty much the same thing as the patched basic.t in ParseXS. I'll make the modifications and test it out if you want?

(I'd also like to fix the "Use of uninitialized value in join or string at /Users/ken/src/modules/ExtUtils-ParseXS/blib/lib/ExtUtils/ParseXS.pm line 798, <File0000> line 14" error before 2.00, but I don't know what's causing it.)

I don't recall seeing that message. Do you see it when building a particular module?

I see it when running 'make test' for ExtUtils::ParseXS.

I included a fix for this in the patch. The array @proto_arg will have an undefined slot in it when prototypes are requested and a subroutine is encounted that does not have any default parameters. That slot is reserved for the flag ( ';' - semicolon ) that indicates the start of the parms with defaults. (You can verify by changing the XS file so is_even has a default parm or changing the calls to process_file in the test script so that 'prototypes => 0') The fix is just to 'grep defined, @proto_arg'...

The thing that puzzles me is that without 'use warnings' I would not expect to see that warning:

$ perl -e "my @a=(undef,'blah');print join('',@a);"
blah

$ perl -we "my @a=(undef,'blah');print join('',@a);"
Use of uninitialized value in join or string at -e line 1.
blah

Randy.
diff -ur ExtUtils-ParseXS-1.99-orig/lib/ExtUtils/ParseXS.pm 
ExtUtils-ParseXS-1.99/lib/ExtUtils/ParseXS.pm
--- ExtUtils-ParseXS-1.99-orig/lib/ExtUtils/ParseXS.pm  2003-02-15 03:47:24.000000000 
-0500
+++ ExtUtils-ParseXS-1.99/lib/ExtUtils/ParseXS.pm       2003-02-16 08:47:49.000000000 
+-0500
@@ -795,7 +795,7 @@
        push @proto_arg, "$s\@"
          if $elipsis ;
        
-       $proto = join ("", @proto_arg);
+       $proto = join ("", grep(defined, @proto_arg));
       }
       else {
        # User has specified a prototype
diff -ur ExtUtils-ParseXS-1.99-orig/t/basic.t ExtUtils-ParseXS-1.99/t/basic.t
--- ExtUtils-ParseXS-1.99-orig/t/basic.t        2003-02-15 03:55:15.000000000 -0500
+++ ExtUtils-ParseXS-1.99/t/basic.t     2003-02-16 11:48:39.000000000 -0500
@@ -16,10 +16,10 @@
 
 use Carp; $SIG{__WARN__} = \&Carp::cluck;
 
-sub Is_MSVC { return $^O eq 'MSWin32'
-               && $Config{cc} =~ /cl(\.exe)?$/i
-               && $Config{ld} =~ /link(\.exe)?$/i
-}
+my $Is_MSWin32 = $^O eq 'MSWin32';
+my $BCC   = $Is_MSWin32 && $Config{cc} =~ /bcc32(\.exe)?$/;
+my $MSVC  = $Is_MSWin32 && $Config{cc} =~ /cl(\.exe)?$/;
+my $MinGW = $Is_MSWin32 && $Config{cc} =~ /gcc(\.exe)?$/;
 
 #########################
 
@@ -34,26 +34,12 @@
 
 # Try to compile the file!  Don't get too fancy, though.
 if (have_compiler()) {
-  my $corelib = File::Spec->catdir($Config{archlib}, 'CORE');
-  my $o_file = "XSTest$Config{obj_ext}";
-  my $cc_out = Is_MSVC() ? '-Fo' : '-o ';
-
-  ok !do_system("$Config{cc} -c $Config{ccflags} -I$corelib $cc_out$o_file XSTest.c");
-  ok -e $o_file, 1, "Make sure $o_file exists";
-  
-  my $lib_file = "XSTest.$Config{dlext}";
-  my $ld_out = '-o ';
-  my $libs = '';
-  if ( $^O eq 'MSWin32' ) {
-    require ExtUtils::Mksymlists;
-    Mksymlists( 'NAME' => 'XSTest', 'DLBASE' => 'XSTest', 'IMPORTS' => {} );
-    
-    if ( Is_MSVC() ) {
-      $ld_out = '-OUT:';
-      $libs = "$Config{libperl} -def:XSTest.def";
-    }
-  }
-  ok !do_system("$Config{shrpenv} $Config{ld} $Config{lddlflags} $ld_out$lib_file 
$o_file $Config{libs} $libs" );
+  my $module = 'XSTest';
+
+  ok do_compile( $module );
+  ok -e $module.$Config{obj_ext}, 1, "Make sure $module exists";
+
+  ok do_link( $module );
 
   eval {require XSTest};
   ok $@, '';
@@ -69,7 +55,7 @@
 sub find_in_path {
   my $thing = shift;
   my @path = split $Config{path_sep}, $ENV{PATH};
-  my @exe_ext = $^O eq 'MSWin32' ?
+  my @exe_ext = $Is_MSWin32 ?
     split($Config{path_sep}, $ENV{PATHEXT} || '.com;.exe;.bat') :
     ('');
   foreach (@path) {
@@ -94,6 +80,52 @@
   return 1;
 }
 
+sub do_compile {
+  my $module   = shift;
+  my $module_o = "$module$Config{obj_ext}";
+  my $corelib  = File::Spec->catdir($Config{archlib}, 'CORE');
+  my $cc_out   = $MSVC ? '-Fo' : $BCC ? '-o' : '-o ';
+  return !do_system("$Config{cc} -c $Config{ccflags} -I$corelib $cc_out$module_o 
+$module.c");
+}
+
+sub do_link {
+  my $module     = shift;
+  my $module_lib = "$module.$Config{dlext}";
+  my $module_def = '';
+
+  my $objs      = "$module$Config{obj_ext}";
+  my $libs      = $Config{libs};
+  my $lddlflags = $Config{lddlflags};
+  my $ld_out    = '-o ';
+
+  if ( $Is_MSWin32 ) {
+    require ExtUtils::Mksymlists;
+    ExtUtils::Mksymlists::Mksymlists(
+      'NAME' => $module, 'DLBASE' => $module, 'IMPORTS' => {} );
+
+    if      ( $MSVC  ) { # Microsoft
+      $ld_out     = '-out:';
+      $libs      .= " $Config{libperl}";
+      $module_def = "-def:$module.def";
+    } elsif ( $BCC   ) { # Borland
+      $objs       = "c0d32.obj $objs"; # Borland's startup obj; must be before others
+      $ld_out     = '';
+      $module_lib = ",$module_lib";
+      $libs       = ",,$Config{libperl} $libs";
+      $module_def = ",$module.def";
+    } elsif ( $MinGW ) { # MinGW GCC
+      (my $libperl = $Config{libperl}) =~ s/^(?:lib)?([^.]+).*$/$1/;
+      $libs        = "-l$libperl $libs";
+      do_system("dlltool --def $module.def --output-exp $module.exp");
+      do_system("$Config{ld} $lddlflags -Wl,--base-file -Wl,$module.base $objs 
+$ld_out$module_lib $libs $module.exp");
+      do_system("dlltool --def $module.def --output-exp $module.exp --base-file 
+$module.base");
+      $module_def  = "$module.exp";
+    }
+  }
+
+  return !do_system("$Config{shrpenv} $Config{ld} $lddlflags $objs $ld_out$module_lib 
+$libs $module_def");
+}
+
 sub do_system {
   my $cmd = shift;
   print "$cmd\n";

Reply via email to