The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Slay::Makefile - Wrapper to Slay::Maker that reads the rules from a file

DESCRIPTION

Slay::Maker is a make engine that uses perl declaration syntax for rules, including regular expressions for targets and anonymous subs for targets, dependencies, and actions. This Slay::Makefile wrapper allows for the rules to be contained within a SlayMakefile file whose syntax is similar to that of a normal Makefile.

FILE SYNTAX

The file syntax is a series of statements where each statement is one of:

   <perl-block>

   <target(s)> : <dependencies>
           <actions>

   [-] include <filename>

   # Comment

<perl-block> has the syntax:

   {
       <perl-statement(s)>
   }

where <perl-statement(s)> is any series of perl statements.

<target(s>) is either a space-delimited set of targets, each of which is either a literal string or a <perl-block> which returns an array, each of which is either a literal string or a regular expression ('Regexp') reference (qr/.../). A literal string can contain a % character to act as a wild-card, just as with GNU make. However, the Regexp feature is more general, since it can capture more than one substring and use the values $!, $2, ... inside the dependencies. Note that only one target can realistically contain wildcards, whether in a Regexp or using %, since there is only one set of $1, $2, ... variables.

The colon separating a <perl-block> for <target(s)> must be on the same line as the closing brace of the <perl-block>.

<dependencies> is either a space-delimited set of dependency strings or a <perl-block> which returns an array of dependencies (or a combination). The dependency string can contain $1, $2, ..., or %, which is synonymous with $1 and ${TARGET}, which gets the target name. They can also use any scalar global variables previously defined in a <perl-block>. A dependency <perl-block> is called with the values ($make, $target, $matches), where $make is a Slay::Maker object, $target is the target name, and $matches is a reference to an array containing the captured values from that target's Regexp (if any).

The colon separating a <perl-block> for <dependencies> must be on the same line as the opening brace of the <perl-block>.

<actions> is a series of zero or more action "lines", where each action is either a string, which will be executed inside a shell, a perl anonymous array, which is executed without a shell (see IPC::Run), or a <perl-block>. For purposes of this discussion, a "line" continues as long as the lines of string action end with "\" or as long as a perl anonymous array or <perl-block> do not have their closing punctuation. A string action can use the strings $1, $2, ..., for the matches, $DEP0, $DEP1, ..., for the dependencies, and $TARGET, which represents the target being built. For make enthusiasts, $* can be used for $1. A string action can also use any scalar global variables previously defined in a <perl-block>. An action <perl-block> is called with the values ($make, $target, $deps, $matches), where $make is a Slay::Maker object, $target is the target name, $deps is a reference to the array of dependencies and $matches is a reference to an array containing the captured values from that target's Regexp (if any).

An include line includes the content of a file with <filename> as a SlayMakefile file. If there is no such file, Slay::Makefile tries to build it using rules that have already been presented. If there is no such rule, Slay::Makefile exits with an error unless there was a - before the "include".

The equivalent of make's defines are handled by setting perl global variables. Each main <perl-block> is executed in the order it appears in the file, but any <perl-block> that is part of a dependency or action is evaluated lazily, so that all the global variables will have been set. A main <perl-block> is called with the value ($makefile), where $makefile is the Slay::Makefile object, so that such code can, for example, recursively call the parse method.

Comments begin with a # and extend to the end of line.

Continuation lines can be specified by putting a backslash at the end of the previous line, provided however, that continuation lines are unnecessary (automatic) within a perl block or perl anonymous array. Although continuation lines in a perl dependency or action must begin with at least one space so a that the parser does not think a new rule is beginning, the minimum indentation is removed prior to evaluation so that HEREIS strings can be used.

METHODS

new([$options])

Class method. Creates a new Slay::Makefile object using the optional $options argument. It also process the following options out of $options:

  strict:      If 0, do not enforce strict checking on perl blocks
maker

Method. Returns the Slay::Maker object used by this Slay::Makefile object.

make (@targets)

Method. Calls the Slay::Maker object's make method to build the list of targets. If no targets are given, makes the targets of the first rule with constant targets.

parse ($filename)

Method. Parses file $filename as a SlayMakefile and populates the Slay::Maker object with its rules. Returns a reference to an array of parse errors.

parse_string ($string, [$filename, [$lineno]])

Method. Parses $string as a SlayMakefile. If $filename and/or $lineno arguments are provided, they are used for more detailed error reporting. Returns a reference to an array of parse errors.

LIMITATIONS

The parsing of perl blocks is only semi-smart. In particular, unbalanced braces within comments or strings can cause parsing to end prematurely or not at all. For example,

  {
     # This comment has an unbalanced }
  }
  {
     "This string has an unbalanced {";
  }

will not parse correctly. The first block will stop parsing at the end of the comment and the second will continue swallowing text after the end of its closing brace. As long as the total number of {'s exceeds the total number lf }'s, parsing continues. You can always overcome this problem by putting comments in judicious places:

  {
     # Compensate with {
     # This comment has an unbalanced }
  }
  {
     "This string has an unbalanced {";  # Compensate with }
  }

ACKNOWLEDGEMENTS

I want to acknowledge Barrie Slaymaker, who wrote the original Slay::Maker module for CPAN and has been very kind in his support for developing this module.

COPYRIGHT & LICENSE

Copyright 2007 Mark Nodine, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.