Table of Contents
Most extensions to configure.pl can be
localized to the JugglerConfigure.pm module file.
That module contains the configuration file parsing code and two data
structures (JugglerModule and
ModuleDependency) for managing the data that is
parsed. In configure.pl, most of the code relates
to execution of the configure scripts in the individual modules. This
includes running the configuration scripts to configure a build tree and
running them to collect, reformat, and output usage information (the
output normally printed from passing --help). In this
chapter, we examine both files separately and explain how to extend
them.
This file contains three Perl packages:
JugglerConfigure, JugglerModule,
and ModuleDependency. The first has a single
procedure, parseConfigFile(), that parses the
user-specified configuration
(juggler.cfg in most cases). The latter two define data structures
(Perl classes) used to manage individual modules defined in the
configuration file and the dependencies of each module. We will
discuss each package in turn.
As stated above, this package contains a single subroutine:
parseConfigFile(). This parses a user-specified
configuration file in the format described in the section called “Build Configuration File”. If the config file is parsed
correctly, a hash named %MODULES is returned to
the caller. This hash, indexed by module name, provides references
to JugglerModule instances.
The parsing code is fairly straightforward. There are only three keywords in the configuration file format: module, depend, and Default. The basic concepts used in the format are similar to those for the C grammar. In other words, curly braces denote blocks, semi-colons denote the end of a declaration, and all code is case-sensitive. The following provides the grammar for the configuration file:
DOCUMENT ::= COMMENT DEFAULT MODULE
DEFAULT ::= 'Default:' NAME | ε
MODULE ::= NAME '{' COMMENT DEPENDENCY '}' COMMENT MODULE | ε
NAME ::= ([A-Za-z0-9_][A-Za-z0-9_]* + λ)[A-Za-z0-9_]
DEPENDENCY ::= DIR ';' DEPENDENCY | MODDEP ';' DEPENDENCY | ε
DIR ::= <valid-path> | <valid-path> ':' ENVVAR
ENVVAR ::= NAME '=' <text> | NAME '=' <text> ',' ENVVAR
MODDEP ::= 'depend' NAME
COMMENT ::= '#' <text> | '//' <text> | '/*' <text> '*/' | εThe structure of this grammar should be reflected in the parsing code. Differences between strict regular expressions (used above, more or less) and Perl regular expressions may muddy the correlation.
The JugglerModule package defines a class
containing two “data members”: name
and deps. These are actually keys of the blessed
hash returned by the new() subroutine. The
name member is just a string that contains the
unique name of the module. The deps member is
more interesting. Indeed, the main purpose of the
JugglerModule package is to maintain the list of
dependencies.
The deps member is a reference to an array
of ModuleDependency objects (see the section called “ModuleDependency”). An array is used to
preserve the ordering read from the configuration file. All
dependencies given in the configuration file appear in the array.
This includes those “inherited” from another module
through the use of the depend keyword.
Duplication of dependencies is avoided by performing a check
whenever a new dependency is added using
addDependency(). The
hasDependency() method encapsulates the
process of making the check. The dependencies of two modules can be
merged using the addDependencies()
method.
The ModuleDependency package defines a
class containing two “data members”:
path and env. The first is a
simple string, and the second is a reference to a hash where the
keys are environment variable names. The values for these are
extracted from the DIR rule in the above grammar.
More specifically, the terminal <valid-path> in
DIR rule corresponds to the path member, and the
ENVVAR rule defines the hash of environment
variable mappings.
Access to a given JugglerModule
object's dependencies happens entirely through the API of that
class. This class is provided as a convenient abstraction around the
information provided through each DIR parser rule
expansion.