Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

let Makefile.PL to do the Readme file for me -- new target?

by Discipulus (Abbot)
on Jan 19, 2021 at 16:36 UTC ( #11127103=perlquestion: print w/replies, xml ) Need Help??

Discipulus has asked for the wisdom of the Perl Monks concerning the following question:

Hello folks!

Despite many years programming in Perl I'm at my second real module. I'm used to module-starter that uses ExtUtils::MakeMaker as default builder.

My laziness got suddenly annoyed to maintain a Readme file manually: I brutally copy my pod output to this file, but I must remember to do it anytime I modify the doc.

I supposed to automate this and I asked here and there. I was pointed to Overriding-MakeMaker-Methods where is stated:

> Here is a simple example of how to add a new target to the generated Makefile:

The only working (for my purpose) modification to my Makefile.PL is the following

sub MY::postamble { return <<'MAKE_README'; postamble :: $(PERLRUN) -MPod::Text \ -e "Pod::Text->new (sentence => 1, width => 78)->parse_from_file( +qw( $(TO_INST_PM) Readme) );" MAKE_README }

Which modify the end of resulting Makefile generated by perl Makefile.PL from:

# --- MakeMaker postamble section: # End.

to this:

# --- MakeMaker postamble section: postamble :: $(PERLRUN) -MPod::Text \ -e "Pod::Text->new (sentence => 1, width => 78)->parse_from_file( +qw( $(TO_INST_PM) Readme) );" # End.

Then I can succesfully run dmake postamble (yes strawberry perl has dmake) to have my Readme updated.

Questions

MY::postamble is a fixed name? Both the class MY and the postamble name are fixed? I tried different names and it always complains: dmake:  Error: -- Don't know how to make `customname' Cannot the creation of the Readme integrated inside make dist or other similar steps?

Or should I treat Makefile.PL as a normal perl program putting my custom do_readme sub call before WriteMakefile one?

It's only me or the docs are sybilline and stingy of words?

PS I have chatted a bit on #perl channel about this and the discussion diverged on authoring tools (where ExtUtils::MakeMaker is not an authoring tool). mbtiny was suggested and also Distar with some interesting read: A-BRIEF-HISTORY-OF-AUTHORING and a COMPARISON

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Replies are listed 'Best First'.
Re: let Makefile.PL to do the Readme file for me -- new target?
by pryrt (Monsignor) on Jan 19, 2021 at 16:55 UTC
    MY::postamble is a fixed name? Both the class MY and the postamble name are fixed? I tried different names and it always complains: dmake: Error: -- Don't know how to make `customname' Cannot the creation of the Readme integrated inside make dist or other similar steps?

    MY::postamble is a fixed name. But the target name inside that postamble is not fixed, and there can actually be more than one.

    sub MY::postamble { return <<'MAKE_README'; postamble :: $(PERLRUN) -MPod::Text \ -e "Pod::Text->new (sentence => 1, width => 78)->parse_from_file( +qw( $(TO_INST_PM) Readme) );" another_target :: $(PERLRUN) -MPod::Text \ -e "Pod::Text->new (sentence => 1, width => 78)->parse_from_file( +qw( $(TO_INST_PM) Readme) );" third :: $(PERLRUN) -MPod::Text \ -e "Pod::Text->new (sentence => 1, width => 78)->parse_from_file( +qw( $(TO_INST_PM) Readme) );" MAKE_README }

    ... will create three new targets, all of which do the same thing (as written), with dmake postamble, dmake another_target, and dmake third.

    See Win32::Mechanize::NotepadPlusPlus::Makefile.PL for an example of a bunch of extra targets, including ones to extract the README and LICENSE automagically from the POD.

    edit: finished the last sentence; thanks hippo :/edit

    edit2: replaced leading spaces with tabs to make it more portable; the actual commands listed were just copy/pasted from OP, and I didn't test/confirm; for known-working examples, see the linked Makefile.PL :/edit2

    edit3: fixed per Re^2: let Makefile.PL to do the Readme file for me -- new target?; left original in spoiler for context :/edit3

      Don't quote me on this, but years and years ago, I almost seem to recall adding stuff to the built-in targets:

      install:: shell command \ do things dist:: ....

      Update: In fact, something like this:

      install:: cgi conf graphics docs libs templates retest clean:: clean_sourcedirs clean_test cgi: install -m 0500 -o www -g www src/cgi-bin/accounting.cgi ${CGIDIR} clean_sourcedirs: rm -f doc/*.html rm -f doc/*.conf clean_test: rm -f t/test.db rm -f t/test.conf-dist ... and other things called by the main directives, such as conf, grap +hics for install...
        quoting stevieb on this, in direct violation of his wishes ;-)
        Don't quote me on this, but years and years ago, I almost seem to recall adding stuff to the built-in targets:

        yes. My linked Makefile.PL shows a realclean:: section, which adds new tasks to an existing target of that same name. It adds it after any existing actions for the target.

      >
      sub MY::postamble { return <<'MAKE_README'; ... MAKE_README ... MAKE_README ... MAKE_README }

      You have a C&P error here.

      I think you wanted to return the whole block not only the first rule, right?

      Delete MAKE_README #2 and #3 :)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        whoops. Fixed my node. Sorry about that. :-)
      > See Win32::Mechanize::NotepadPlusPlus::Makefile.PL for an example of a bunch of extra targets

      With the help of https://makefiletutorial.com/ I was able to decipher, well at least get an idea of what is happening.

      We use a

      Perlmodule to build a makefile with embedded rules in here-docs snippets

      And those makefile rules embed

      • a macro syntax
      • a variable syntax
      • plus bash code

      So to be runnable on other plattforms we need

      • a make program
      • a bash emulation

      Doesn't sound like a very efficient way to have a file-timestamp-dependency system in Perl.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        Rolf, no offense meant, but you seem to want this to be difficult; it's really not.

        For example, did you notice the name of that module: it starts with "Win32"? The solution I showed functions perfectly in Strawberry Perl on Windows, out of the box.

        Strawberry gives you the gcc build environment, with dmake (older strawberries) or gmake (newer strawberries) with perl -V:make showing the make variant to use. No extra work on your part. No bash emulation needed.

        Using a perl module to build a makefile is part of the standard ExtUtils::MakeMaker environment.

        Data::IEEE754::Tools Makefile.PL shows similar syntax, with the same syntax working on both Windows and Linux environments.

        Using the Makefile.PL -> Makefile to add extra targets, to automate extra things for development, is an intended use of the ExtUtils::MakeMaker environment. If you don't like it, that's your perogative; you don't have to use it. But it is a system that works, even on Windows with Strawberry Perl.

Makefile caveat: tabs not spaces
by bliako (Prior) on Jan 20, 2021 at 14:49 UTC

    Apropos Makefile: since time immemorial Makefile uses tabs as part of its syntax. Tabs are important to Makefile (at least in *nix, though later GNU additions make this flexible). 8 or 4 spaces will not do. And so, in Discipulus example:

    return <<'MAKE_README'; postamble :: $(PERLRUN) -MPod::Text \ -e "Pod::Text->new (sentence => 1, width => 78)->parse_from_file( +qw( $(TO_INST_PM) Readme) );" MAKE_README

    In the here-doc, the space before $(PERLRUN) should be a single (real) tab if we want to be portable, I guess.

    But in M$-windows system dmake probably made a compromise? Or it's run with special command-line flags? Because I see there are just 4 spaces and not a single tab.

    Apropos2: recently there was a discussion about tabs and spaces in code and how editors can transform these. They were not counting die-hard Makefile.

    bw, bliako

      But in M$-windows system dmake probably made a compromise? Or it's run with special command-line flags?

      dmake uses a syntax that looks a little bit like GNU make, but it has some nasty differences. Quoting its man page:

      dmake is not compatible with GNU Make. In particular it does not understand GNU Make's macro expansions that query the file system.

      dmake is fully compatible with SYSV AUGMAKE

      And yes, dmake can use spaces instead of tabs:

      OPTIONS

      [...]

      -B
      Enable the use of spaces instead of <tabs> to begin recipe lines. This flag equivalent to the .NOTABS special macro and is further described below.

      [...]

      CONTROL MACROS

      [...]

      .NOTABS
      When set to "yes" enables the use of spaces as well as <tabs> to begin recipe lines. By default a non-group recipe is terminated by a line without any leading white-space or by a line not beggining with a <tab> character. Enabling this mode modifies the first condition of the above termination rule to terminate a non-group recipe with a line that contains only white-space. This mode does not effect the parsing of group recipes bracketed by [].

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        I'm trying to play with the examples given in https://makefiletutorial.com/#default-shell

        But I'm on Windows and have dmake via ActiveState's Perl installed, which is trying to use batch as shell-language.

        Do you happen to know how I can tell dmake to use it's "bash" emulation?

        (I suppose strongly it comes with ActiveState too)

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

        update

        I was able to work around that by using git-bash ... But I'm still curios what the canonical approach may be.

Re: let Makefile.PL to do the Readme file for me -- new target?
by LanX (Cardinal) on Jan 19, 2021 at 17:31 UTC
    I'm a bit irritated about what your goal is.

    When you asked in the CB I thought you wanted to have an up-to-date README which is displayed as GitHub's project page during development

    But AFAIK is makefile.pl only relevant when installing from CPAN on the client side.

    So I'm not sure if the solution I shared with you is of any use...

    Probably I'm missing something?

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      Dont feel irritated LanX, take it easy :)

      Yesterday I asked in the chatterbox:

      > can I use my Makefile.pl to autogenerate the Readme based on POD of the main module?

      and you answered with a nice trick about doing it in a pseudo test file. Nothing bad on both part. I'm investigating the matter.

      Your solution is good in the sense it updates the Readme anytime you run prove -l -v so the github/gitlab Readme is always up to date. It is not clean in the sense that tests are for testing.

      Using the Makefile.pl on the other hand, will update the Readme only during the make phase so github/gitlab Readme will be always out of date and another git push is needed after make postamble is run.

      PS I always look at What are the files in a CPAN distribution? and it says:

      > MetaCPAN will display the following documentation files on a release's front page if they exist: ./README / ./README.md / ./README.pod

      L*

      There are no rules, there are no thumbs..
      Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
        I'm easy, just curious.

        > It is not clean in the sense that tests are for testing.

        Well include a check if README is up to date at the end and you got a "clean test". ;-)

        You might also want to ensure that these kind of "tests" are only run when authoring on your machine.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

        > > MetaCPAN will display the following documentation files on a release's front page if they exist: ./README / ./README.md / ./README.pod

        OK didn't know that ...

        I created README.pod primarly for GitHub.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

      "But AFAIK is makefile.pl only relevant when installing from CPAN on the client side."

      Not necessarily if it's part of the make dist routine. The README will get created inside of the repo, and if the file is already added to git, it'll show up in Github because it's generated prior to creating the tarball. It'll also have to be included in the MANIFEST.

      At least that's what I envisioned the desire to be.

        That means every time he want's to push his commits to GitHub he'll need to run make dist first?

        update

        I suppose it's possible to hook into git for that automation?

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

       But AFAIK is makefile.pl only relevant when installing from CPAN on the client side.

      AFAI-do, yes-and-no.

      Makefile is my friend and assistant: it runs for me tests, benchmarks and, like Discipulus wants to do: creates a readme from pod in various formats. This is in the tradition of Autotools/automake. In which just one last target (of many): make dist will create a tarball of the project for distributing it to end-users with all dev-related files filtered out. (btw I usually add make push-git to spare me the grory task of interacting with that abomination called git.)

      That means that, in this style, there are 2 makefiles, one for the developer and one for the end-user. The latter created automatically, so there is no need to maintain 2 makefiles actually. However, please correct me if I am wrong, but this is not the case with ExtUtils::MakeMaker which, as LanX points out, assumes or imposes that Makefile.PL is for the end-users' benefit only. Assuming that only *they* are the only lazy (or dumb or forgetfull) link in the project's development chain!

      Now, if there was a competition for the most lazy developer I would lose it because I would be too busy crafting an automated system for submitting my entry with just make submit && make win ...

      So, I claim back my right to laziness and chose to inflate Makefile.PL with targets that the end user will never want to use - (caveat: that entails the danger of exposing sensitive urls/passwords). Because I want to have a functional, development-stage, Makefile fit for my lazy lifestyle.

      10 minutes EDIT: See Re: let Makefile.PL to do the Readme file for me -- new target? for an alternative which involves other tools.

      bw, bliako

        Perhaps I am misunderstanding you, but what you have said sounds like a contradiction to me.

        You have mentioned the author-only targets (such as make dist) and these can be auto-generated by ExtUtils::MakeMaker but you subsequently say that this module "assumes or imposes that Makefile.PL is for the end-users' benefit only". That is clearly not the case.


        🦛

      When ExtUtils::MakeMaker is your authoring tool, you want to hook into it to perform any authoring task, which this would be one. Not necessarily related to make dist, but in the same vein. Personally, I prefer real authoring tools but for people who really like Makefile this is fine.
        Isn't it a scaffolding tool, providing me with the initial base dirs and files for a dist?

        Can I run it to change an already existing distribution?

        As I understood the OP he wants to automatically update README.pod with content from Module.pod (at least that's what I want to do)

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

Re: let Makefile.PL to do the Readme file for me -- new target?
by bliako (Prior) on Jan 20, 2021 at 12:01 UTC

    As pryrt said you can have many Makefile targets into the single postamble. I had similar worries asked here: Benchmarks target in Makefile. If you super-search for postamble you will find more.

    If you were developing in Linux you could benefit from Autotools (I guess win-gnu has it too). I know it's old and tired but this is what I use and sometimes I hit its limitations. The "pattern" I use is to create a dir for my project to contain a huge Autotools Makefile (skeleton). Inside that parent dir I create a dir called Perl. Therein lies the Perl code, tests, doc etc. and the simplest Makefile.PL. Autotools' Makefile will be responsible for entering the Perl dir, creating the doc, even spellchecking the docs!, running critic, running the dev-tests, dev-benchmarks, pushing to git and eventually creating the dist-tarball for CPAN from only Perl's subdir contents. To recap: create the simplest, client-side Makefile.PL and all the functionality is in the parent dir in Autotools' Makefile which can hold sensitive passwords without having to remove them before dist. Nothing of this goes to client-side. A template is easy to be created to re-use with other projects.

    Again, Autotools I feel is tired. The pattern I am suggesting of Parent-dir/Perl-dir may be a solution to limitations of Makefile.PL and the effort to keep it simple, just for client-side use. My proposal can be implemented with other auto-tools. I would personally keep away from cmake and all the "modern" gradles, ants, mavens and whatnot. (warning: based on personal experience and bitter taste rather than any sensible arguments, sorry.).

    Although the point Anonymous Monk makes (++) that "Make syntax isnt portable." is valid.

    bw, bliako

Re: let Makefile.PL to do the Readme file for me -- new target?
by Anonymous Monk on Jan 20, 2021 at 03:35 UTC
    Make syntax isnt portable.
      Make syntax isnt portable.

      I don't buy this argument. About 88% of the currently over 39k distributions in my (up-to-date) CPAN::Mini contain a Makefile.PL.

      Update: To clarify: I'm not saying Makefiles are necessarily portable. The point is the solutions to the OP can be implemented in a portable way, but the way the above statement is worded makes it seem like they can't. That's the problem with a four-word post; perhaps clarification would have been useful.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11127103]
Approved by stevieb
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2021-02-25 08:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?