Subject: | Multiple XS files with c_source causes relink |
When there are multiple XS files and a c_source set, Module::Build will
sometimes try to relink the first object file causing the compilation to
fail. To see this happen, unpack the tarball, run Build.PL and then
continuously clean, build and rebuild until it fails. Should take just
a few iterations.
$ perl -wle 'system(q[./Build clean && ./Build && echo "Build" && echo
"Rebuild" && ./Build]) while $? == 0'
Eventually it should fail something like this (YMMV for your OS)
Rebuild
env MACOSX_DEPLOYMENT_TARGET=10.3 cc -L/sw/lib -bundle -undefined
dynamic_lookup -L/usr/local/lib -L/opt/local/lib -o
blib/arch/auto/MB/Foo/Other/Other.bundle lib/MB/Foo/Other.o ./test.o
./lib/MB/Test.o ./lib/MB/Foo/Other.o
/usr/libexec/gcc/i686-apple-darwin8/4.0.1/ld: multiple definitions of
symbol _XS_MB__Other_other
lib/MB/Foo/Other.o definition of _XS_MB__Other_other in section
(__TEXT,__text)
./lib/MB/Foo/Other.o definition of _XS_MB__Other_other in section
(__TEXT,__text)
/usr/libexec/gcc/i686-apple-darwin8/4.0.1/ld: multiple definitions of
symbol _boot_MB__Other
lib/MB/Foo/Other.o definition of _boot_MB__Other in section (__TEXT,__text)
./lib/MB/Foo/Other.o definition of _boot_MB__Other in section
(__TEXT,__text)
collect2: ld returned 1 exit status
error building blib/arch/auto/MB/Foo/Other/Other.bundle from
lib/MB/Foo/Other.o ./test.o ./lib/MB/Test.o ./lib/MB/Foo/Other.o at
/usr/local/lib/site_perl/ExtUtils/CBuilder/Base.pm line 213.
This is because link_c() is linking each library against all the object
files. process_support_files() just puts all the object files into one
big list. Because it builds last, this means lib/MB/Test.o is sometimes
newer than lib/MB/Foo/Other.o and thus MB thinks recompilation is necessary.
I believe each library should link only against its own object file. I
may be wrong but it does work. The attached patch does so.
Subject: | MB-Test.tgz |
Subject: | xs.patch |
--- lib/Module/Build/Base.pm (revision 55266)
+++ lib/Module/Build/Base.pm (local)
@@ -2270,7 +2270,7 @@
my $files = $self->rscan_dir($p->{c_source}, file_qr('\.c(pp)?$'));
foreach my $file (@$files) {
- push @{$p->{objects}}, $self->compile_c($file);
+ $p->{objects}{$file} = $self->compile_c($file);
}
}
@@ -3972,18 +3972,19 @@
$self->add_to_cleanup($spec->{lib_file});
- my $objects = $p->{objects} || [];
+ my @objects = $spec->{obj_file};
+ push @objects, $p->{objects}{$spec->{lib_file}}
+ if $p->{objects}{$spec->{lib_file}};
return $spec->{lib_file}
- if $self->up_to_date([$spec->{obj_file}, @$objects],
- $spec->{lib_file});
+ if $self->up_to_date(\@objects => $spec->{lib_file});
my $module_name = $self->module_name;
$module_name ||= $spec->{module_name};
$self->cbuilder->link(
module_name => $module_name,
- objects => [$spec->{obj_file}, @$objects],
+ objects => \@objects,
lib_file => $spec->{lib_file},
extra_linker_flags => $p->{extra_linker_flags} );