# vim:tw=72:
use strict;
use warnings;
package CPAN::API::BuildPL;
# ABSTRACT: Documentation of the API for using Build.PL

our $VERSION = '0.002'; # VERSION

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

CPAN::API::BuildPL - Documentation of the API for using Build.PL

=head1 VERSION

version 0.002

=head1 DESCRIPTION

B<THIS DOCUMENT IS STILL A ROUGH DRAFT>

This documentation describes an API for how a Build.PL file in a Perl
distribution may be used to build and install the distribution.  This is
primarily of interest to CPAN clients like L<CPAN>, L<CPANPLUS> and
L<cpanm>.

While Build.PL originated with L<Module::Build>, there is no reason that
alternative pure-Perl build systems can't use the same mechanism.  With
the C<<< configure_requires >>> key in distribution META files supported in the
Perl core since version 5.10.1, it will be increasingly easy over time
for other pure-Perl build system to flourish.

The terms B<must>, B<should>, B<may> and their negations have the usual
IETF semantics.

The API described herein is a minimal feature sufficient for basic
interoperability between a CPAN client and a pure-Perl build system to
build, test and install Perl distributions.  Any build system B<must>
provide all of the features. The build system B<may> provide additional
features, but CPAN clients B<should not> rely on them.

Portions of this document have been copied or adapted from the
documentation of L<Module::Build> (copyright Ken Williams).

=head1 USAGE

=head2 Build.PL program

   perl Build.PL [options]

=over

=item *

B<must> generate a Build file if configuration is successful

=item *

B<must> exit with exit code of zero if configuration is successful

=item *

B<must> not generate a Build file if configuration fails

=item *

B<may> exit with a zero or non-zero exit code; clients B<may> interpret
a zero exit code with no Build file produced as a request to abort
further action without signaling error to the user

=item *

B<must> generate at least one MYMETA file following a version of the
CPAN::Meta::Spec

=item *

B<may> print warnings about unsatisfied prerequisties to STDOUT

=item *

B<must> accept user configuration as described in this document

=item *

B<must> cache user configuration for later use by 'Build'

=back

=head2 Build program

   ./Build [command] [options]

=over

=item *

B<must> carry out a 'build' action if no command is specified

=item *

B<must> use the same perl executable that was used to run Build.PL

=item *

B<should not> preserve @INC from Build.PL

=back

A list of actions that B<must> be supported follows:

=head3 'build' action

=over

=item *

B<must> prepare the distribution for the test and install actions

=item *

B<must> exit with 0 if the distribution is considered ready for
testingE<sol>installation

=item *

B<must> exit with a non-zero code if the distribution is not ready
for testingE<sol>installation

=back

Historically, this means compiling, copying files to blib, etc.
and many existing tools may expect to find things in blib.  This is
not necessarily the right way to do thing forever and ever.

=head3 'test' action

(Add purpose statement?)

=over

=item *

B<must> exit with 0 if the distribution is considered install-ready

=item *

B<must> exit with a non-zero code if the distribution is not ready to
install

=item *

B<should> produce a human-readable result to STDOUT

=item *

B<may> run the 'build' action

=item *

B<may> consider having no tests to be a successful result

=back

=head3 'install' action

=over

=item *

B<must> exit with 0 if the distribution was installed successfully

=item *

B<must> exit with a non-zero code if the distribution was not installed
successfully

=item *

B<must> install to the paths defined in other sections of this document

=item *

B<should> not modify paths not defined in other sections of this
document

=item *

B<should> preserve the prior state of the system if installation is
unsuccessful

=item *

B<must not> require the test action to have been run

=back

=head3 'clean' action

=over

=item *

B<must> exit with 0 if ran successfully, or non-zero if not

=item *

B<should> remove all files generated by the build tool after the
configuration (e.g. blib)

=item *

B<should not> create any files in the cleanup process

=back

=head3 'realclean' action

=over

=item *

B<must> exit with 0 if ran successfully, or non-zero if not.

=item *

B<must> remove all files removed by the 'clean' action

=item *

B<must> additionally remove all files generated during configuration,
including but not limited to the CE<lt>BuildE<gt> script and the MYMETA files

=item *

B<should not> create any files in the cleanup process

=back

=head1 CONFIGURATION

(blah blah configuration blah blah)

During execution of Build.PL or Build, options should have the following
precedence (from high to low):

=over

=item *

C<<< @ARGV >>>

=item *

C<<< $ENV{PERL_MB_OPT} >>>

=item *

cached configuration from Build.PL (only when running Build)

=back

Conceptually, options should be split on white space and then spliced
together, with higher-precedence options following lower-precedence
options.  Options should then be processed "in order".

=head2 Command Line Options

All command line arguments are accepted on action, even if they
only affect one action.

=over

=item *

--destdir E<lt>dirE<gt>

=back

   This sets the destdir as described in L</INSTALL PATHS>

=over

=item *

--installdirs E<lt>typeE<gt>

=back

   <type> must be one of C<site>, C<vendor> or C<core> as described in L</INSTALL PATHS>

=over

=item *

--install_base E<lt>dirE<gt>

=back

   This sets the install_base as described in L</INSTALL PATHS>

=over

=item *

--install_path E<lt>typeE<gt>=E<lt>dirE<gt>

=back

   This sets the install_path for a type as described in L</INSTALL PATHS>

=over

=item *

--uninst

=back

   If enabled this will cause old versions of the module to be
   uninstalled when the new version is installed.

=over

=item *

--verbose

=back

   This instructs the build tool it should output additional information
   on what it's doing

=head2 Environment variables

=over

=item *

PERL_MB_OPT -- provides option as if they were specified on the command
line to Build.PL or any Build action, but with precedence lower than
actual command line options .  The string B<must> be split on whitespace
as the shell would and the result prepended to any actual command-line
arguments in C<<< @ARGV >>>

=back

=head1 INSTALL PATHS

When you invoke C<Build>, it needs to figure
out where to install things.  The nutshell version of how this works
is that default installation locations are determined from
F<Config.pm>, and they may be overridden by using the C<install_path>
parameter.  An C<install_base> parameter lets you specify an
alternative installation root like F</home/foo>, and a C<destdir> lets
you specify a temporary installation directory like F</tmp/install> in
case you want to create bundled-up installable packages.

A build system *must* provide default installation locations for
the following types of installable items:

=over 4

=item lib

Usually pure-Perl module files ending in F<.pm>.

=item arch

"Architecture-dependent" module files, usually produced by compiling
XS, L<Inline>, or similar code.

=item script

Programs written in pure Perl.  In order to improve reuse, try to make
these as small as possible - put the code into modules whenever
possible.

=item bin

"Architecture-dependent" executable programs, i.e. compiled C code or
something.  Pretty rare to see this in a perl distribution, but it
happens.

=item bindoc

Documentation for the stuff in C<script> and C<bin>.  Usually
generated from the POD in those files.  Under Unix, these are manual
pages belonging to the 'man1' category.

=item libdoc

Documentation for the stuff in C<lib> and C<arch>.  This is usually
generated from the POD in F<.pm> files.  Under Unix, these are manual
pages belonging to the 'man3' category.

=item binhtml

This is the same as C<bindoc> above, but applies to HTML documents.

=item libhtml

This is the same as C<bindoc> above, but applies to HTML documents.

=back

Five other parameters let you control various aspects of how
installation paths are determined:

=over 4

=item installdirs

The default destinations for these installable things come from
entries in your system's C<Config.pm>.  You can select from three
different sets of default locations by setting the C<installdirs>
parameter as follows:

                          'installdirs' set to:
                   core          site                vendor

              uses the following defaults from Config.pm:

  lib     => installprivlib  installsitelib      installvendorlib
  arch    => installarchlib  installsitearch     installvendorarch
  script  => installscript   installsitescript   installvendorscript
  bin     => installbin      installsitebin      installvendorbin
  bindoc  => installman1dir  installsiteman1dir  installvendorman1dir
  libdoc  => installman3dir  installsiteman3dir  installvendorman3dir
  binhtml => installhtml1dir installsitehtml1dir installvendorhtml1dir [*]
  libhtml => installhtml3dir installsitehtml3dir installvendorhtml3dir [*]

  * Under some OS (eg. MSWin32) the destination for HTML documents is
    determined by the C<Config.pm> entry C<installhtmldir>.

The default value of C<installdirs> is "site".  If you're creating
vendor distributions of module packages, you may want to do something
like this:

  perl Build.PL --installdirs vendor

or

  ./Build install --installdirs vendor

If you're installing an updated version of a module that was included
with perl itself (i.e. a "core module"), then you may set
C<installdirs> to "core" to overwrite the module in its present
location.

=item install_path

Once the defaults have been set, you can override them.

On the command line, that would look like this:

  perl Build.PL --install_path lib=/foo/lib --install_path arch=/foo/lib/arch

or this:

  ./Build install --install_path lib=/foo/lib --install_path arch=/foo/lib/arch

=item install_base

You can also set the whole bunch of installation paths by supplying the
C<install_base> parameter to point to a directory on your system.  For
instance, if you set C<install_base> to "/home/ken" on a Linux
system, you'll install as follows:

  lib     => /home/ken/lib/perl5
  arch    => /home/ken/lib/perl5/i386-linux
  script  => /home/ken/bin
  bin     => /home/ken/bin
  bindoc  => /home/ken/man/man1
  libdoc  => /home/ken/man/man3
  binhtml => /home/ken/html
  libhtml => /home/ken/html

=item destdir

If you want to install everything into a temporary directory first
(for instance, if you want to create a directory tree that a package
manager like C<rpm> or C<dpkg> could create a package from), you can
use the C<destdir> parameter:

  perl Build.PL --destdir /tmp/foo

or

  ./Build install --destdir /tmp/foo

This will effectively install to "/tmp/foo/$sitelib",
"/tmp/foo/$sitearch", and the like, except that it will use
C<File::Spec> to make the pathnames work correctly on whatever
platform you're installing on.

=item prefix

An implementation *may* implement this option for compatibility with
ExtUtils::MakeMaker's PREFIX argument. If implemented it *must* behave
the same as ExtUtils::MakeMaker 6.30 would given the PREFIX argument. In
other words, the following examples must be equivalent.

 perl Build.PL --prefix /tmp/foo
 perl Makefile.PL PREFIX=/tmp/foo

If an implementation opts not implement prefix, it *must* give a
descriptive error at the earliest possible time if a user tries to use
it.

=back

=head1 SEE ALSO

=over

=item *

L<CPAN>

=item *

L<CPANPLUS>

=item *

L<cpanm>

=item *

L<Module::Build>

=item *

L<Acme::Module::Build::Tiny>

=back

=head1 AUTHOR

David Golden <dagolden@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2023 by David Golden.

This is free software, licensed under:

  The Apache License, Version 2.0, January 2004

=cut
