in reply to MakeMaker-Makefile Reform School

How to override the overridable MakeMaker methods is fully documented in other places (such as the manpage for MakeMaker)

I've looked over the ExtUtils::MakeMaker manpage several times, but I still can't find any documentation on proper use of its (to my eyes) completely weird &MY::stuff type of "inheritance" (or whatever it is).

Makemaker is still one of perl's biggest mysteries to me, so if you have any hints on where to find this documentation, please please please share it.

update: As an example, the docs say

[...] you can edit the default by saying something like: package MY; # so that "SUPER" works right sub c_o { my $inherited = shift->SUPER::c_o(@_); $inherited =~ s/old text/new text/; $inherited; }

And then remains silent on what the &c_o method is supposed to do, and only mentions &postamble, which doesn't do anything by default. Likewise, there is no mention of any method to override to create your own META.yml file (and there is one, but I forgot what it was).

update2: fixed broken arrow...

J.

Replies are listed 'Best First'.
Re^2: MakeMaker-Makefile Reform School
by Intrepid (Curate) on Mar 31, 2005 at 00:41 UTC
    Joost wrote
    I've looked over the ExtUtils::MakeMaker manpage several times, but I still can't find any documentation on proper use of its (to my eyes) completely weird &MY::stuff type of "inheritance" (or whatever it is).


    Note: within 15 minutes or so of posting this reply, I had to fix some typos and errors in the example at bottom. Should read correctly now.
    Update Notice: (2005.04.03) - I've realized based on some recent discussions that the documentation cited is probably ineffectual / wrong ... so the "expanded" sub-method override code at the bottom of this message now shows us using a diferent means than "::SUPER" to accomplish what's needed.

    It takes some getting used to. I'll try to help with a little elucidation of what happens, etc. OO terminology not being my very strongest point, it may be that others will offer pointers too.

    The direct answer to your original question is: the documentation in the POD for ExtUtils::MakeMaker that you pointed to is the Fun{damental} Documentation. My 2Ed Camel ("Programming Perl" for newbies ;-) gives the same basic example and text. There is no other.

    The answer to the implied question is this:

    • Look at the build of the module as it proceeds. Is anything amiss? Read every line of the compiler output. If nothing is broken, there's nothing to fix.

    • If you find that there's something to fix, then that something lives in the Makefile. Each MM method that outputs text leaves a snailtrail that looks like this, in the Makefile:
           # --- MakeMaker <mm_methodname> section:
      
      where mm_methodname happens to be the name of the MM method that creates the text that follows. All you have to do is "reverse-engineer" by finding the part of the Makefile where things are not going as you wish (make conforms to the MJD principle just like any other computer programming: it cannot magically guess what you need, you have to tell it in the proper manner). Once you have done that, you know what method you want to override.
    • A little warning here:
      Although it probably should not be, there is some interdependency between the MM methods that are overridable. I have found that overriding one made output of another break. This is not, I think, in conformance with the original intentions of the early MM authors, and may be bugs introduced in the later rewriting which has been going on.

      Back to our show
    • ... the method override is written into the Makefile.PL. It does not matter whether it comes before the WriteMakefile() invocation or not: it is a sub declaration, it is grokked at compile time.

    Now that we've gotten the "why" or "when" (might I want to override a MM method) out of the way, and touched on the "how", let's go back and look at the "ehhhh?!?".

    Understand that this IS OO programming. When use ExtUtils::MakeMaker; is seen, there's going to be an implicit instantiation of a ExtUtils::MakeMaker object happening. Right away. By perl mechanism this object is the first arg passed into all method calls; by MakeMaker convention the object is assigned to the scoped lexical var $self. Thus we are always operating on a $self unless we choose to just throw away the object, as in:

    sub MY::makefile { return "# removed" }
    In this example I have left a little snail slime (a comment) in the Makefile, where the "stuff" that once directed the re-making of the Makefile once was. I ignored the MM object completely. The point here is that the MM methods which exist to create segments of the Makefile just output a string; this is quite simple actually. Each is like a part of a modern modular assembly-line process for creating manufactured goods, like automobiles. MakeMaker takes care of assembling all the parts into the final vehicle (the output Makefile). You can modify any part by either taking the "stock" part and working modifications on it, or chuck it in the junk heap completely and start from scratch. "Monster Garage" has nothing on us!

    The example given in a recent ExtUtils::MakeMaker POD page shows both approaches. Their example of "modification of the stock part" looks like this:

    package MY; sub c_o { my $inherited = shift->SUPER::c_o(@_); $inherited =~ s/old text/new text/; $inherited; }
    This (bogus) example shows overriding of the MM method that generates the Makefile entries for remaking object files from C code modules.

    Saying package MY; sub c_o .... is just the same as saying sub MY::c-o { ..... There is no difference whatsoever.

    This is inheritance (Perl-style) at work, yes. But one doesn't really have to understand why or how it works in order to use it, one can just take the example (and hours of poring over the POD and source for ExtUtils::MM_Unix) ;-) and modify it to suit one's requirements. The bottom line is that anything declared into the MY:: package is going to have the final word on what gets placed in the Makefile.

    Rewritten to remove some terse obfuscating confusion, the above example could look like this (commented to aid understanding):

    sub MY::c_o { my $self = shift( @_ ); # get our MM object local *c_o; # localize to inside our current scope a +t runtime. my $inherited_text = $self->MM::c_o( @_ ); # any other args get p +assed to # the "stock" MM metho +d (there # generally are none). $inherited_text =~ s/old text/new text/; # do vengeance on those +who have # wronged us. return $inherited_text; # a return of a scalar whose value is jus +t a # (probably multi-line) string. }

    HTH!

Re^2: MakeMaker-Makefile Reform School
by ysth (Canon) on Mar 31, 2005 at 06:11 UTC
    The ExtUtils::MakeMaker documentation directs you to ExtUtils::MM_Unix for documentation of all MakeMaker methods, where it says:
    c_o (o)
        Defines the suffix rules to compile different flavors of C files to object files.
    To see what that looks like, open up a generated Makefile and look for "MakeMaker c_o section:".