I unfortunately wont be attending, but I've had a few thoughts about
these and related issues, but haven't yet had a chance to pursue them.
First, META.yml should alert installers about the dependency. The
dependency on Module::Build and any specific version requirements should
be present there. It actually is there implicitly in the 'generated_by'
field, but should probably be more explicitly listed and separated from
other dependencies, I think.
builder:
name: Module::Build
version: > 0.28
features: C_support
But the current solution is to declare it in the normal 'build_requires'
field, along with sub-dependencies like ExtUtils::CBuilder for XS builds
(yes, that feels extremely sloppy).
CPAN.pm does look at META.yml for dependencies, but I'm not sure about
CPANPLUS: I haven't had a chance to look too much into its internals.
Superficially that might be true. But if you look at how the internals
work, the process by which it does so is logically flawed in the
Module::Build case, which is what introduces the circular dependency.
I suspect there might be an incorrect assumption here on the part of
Module::Build as to the limitations of the CPAN client that are necesary
to make bootstrapping work.
I'd personally also like to see the dependency checking code move out of
Module::Build into a separate distro. I started work on this a long
while back but was never really happy with my initial approach. This was
the CPAN::Metadata module I've mentioned on a few occasions. The idea
being that CPAN.pm, CPANPLUS, Module::Build, Module::Install,
ExtUtils::MakeMaker can all use this module to read, write, and evaluate
the dependencies and other meta information in META.yml. This includes
the distant future dynamic dependency mini-language.
I suspect that this seperate dist idea is going to be something of a
non-starter from a practical perspective.
At the very least CPAN.pm has a design rule in place currently that any
dependencies needs to be optional and CPAN.pm should always work
correctly without needing them. Andreas has gone to extraordinary
lengths to hold to this concept.
The current rules surrounding dependencies are relatively straight
forward, and simple enough that reimplementation by each installer
component should be quite reasonable.
If implemented correctly, they should also mean that a more complex
dependency language is not required.
I've also wondered very briefly, without having thought it through
completely, if we couldn't move some of the initial construction code
into Module/Build.pm. Basically making it a front-end loader that will
load a very very bare minimum, do some initial checks and then load or
setup autoload to do a delayed-load of the main Module::Build::Base.
This will let us have a chance to check version problems, check that the
version currently loaded is the same version that will later be
requested for the actual 'build'. This is the current problem with the
programatic interface in some circumstances where we have one script
(eg. CPANPLUS) load Module::Build:
use Module::Build; # loads installed version
my $mb = Module::Build->new_from_context;
Then the Build.PL evaluated during the call to ->new_from_context()
changes the @INC to load a different version:
use lib 'inc'; # load a special bundled version
use Module::Build;
Oops, the bundled version isn't loaded because the installed version is
already loaded!
I actually think this is a wrong approach. As I understand it, it ends
up mixing the two codebases together. Having the installer in a
different process to the CPAN client is a very VERY good thing, as it
provides a firewall between any problems with a single installer.
There is also an important trust boundary here. We are mixing the code
from many random authors together in the same process. It's one thing
when there are clear APIs for this in normal code, but in an installer
this could result in an uncontrolled mixing of ANY arbitrary installers.
This is a combinatorially explosive situation, and causes huge scope for
obscure bugs and edge cases to appear.
We already have this working properly with CPAN.pm, and I think that
additional separation would be a good thing to add to CPANPLUS.
I /think/ if we delay loading of Module::Build::Base, we can fix this
with some caveats about not invoking any instance/class methods before
the constructor has a chance to evaluate the Build.PL. Of course, this
is still limited to running one build in the current running process...
Again, I haven't completely thought this one through though.
I think these are important problems that need to be and will be
addressed, but I still wonder how many people are experiencing the
problem? I'm not trying to belittle or deny the problem. Maybe I'm just
being defensive. But I really haven't heard of but a few instances of
this occurring. I'd sincerely like to know how much impact this bug (and
I do acknowledge that it *is* a bug or at least an incomplete feature
set ;) has had on users.
I have not heard of much in the way of impact from CPANPLUS mixing
Module::Build code into the same process (although I find it surprising
that nothing has blown up yet, and can aforementioned combinatorial
explosion I would have expected to see examples by now)
I've heard a number of people complaining about Module::Build-using
distributions failing due to the circular problem. I talk regularly with
Matt Trout from the Catalust project, who has a relatively high number
of less-experienced users, and they see problems from this as well.
I'd also add that the very nature of the problem is that it manifests
itself increasingly over time. It is somewhat similar to the PREFIX
issue in this regards (although obviously the merits of the PREFIX
feature were entirely different)
Whenever you take an assumption that used to be true and make it no
longer be true, people are going to have issues.
Also, the placeholder Makefile.PL's are masking a lot of the problem.
If you were to remove them all, even if CPAN.pm supported Build.PL,
you'd see big problems.
This would mean we can hopefully get the solution implemented in time
for the release of 5.8.9.
Module::Build will not be in core until 5.10.
Ah, ok, I had mistakenly assumed that the core merge meant a merge on
the maint branch.
Adam K