Subject: | Wrong working directory after building dependencies, causing failure |
I have just spent more than one day trying to debug why a long CPAN build job
sometimes produced output like this:
Building Module-Runtime
Installing /opt/OSAGperlm/lib/Module/Runtime.pm
Installing none/Module::Runtime.3
ZEFRAM/Module-Runtime-0.014.tar.gz
./Build install -- OK
make[1]: Entering directory '/usr/src/packages/src/OSAGperlm.dws/cpan/build/Module-Runtime-0.014-RFZP5p'
make[1]: *** No targets specified and no makefile found. Stop.
make[1]: Leaving directory '/usr/src/packages/src/OSAGperlm.dws/cpan/build/Module-Runtime-0.014-RFZP5p'
DROLSKY/Module-Implementation-0.09.tar.gz
make -- NOT OK
Or this:
make[1]: Leaving directory '/usr/src/packages/src/OSAGperlm.dws/cpan/build/Test-Warn-0.30-_wIub_'
CHORNY/Test-Warn-0.30.tar.gz
make install -- OK
Alert: no Build file available for 'make ' in cwd[/usr/src/packages/src/OSAGperlm.dws/cpan/build/Test-Warn-0.30-_wIub_]. Danger, Will Robinson!
Can't exec "./Build": No such file or directory at /opt/OSAGperl/lib/5.20.1/CPAN/Distribution.pm line 2194.
BAREFOOT/Method-Signatures-20140224.tar.gz
./Build -- NOT OK
Note how the cwd is Test-Warn, but CPAN is currently trying to build Method-Signatures.
What I found is the following code in CPAN::Distribution::make:
unless (chdir $builddir) {
$CPAN::Frontend->mywarn("Couldn't chdir to '$builddir': $!");
return;
}
...
# this changes the "chdir":
my $satisfied = eval { $self->satisfy_requires };
...
if ($self->{modulebuild}) {
unless (-f "Build" || ($^O eq 'VMS' && -f 'Build.com')) {
my $cwd = CPAN::anycwd();
$CPAN::Frontend->mywarn("Alert: no Build file available for 'make $self->{id}'".
The fix (which I tested), is this (for CPAN 2.05):
--- Distribution.pm.orig 2014-10-21 16:49:38.000000000 +0200
+++ Distribution.pm 2014-10-21 16:49:45.000000000 +0200
@@ -2130,6 +2130,13 @@
delete $self->{force_update};
return;
}
+
+ # need to chdir again, because $self->satisfy_requires might change the directory
+ unless (chdir $builddir) {
+ $CPAN::Frontend->mywarn("Couldn't chdir to '$builddir': $!");
+ return;
+ }
+
my $system;
my $make_commandline;
if ($self->prefs->{make}) {