# Copyright (C) 2004-2006, The Perl Foundation.
# $Id: configuration.pod 16023 2006-12-06 16:56:50Z bernhard $

=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 test you should add a new step unless a test
I<clearly> belongs in a current step. For example, if we added a new
user-configurable type called C<FOOVAL>, you should add the test for its size
in F<config/auto/sizes.pm>; however, if you were testing what dynaloading
capabilities are available, you should 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>. These will rarely be added; when they are, it usually means that
the configuration system is getting significant new capabilities. They're kept
in the directory F<config/init>.

Initialization steps usually do not output anything under normal circumstances.

=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.

Interactive steps virtually always output something.

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 often need to be modified by the user.  A step
containing probes is an I<automatic step>. Automatic steps should be in the
F<config/auto> folder.

Automatic steps usually do not output anything under normal circumstances.

=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.

Generation steps usually do not output anything under normal circumstances.

Templates for to be generated files usually have the extension '.in'.  There is
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 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 its L<Parrot::Configure/runsteps> method.

=head2 Adding New Steps

New steps should be added in one of the three folders mentioned above.

All steps are really classes; they each exist in a unique namespace.  The
namespace used depends on the tests relative path in the source tree minus sans
the F<config> prefix.  For example, the step F<config/init/defaults.pm> uses
the C<init::defaults> namespace.

They should define the following methods:

=over 4

=item C<description>

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/inter/progs.pm>

    Okay, I'm going to start by asking you a couple questions about your
    compiler and linker. Default values are in square brackets; you can
    hit ENTER to accept them. If you don't understand a question, the
    default will usually work--they've been intuited from your Perl 5
    configuration.

=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 L<runstep>

This method is called to actually execute the step.  The global
L<Parrot::Configure> is passed is as the first parameter.  The return value is
undefined.

I<XXX> In the near future the return value of this method will be signifigant
and 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 the F<Configure.pl> files.  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;

    $description = '<description>';
    @args = qw(<args>);

    sub runstep {
        my ($self, $conf) = @_
        ...
    }

=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.

If you add a new option, don't forget to add it to this documentation and the
C<--help> listing in F<Configure.pl>.

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

=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

