NAME
Mpp::CommandParser - Base class for makepp command parsers
SYNOPSIS
use Mpp::CommandParser;
our @ISA = qw/Mpp::CommandParser/;
DESCRIPTION
Mpp::CommandParser
is a base class for makepp(1) command parsers. When used directly, it does nothing except add a dependency on the executable.
The parser for a particular command should derive from this class. The parser should instantiate objects of type Mpp::Scanner
for the language(s) of the files that it scans for include directives.
METHODS
new
my $parser=new Mpp::CommandParser($rule, $dir);
Returns a new Mpp::CommandParser
object for rule $rule. $dir is the directory (a string) in which the command runs. The derived class may override this method and its parameters.
parse_command
$parser->parse_command($command, $setenv_hash);
Splits the command into words, prints a log message, and calls xparse_command.
add_executable_dependency
Gets called before xparse_command with the first command word as the argument. By default, it adds a dependency on the file given by the word, but only if it contains no shell metacharacters. It then adds runtime dependencies, if any, and calls add_more_executable_dependencies (which the subclass can override) with the directory name of the executable.
input_filename_regexp
$parser->input_filename_regexp($command[0], [qw(.c .C .cpp .cc .c++)]);
Returns a regular expression against which arguments will match if they look like ordinary (positional) input files. This is the common way to pick up custom file suffixes from register_input_suffix statements.
xparse_command
$parser->xparse_command($command_array, $setenv_hash);
The derived class should override this to set the default signature method, to parse the $command_array command and to add the implicit targets and dependencies to $self->rule. $setenv_hash is a hashref indicating the command-line environment settings. (Whether its values have shell variables expanded is not yet guaranteed.)
The current plan is that a new object of this class is created for each command, but that might change in the future. If it does, then this method is responsible for clearing previous command information, such as the include paths.
A TRUE return value indicates that some meaningful scanner was successfully employed. An undefined return value is interpreted as a failure. A failure forces the rule to propagate failure status, without attempting to build the target.
rule
my $rule=$parser->rule;
Returns the rule.
dir
my $dir=$parser->dir;
Returns the directory Mpp::File object.
add_dependency
add_optional_dependency
add_simple_dependency
add_target
add_env_dependency
$parser->add_dependency($name);
$parser->add_dependency($finfo, $tag, $src, $incname);
$parser->add_optional_dependency($name, $simple);
$parser->add_simple_dependency($name);
$parser->add_simple_dependency($finfo, $tag, $src, $incname);
$parser->add_target($name);
$parser->add_env_dependency($name);
Add a dependency or target on file $name relative to $self->dir. Returns the Mpp::File object.
The 5-arg versions add a dependency on $finfo, and record the dependency based on $tag, $src, and $incname. $finfo can be undefined, indicating that the file was sought but not found. The 1-arg versions add a dependency on $name (relative to $parser->dirinfo), and record the dependency based on undef, undef, and $name relative to $parser->rule->build_cwd. The 1-arg version of add_dependency is guaranteed either to return a successfully built Mpp::File object (possibly nonexistent if it was phony or marked for don't build, etc.) or to die.
add_dependency adds a "meta" dependency (a dependency on which the rule's dependencies might depend), and causes the dependency to be built before returning. If the dependency file was found but couldn't be built, then it dies with "SCAN_FAILED\n". If the dependency wasn't found, then it returns 1.
add_optional_dependency is just like add_dependency, except that no error occurs if the file does not exists and cannot be built. This is useful for adding dependencies on optional initialization files, because the target becomes outdated should the file come into existence. If you pass it a second TRUE argument, then it adds a simple optional dependency instead of a meta dependency.
add_simple_dependency adds a simple dependency, and does not attempt to build the dependency if it doesn't exist.
Even if no actual file dependency is added, calls to add_dependency and add_simple_dependency are recorded for the purposes of caching scanner info, in case the file becomes buildable in subsequent makepp runs.
add_env_dependency adds a dependency on the value of the named environment variable. If $name is of the form /(.+) in (\S+)/, then $1 is a filename to seek in directories given by the value of the environment variable named by $2, split on colons. The rule is then dependent on the name of the first directory in which the file is found or can be built. (This is useful for avoiding rebuilds when a search path changed without affecting where files are found along the search path.)
BUGS
There is no variant of the add_dependency method that doesn't add a dependency if the file doesn't exist and can't be built. (For example, an optional configuration file.) This would be easy to implement, but there aren't any scanners that would use it right now.
FUTURE WORK
Dependencies on the environment should also be captured by xparse_command. I don't know if there is a way to do this at all yet, but in principle it could be added. The $setenv_hash parameter can be used to avoid adding dependencies on variables that are set earlier in the action. For search paths picked up from the environment, it would be a lot more efficient to capture dependencies in the form "rebuild unless file X is picked up from directory Y," rather than "rebuild if the path changed." Also, if we could avoid rebuilding if the file is picked up from a different location but has the same MD5, then that would be cool.
Perhaps there should be a finfo method that just returns file_info($_[0], $self->dirinfo).