Why Module::Build sucks

I never understood why Module::Build attracted people at all

It is limited, broken and has less features than the good old EU::MM (ExtUtils::MakeMaker).

Limited:
1. dependencies, like the equivalent of make or make clean never works.
It does not check or clean important intermediate dirs and object files.
I always have to do a make realclean, to start testing with a new perl,
or updated xs file.

2. You cannot use a XS as a submodule in your package.
E.g. with Base\XS.xs windows builds will fail. Windows only!
You'll never find that out until someone else will blaim Windows.
It is just a bad Module::Build and ExtUtils::CBuilder design.
It is even not documented.
See https://rt.cpan.org/Public/Bug/Display.html?id=64476

3. On cygwin it is about 20x times slower than it should. Building Module::Build lasts ~20 minutes, because it calls a slow function to check for case-sensitivity for each file, uncached.
It is my fault, because I added this slow check, but it needed years to get the fix into Module::Build. It is still not released. (Note: My official cygwin perl is patched, this works fine.)

Broken:
It has 68 open bugs. I filed just one or two so far, and ignore the rest.
https://rt.cpan.org/Public/Dist/Display.html?Status=Active&Name=Module-Build

My current favorites:
- On Windows extra_compiler_flags is ignored.
- On Windows have_compiler fails because its companion ExtUtils::CBuilder writes to a tempfile, does not close it, but wants to compile it, which fails obviously.
https://rt.cpan.org/Ticket/Display.html?id=63911

Less features:
With EU::MM you can override almost everything with a clever API design.
Just define your MY:: override and you can do everything. Add, replace, hook.
No need for a cookbook.
Not so with Module::Build. I never saw a useful example how to override broken Module::Build methods, because those methods are too big.
With EU::MM you need to override just the getters and setters, not the methods.
With a method driven approach you need at least after, before and around methods,
as with every useful object system. (Moose for example got it from CLOS).
With a data driven approach as in EU::MM you work as in perl with tie overrides,
just fix the the data as they will appear in the Makefile.

Module.:Build is for dummies, do not use it. Even if the beginning looks sexy.
Check how many CORE modules use Module::Build. None.

In the meantime I converted all modules I took over from Module::Build to EU::MM, it became unbearable. But from time to time I still have to suffer this mess.

And sorry, I'm not in the mood to continue fixing the known problems. I just fixed the case-sensitivity check to use caching, buit the rest is beyond repair.
The flaws are fundamental, and don't want to ducktype it.

One should use EU::MM and ExtUtils::Embed, and avoid Module::Build and ExtUtils::CBuilder to avoid trouble on windows and other stricter platforms.

8 Comments

1. There is no `make` :)

2. I just put the xs into root and then did

xs_files => { 'Bar.xs' => 'lib/Foo/Bar.xs' },

for Build.PL and nothing for Makefile.PL (which I generate automatically -- no, not with M::B)

"Less features": you can subclass M::B and override any part you want as well.

But anyway, I only have a single XS module. Maybe you're right for the XS part, but it's far more better than EU::MM IMHO and IME. EU::MM is just a fall-back for me.

I never had issues with Build clean, but I can't comment on the other issues. They may be valid bugs, but bugs can usually be resolved. That said, I am a bit worried about the stagnation of its development though, it doesn't seem to get all the loving it should get.

The one thing I do vehemently disagree with is that EU::MM is easy to extend. It's not. The MY hack is horrible. EU::MM has merits but that's not one of them. Module::Build may be a bit buggy when used in unusual circumstances, but it doesn't have less features!

I'm waiting for just one system that doesn't suck, in any language. I always liked Bare Bones old motto "BBedit sucks less". Like all packaging and build systems, all editors suck. Some just suck less. :)

Three things are to note here:

First off, the current maintainer is David Golden, who has a preposterous amount of stuff on his plate already: http://search.cpan.org/~dagolden/

There has been continuous progress and bug-fixing on Module::Build, only it hasn't been submitted to CPAN as stable builds to allow for testing before wide-spread release. You can see the current log of changes here: http://cpansearch.perl.org/src/DAGOLDEN/Module-Build-0.36_20/Changes

Lastly, instead of just writing vague error reports you should provide minimal test cases and more importantly, you could simply fork on github, implement a patch and open a pull request to xdg. http://github.com/dagolden/module-build/

Software has bugs, ZOMG!!!1

Sometimes you have to vent, but you can hammer this into bug reports, and even more importantly, *patches*. Getting people to support Windows has always been a challenge as most of the toolchain people don't use Windows and don't really understand it. You obviously do. MakeMaker works on Windows because people like Jan Dubois and Christian Walde and Yasuhiro Matsumoto and Sisyphus and Steve Hay work diligently at it. And it has a huge head start over MB. It's a pain in the ass to support.

Get patching or stop bitching.

Continuing to patch MakeMaker's C compilation code is a dead end. That code will forever be wielded to MakeMaker, be a big untestable hairball, and will never benefit any other Perl project. I urge you to work on ExtUtils::CBuilder. We need an independent, testable module to compile XS code in order to move forward.

Another thing you can do is set up a smoker for your preferred platforms. If you look at the MB test matrix you can see that there's *no* Cygwin reports for the alphas and spotty Windows coverage.

Bug counts... not a useful metric. MakeMaker has 103. Test::More has 51. Some are wishlists. Some are obscure platform specific things. Some projects close bugs even before they are fixed. Others never close until full resolution.

Number of core modules using Module::Build is a terrible metric! Most (all?) of them were written before MB was in the core.

As to the idea that MakeMaker is more flexible than Module::Build, that's just poppy cock. Did you know that MakeMaker only allows you to override certain methods? Yep. Because of the crazy internal architecture there's a list of what you can override. Some things you just can't. Module::Build is a normal OO system, you can override anything.

The idea that MM is better factored is also baloney. Try adding a dependency to the 'all' target. Some targets cannot be overridden. There's no rhyme or reason as to what methods output what targets or what methods initialize what values. You have to do string replacements on fragments of make files that might change. Oh, and remember to do it all cross platform... in shell.

The biggest whopper is that you wouldn't need a cookbook for MakeMaker. Hell, *I* don't know how to do a lot of things in MakeMaker! If *you* don't need a cookbook, it's just because you've used it for so long. How do you override the test target in Module::Build? sub ACTION_test. How do you override it in MakeMaker? Have fun. How do you add a target to Module::Build and make it a dependency on another? sub ACTION_newtarget { ... } sub ACTION_othertarget { $self->depends_on("newtarget"); $self->SUPER::ACTION_othertarget(@_) } Try that in MakeMaker.

"With EU::MM you need to override just the getters and setters, not the methods." What getters and setters? What does that mean?

"With a method driven approach you need at least after, before and around methods, as with every useful object system." SOMEHOW we survived doing OO for the last 10 years without them. And MakeMaker IS OBJECT ORIENTED TOO so I don't know what you're talking about. I don't know what "data driven approach" in MakeMaker you're talking about either.

Module::Build has issues, but a fistful of minor Windows bugs isn't worth junking it for. And the idea that MakeMaker is more flexible is sheer fantasy.

I find it mildly annoying to see someone say that software I help maintain "sucks".

On the one hand, I agree that Module::Build had a number of suboptimal design choices from the start. And I certainly don't think Module::Build is the right tool for everyone.

However, at least some of the points raised are bunk. Either they were made in ignorance or they were made maliciously in place of actual argument. Assuming it's the former, I'll try to set the record straight.

For example "No CORE modules use Build.PL" -- I'm not even sure where to start. Most core modules predated Module::Build in core, for one. Few dual-life core modules even use their own Makefile.PL either; instead one is generated for them during build time due to the legacy way that Perl builds core modules. And anything in the Module::Build dependency chain can't use Build.PL either to avoid circular dependencies.

The other blatantly wrong point that annoys me is that you claim "68 open bugs". That's 68 (actually 69 last I checked) open TICKETS. If you actually looked at them, particularly sorted by severity, you'll see that most of the high severity tickets are marked patched and if you scroll way down, you'll see that half the list consists of "Wishlist" items.

You complain about an ExtUtils::CBuilder bug (#63911) which was submitted on Dec 14. It's very considerate of you to wait three whole weeks (including the holidays) before blogging about lack of progress.

I conclude that you're mostly cheesed about bug #64476, which I take from the vague and grumpy nature of the initial report and unconstructive followup message in it, in which you'd rather document a bug than fix it.

You're annoyed there hasn't been a "production" release of Module::Build in a while. Mea culpa. I didn't think it was ready and haven't had a chance to do a proper regression test. (There will be a stable release within the next month to get ready for Perl 5.14.)

You don't like the lack of proper dependency resolution (which I agree with 100%) and you find it hard to subclass (which some do and some don't).

If that's enough to qualify as "sucks" then I'm very glad to have you convert everything you can away from Module::Build.

-- dagolden

You are right at 100%. I try maintain several simple XS modules with Module::Build and end with fallback Ex:MM. IMHO M::B can be good for PP modules. For this moment I have switch to EU::MM.

I would like to add, for the record, it was originally my stabbings at Socket::GetAddrInfo that started this entire post.

Socket::GetAddrInfo is now happily building using Module::Build, and has PASSes on MSWin32.

Leave a comment

About Reini Urban

user-pic Working at cPanel on B::C (the perl-compiler), p2, types, parrot, B::Generate, cygwin perl and more guts (LLVM, jit, optimizations).