# Copyright (C) 2004-2007, The Perl Foundation.
# $Id: configuration.pod 23427 2007-12-04 00:55:49Z jkeenan $
=pod
=head1 NAME
docs/configuration.pod - Parrot Configuration System
=head1 DESCRIPTION
Parrot configuration is broken up into I<steps>. Each step contains several
related I<prompts>, I<probes>, or I<generations>. Steps should be mostly of a
single type, though some overlap is allowed (for example, allowing a probe to
ask the user what to do in an exceptional situation).
The directory F<config> contains subdirectories for each type of step. Each
step should consist of I<exactly one> F<.pm> file and any number of supporting
F<.c>, F<.in>, etc. files. Any supporting files should be in a folder whose
name is the same as the basename of the step's F<.pm> file; for example, if
F<foo.pm> uses F<bar_c.in>, F<bar_c.in> should be in a directory called F<foo>;
the full path might be F<config/auto/foo/bar_c.in>.
Generally, when adding a new component to the configuration process you should
add a new step unless that component I<clearly> belongs in a current step. For
example, if you added a new user-configurable type called C<FOOVAL>, you would
add the code used to determine its size in F<config/auto/sizes.pm>. However,
if you were determining what dynaloading capabilities are available, you would
create a new step.
=head2 Initialization Steps
I<Initialization steps> are run before any other steps. They do tasks
such as preparing the configuration system's data structures and
checking the F<MANIFEST>. New initialization steps will only be added
when the configuration system is getting significant new capabilities.
They're kept in the directory F<config/init>.
=head2 Prompts
Prompts ask the user for some information. These should be used sparingly. A
step containing prompts is an I<interactive step>. Interactive steps should be
in the F<config/inter> folder.
Interactive steps often include simple probes to determine good guesses of what
the user will answer. See L</Prompt or Probe?> for more information.
Note that, by default, these prompts are turned off. To enable them run
F<Configure.pl> with the C<--ask> option.
=head2 Probes
Probes are automated tests of some feature of the computer. These should be
used wherever a value will not need to be modified often by the user. A step
containing probes is an I<automatic step>. Automatic steps should be in the
F<config/auto> folder.
=head2 Generations
Generations create files needed after configuration has completed, such as
Makefiles and configuration headers. A step containing generations is a
I<generation step>. Generation steps should be in the F<config/gen> folder.
Templates for files to be generated usually have the extension F<.in>. There
are variable substitutes and funny macros like 'CONDITIONED_LINE' and
'INVERSE_CONDITIONED_LINE'.
=head2 Prompt or Probe?
It can sometimes be hard to decide whether a given step should be an automatic
or an interactive step. The guiding question is I<Would a user ever want to
change this?>, or conversely, I<Is this something that can be completely
determined without user intervention?> A step figuring out what the compiler's
command is would probably be an interactive step; conversely, a step figuring
out if that command is connected to a specific compiler (like F<gcc>) would be an
automatic step.
=head2 Configuring Configuration
The configuration system gets its own configuration data from, and is invoked
via, the F<Configure.pl> script. The system is invoked by instantiating a
L<Parrot::Configure> object, registering one or more steps with that object,
and then calling C<Parrot::Configure::runsteps()>.
=head2 Adding New Steps
New steps should be added in one of the four folders mentioned above.
All steps are really classes; each exists in a unique namespace. The
namespace used depends on the step's relative path in the source tree sans the
F<config> prefix. For example, the step F<config/init/defaults.pm> uses the
C<init::defaults> namespace.
Each step inherits its constructor and some other methods from
F<lib/Parrot/Configure/Step/Base.pm>. Each step needs to define only
two methods: C<_init()> and C<runstep()>.
The C<_init()> method should follow the following example, defining three
elements within an internal hash:
sub _init {
my $self = shift;
my %data;
$data{description} = q{This is the step description};
$data{args} = [ qw( optional arguments ) ];
$data{result} = q{};
return \%data;
}
=over 4
=item C<description>
Of these three elements, C<description> is the most important as it is
used extensively within C<lib/Parrot/Configure.pm>.
Returns a short descriptive message that should be printed before the step
executes. Usually, interactive steps have long, friendly descriptions and
other steps have terse descriptions ending in "...".
Some example descriptions:
=over 4
=item F<config/auto/cgoto.pm>
Determining if your compiler supports computed goto...
=item F<gen/config_h.pm>
Generating config.h...
=back
Note that on non-interactive steps, the text I<done> will be printed after the
description when the step finishes executing; for example, the user will see:
Determining if your compiler supports computed goto...done.
=item C<args>
Returns a list of the names of any command-line arguments the step cares about.
Command-line arguments are standardized in F<Configure.pl>; this will be
described L<later|/"Command-line Arguments"> in more detail.
I<XXX> Note that this method is currently unused but will be used in the futher
to register acceptable CLI parameters. New steps should continue to define
this method.
=item C<result>
The C<result> is initialized to an empty string mainly to quiet
'uninitialized variable' warnings. Most configuration steps override
the C<result> value inside their C<runstep()> method.
=item L<_run_this_step>
This method is called to actually execute the step. The return
value should be C<1> if the step accomplishes what it is intended to do.
Otherwise, the step should simply C<return>, I<i.e.>, return an
undefined value.
I<XXX> In the near future there will be a means of passing additional parameters.
=back
The configuration system won't execute your step by default unless it's
specifically told to. To do this, edit F<lib/Parrot/Configure/Step/List.pm>.
Steps are run in the order in which that are registered with the
L<Parrot::Configure> object.
Various utility functions for configuration steps are provided by the
L<Parrot::Configure::Step> module.
A template for a new step might look like this:
package auto::newstep;
use strict;
use warnings;
use vars qw($description $result @args);
use base qw(Parrot::Configure::Step::Base);
use Parrot::Configure::Step;
sub _init {
my $self = shift;
my %data;
$data{description} = q{This is the step description};
$data{args} = [ qw( optional arguments ) ];
$data{result} = q{};
return \%data;
}
sub runstep {
my ($self, $conf) = @_
...
if ($success) {
$self->set_result('yes');
return 1;
} else {
$self->set_result('no');
return;
}
}
The step's C<runstep()> method should return C<1> upon success and do a
bare return on failure (thereby returning an undefined value).
=head2 Command-line Arguments
Command-line arguments look like C</--[-\w]+(=.*)?/>; the equals sign separates
the name and the value. If the value is omitted, it's assumed to be 1. The
options C<--help> and C<--version> are built in to Configure; any others are
defined by steps.
Command-line arguments are now processed by C<process_options()>, a subroutine
exported by L<Parrot::Configure::Options>. If you add a new option, don't
forget to add it to this documentation and to two locations in
F<lib/Parrot/Configure/Options.pm>:
=over 4
=item *
the list of valid command-line arguments in
C<Parrot::Configure::Options::get_valid_options()>; and
=item *
the description of command-line arguments found in
C<Parrot::Configure::Options::print_help()>.
=back
Arguments passed to F<Configure.pl> are held in a L<Parrot::Configure::Data>
object stored inside the L<Parrot::Configure> object. The options data object
may be accessed via the L<Parrot::Configure/options> method.
Steps use the C<args> method to list any options they're interested in. They
should be listed without the dashes.
=head2 Building Up Configuration Data
The second step is F<config/init/defaults.pm>, which sets up some defaults in a
L<Parrot::Configure::Data> object contained by the main L<Parrot::Configure>
object. It can be accessed via the L<Parrot::Configure/data>method. You get
and set configuration system's data by interacting with this object. Some of
its methods are summarized below.
=over 4
=item C<get(keys)>
Returns the values for the given keys.
=item C<set(key, value, [key, value, ...])>
Sets the given keys to the given values.
=item C<add(delim, key, value, [key, value, ...])>
Sets the given keys to the given values or appends values delimited by I<delim>
to existing keys.
=item C<keys()>
Returns a list of all keys.
=item C<dump()>
Returns a string that can be C<eval>ed by Perl to create a hash representing
the configuration system's data.
See the L<Parrot::Configure::Data> documentation for further details.
=back
=head2 Special Configuration Items
Some configuration items, by convention, have a special meaning (mainly
prefixes) and are handled with some magic internally.
=over 4
=item C<i_(\w+)> include files
defines or undefs PARROT_HAS_HEADER_XXX in F<include/parrot/has_header.h>
=item C<HAS_(\w+)> features
defines PARROT_HAS_XXX in F<include/parrot/has_header.h>
=item C<TEMP_(\w+)> temporary settings
These settings are deleted before F<lib/Parrot/Config.pm> is written. These
entries are only used e.g. for Makefile creation.
=back
=head2 Accessing Configuration Information via Perl 5 Variables
Parrot configuration is currently jump-started by extracting
considerable information from variables associated with the instance of
Perl 5 which the user is using to run F<Configure.pl>. These variables
are largely looked up in the C<%Config> found in the Perl 5
F<Config.pm>, but may also be sought in Perl 5 special variables such as
C<$^O>. All such lookups should be done in configuration step
C<init::defaults> and B<only> in that step. Special accessors are
available for working with such variables; see
F<config/init/defaults.pm> and F<lib/Parrot/Configure/Data.pm>.
=head1 HISTORY
The Parrot configuration system was created by Brent Dax and has been heavily
mangled by Joshua Hoblitt.
=head1 SEE ALSO
L<Parrot::Configure>, L<Parrot::Configure::Data>,
L<Parrot::Configure::Step>, L<Parrot::Configure::Step::Base>
=cut
syntax highlighted by Code2HTML, v. 0.9.1