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:
Bug Report: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.
===========
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 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'...(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.
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";
