Picture me begging for elucidation and an example? Thus far I've tried adding a postamble...
Certainly! I'll refer to areas in the Makefile.PL for the current version of my RPC::XML package, so you can follow along at home :-).
First off, what did your postamble() return, and in what form? The overridable methods are expected to return a single string, which MM writes out to the Makefile-in-progress. Take a look at MY::postamble in my example (it's the last subroutine definition in that file). It does a great deal of work-- it creates a specfile for RPM packaging, as well as a macro file and faux-rcfile for rpm itself to use. When it has done all of that, the routine creates an array of lines in the variable @text like so:
# Create the rules that create RPM and SRPM files push(@text, qq{ rpm: \$(SPECFILE) \$(DISTVNAME).tar\$(SUFFIX) \t\$(RPM) -bb --clean --rcfile rpmrc \$(SPECFILE) srpm: \$(SPECFILE) \$(DISTVNAME).tar\$(SUFFIX) \t\$(RPM) -bs --clean --rcfile rpmrc \$(SPECFILE) }); # Create the dependancy rules for the methods/XPL files for (sort grep(/\.xpl$/, keys %::PM_FILES)) { s/\.xpl$//; push(@text, "$_.xpl: $_.base $_.help $_.code"); } join("\n", @text);
Amidst all the funky quoting there, what that is doing is pushing plain ol' make syntax for two new rules: rpm and srpm. Right after that, it iterates over a list that was defined earlier, and adds some dependancy rules so that a change to A.code triggers a rebuild of A.xpl. What matters is the last line I provide up there: the join(). That's the last statement of the subroutine, and the result from it is the return value of the sub. In this case, it takes all of @lines and joins them together with line-break characters. The resulting code in the Makefile looks a little like this:
rpm: $(SPECFILE) $(DISTVNAME).tar$(SUFFIX) $(RPM) -bb --clean --rcfile rpmrc $(SPECFILE) srpm: $(SPECFILE) $(DISTVNAME).tar$(SUFFIX) $(RPM) -bs --clean --rcfile rpmrc $(SPECFILE)
(I didn't include the dependancy rules because they have lengthy, ugly relative paths and wrap around a lot.)
So, how would you apply this to your problem? Push onto @lines text that will add copying of the files to the "install" rule. Do you know where you want them to go? Is it a location relative to where the modules themselves go? Maybe you want to define a Makefile variable for the destination, so that you can override it on the command-line if needed. So we'll write two new methods: one for postamble, and one for post_constants. The method post_constants gets called after MM has written all of its internal constants, so it's the ideal place for you to write yours. Let's say that you want to use the existing INSTALLSITELIB value (which is /usr/lib/perl5/5.6.0 on my Red Hat 7.2 box), but with a "/db" appended to it, as the place for your DB files. Then your library can use the Config module to build the pathname. It will look kind of like this:
sub MY::post_constants { # With this, you can override INSTALLSITELIB when # you call WriteMakefile, or when you run make. # You can also override INSTALL_DB_FILE when you # run make. Assume you've set @list_of_db_files join("\n", 'INSTALL_DB_FILES=\$(INSTALLSITELIB)/db', "DB_FILES=@list_of_db_files"); } sub MY::postamble { my $self = shift; my @text; push(@text, 'install:: install.dbfiles', '', 'install.dbfiles:: $(DB_FILES)', "\t\$(MKPATH) \$(INSTALL_DB_FILES)", "\t\$(CP) \$(DB_FILES) \$(INSTALL_DB_FILES)"); join("\n", @text); }
Some notes on this example: you don't have to first define a target like "install.dbfiles" for "install", then put all the extra stuff under the new target. That's just a matter of taste and good planning. This approach means you can run "make install.dbfiles" by itself, to make sure it is installing where you expect it to (or run make with "-n" to at least sanity-check it). Secondly, instead of pasting in INSTALLSITELIB directly, I reference it as a make variable. Now INSTALL_DB_FILES is a direct function of that path, unless you explicitly provide it on the command-line to make. And if you change INSTALLSITELIB either on the command-line or in the call to WriteMakefile(), everything still stays in place. Third, instead of calling cp or mkdir, I use constructs that MM provides that are more portable, and more likely to work across platforms. Lastly, MM provides the trailing newlines, so you don't have to feed join() an extra null string to force a final newline.
I hope this helps. I wrote an early article on MakeMaker for the Perl Journal. It's now archived by the publishers of SysAdmin magazine. If I ever get enough round tuits to spare, I may consider writing a follow-up, to cover more advanced features.
--rjray
In reply to Re: Re: Re: MakeMaker Hacking?
by rjray
in thread MakeMaker Hacking?
by hsmyers
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |