NAME¶
ExtUtils::AutoInstall - Automatic install of dependencies via CPAN
VERSION¶
This document describes version 0.63 of
ExtUtils::AutoInstall, released
September 12, 2005.
SYNOPSIS¶
In
Makefile.PL, with Module::Install available on the author's system:
use inc::Module::Install;
name ('Joe-Hacker');
abstract ('Perl Interface to Joe Hacker');
author ('Joe Hacker <joe@hacker.org>');
include ('ExtUtils::AutoInstall');
requires ('Module0'); # mandatory modules
features (
-config => {
make_args => '--hello', # option(s) for CPAN::Config
force => 1, # pseudo-option to force install
do_once => 1, # skip previously failed modules
},
'Feature1' => [
'Module2' => '0.1',
],
'Feature2' => [
'Module3' => '1.0',
],
);
auto_install();
&WriteAll;
Invoking the resulting
Makefile.PL:
% perl Makefile.PL # interactive behaviour
% perl Makefile.PL --defaultdeps # accept default value on prompts
% perl Makefile.PL --checkdeps # check only, no Makefile produced
% perl Makefile.PL --skipdeps # ignores all dependencies
% perl Makefile.PL --testonly # don't write installation targets
Note that the trailing 'deps' of arguments may be omitted, too.
Using "--defaultdeps" will make
Makefile.PL behave similarly to
a regular Makefile.PL file with "PREREQ_PM" dependencies.
One can use environment variables (see "ENVIRONMENT") below to set a
default behavior instead of specifying it in the command line for every
invocation of
Makefile.PL.
Using
make (or
nmake):
% make [all|test|install] # install dependencies first
% make checkdeps # same as the --checkdeps above
% make installdeps # install dependencies only
DESCRIPTION¶
ExtUtils::AutoInstall lets module writers to specify a more sophisticated
form of dependency information than the "PREREQ_PM" option offered
by
ExtUtils::MakeMaker.
This module works best with the
Module::Install framework, a drop-in
replacement for MakeMaker. However, this module also supports
Makefile.PL files based on MakeMaker; see "EXAMPLES" for
instructions.
Prerequisites and Features¶
Prerequisites are grouped into
features, and the user could choose yes/no
on each one's dependencies; the module writer may also supply a boolean value
via "-default" to specify the default choice.
The
Core Features marked by the name "-core" will double-check
with the user, if the user chooses not to install the mandatory modules. This
differs from the pre-0.26 'silent install' behaviour.
Starting from version 0.27, if "-core" is set to the string
"all" (case-insensitive), every feature will be considered
mandatory.
The dependencies are expressed as pairs of "Module" =>
"version" inside an array reference. If the order does not matter,
and there are no "-default", "-tests" or
"-skiptests" directives for that feature, you may also use a hash
reference.
The Installation Process¶
Once
ExtUtils::AutoInstall has determined which module(s) are needed, it
checks whether it's running under the
CPAN shell and should therefore
let
CPAN handle the dependency.
Finally, the "WriteMakefile()" is overridden to perform some
additional checks, as well as skips tests associated with disabled features by
the "-tests" option.
The actual installation happens at the end of the "make config"
target; both "make test" and "make install" will trigger
the installation of required modules.
If it's not running under
CPAN, the installer will probe for an active
connection by trying to resolve the domain "cpan.org", and check for
the user's permission to use
CPAN. If all went well, a separate
CPAN instance is created to install the required modules.
If you have the
CPANPLUS package installed in your system, it is
preferred by default over
CPAN; it also accepts some extra options
(e.g. "-target => 'skiptest', -skiptest => 1" to skip
testing).
All modules scheduled to be installed will be deleted from %INC first, so
ExtUtils::MakeMaker will check the newly installed modules.
Additionally, you could use the "make installdeps" target to install
the modules, and the "make checkdeps" target to check dependencies
without actually installing them; the "perl Makefile.PL --checkdeps"
command has an equivalent effect.
If the
Makefile.PL itself needs to use an independent module (e.g.
Acme::KillarApp, v1.21 or greater), then use something like below:
BEGIN {
require ExtUtils::AutoInstall;
# the first argument is an arrayref of the -config flags
ExtUtils::AutoInstall->install([], 'Acme::KillerApp' => 1.21);
}
use Acme::KillerApp 1.21;
ExtUtils::AutoInstall->import(
# ... arguments as usual ...
);
Note the version test in the use clause; if you are so close to the cutting edge
that
Acme::KillerApp 1.20 is the latest version on CPAN, this will
prevent your module from going awry.
User-Defined Hooks¶
User-defined
pre-installation and
post-installation hooks are
available via "MY::preinstall" and "MY::postinstall"
subroutines, as shown below:
# pre-install handler; takes $module_name and $version
sub MY::preinstall { return 1; } # return false to skip install
# post-install handler; takes $module_name, $version, $success
sub MY::postinstall { return; } # the return value doesn't matter
Note that since
ExtUtils::AutoInstall performs installation at the time
of "use" (i.e. before perl parses the remainder of
Makefile.PL), you have to declare those two handlers
before the
"use" statement for them to take effect.
If the user did not choose to install a module or it already exists on the
system, neither of the handlers is invoked. Both handlers are invoked exactly
once for each module when installation is attempted.
"MY::preinstall" takes two arguments, $module_name and $version; if it
returns a false value, installation for that module will be skipped, and
"MY::postinstall" won't be called at all.
"MY::postinstall" takes three arguments, $module_name, $version and
$success. The last one denotes whether the installation succeeded or not: 1
means installation completed successfully, 0 means failure during install, and
"undef" means that the installation was not attempted at all,
possibly due to connection problems, or that module does not exist on CPAN at
all.
Customized "MY::postamble"¶
Starting from version 0.43,
ExtUtils::AutoInstall supports modules that
require a "MY::postamble" subroutine in their
Makefile.PL.
The user-defined "MY::postamble", if present, is responsible for
calling "ExtUtils::AutoInstall::postamble" and include the output in
its return value.
For example, the
DBD::* (database driver) modules for the Perl DBI are
required to include the postamble generated by the function
"dbd_postamble", so their
Makefile.PL may contain lines like
this:
sub MY::postamble {
return &ExtUtils::AutoInstall::postamble . &dbd_postamble;
}
Note that the
ExtUtils::AutoInstall module does not export the
"postamble" function, so the name should always be fully qualified.
CAVEATS¶
ExtUtils::AutoInstall will add "UNINST=1" to your
make
install flags if your effective uid is 0 (root), unless you explicitly
disable it by setting
CPAN's "make_install_arg" configuration
option (or the "makeflags" option of
CPANPLUS) to include
"UNINST=0". This
may cause dependency problems if you are
using a fine-tuned directory structure for your site. Please consult
"FAQ" in CPAN for an explanation in detail.
If either
version or
Sort::Versions is available, they will be
used to compare the required version with the existing module's version and
the CPAN module's. Otherwise it silently falls back to use
cmp. This
may cause inconsistent behaviours in pathetic situations.
NOTES¶
Since this module is needed before writing
Makefile, it makes little use
as a CPAN module; hence each distribution must include it in full. The only
alternative I'm aware of, namely prompting in
Makefile.PL to force user
install it (cf. the
Template Toolkit's dependency on
AppConfig)
is not very desirable either.
The current compromise is to add the bootstrap code listed in the
"SYNOPSIS" before every script, but that does not look pretty, and
will not work without an Internet connection.
Since we do not want all future options of
ExtUtils::AutoInstall to be
painfully detected manually like above, this module provides a
bootstrapping mechanism via the "-version" flag. If a newer
version is needed by the
Makefile.PL, it will go ahead to fetch a new
version, reload it into memory, and pass the arguments forward.
If you have any suggestions, please let me know. Thanks.
ENVIRONMENT¶
ExtUtils::AutoInstall uses a single environment variable,
"PERL_EXTUTILS_AUTOINSTALL". It is taken as the command line
argument passed to
Makefile.PL; you could set it to either
"--defaultdeps" or "--skipdeps" to avoid interactive
behaviour.
EXAMPLES¶
Using MakeMaker with AutoInstall¶
To use this module with ExtUtils::MakeMaker, first make a
inc/ExtUtils/
subdirectory in the directory containing your Makefile.PL, and put a copy this
module under it as
inc/ExtUtils/AutoInstall.pm. You can find out where
this module has been installed by typing "perldoc -l
ExtUtils::AutoInstall" in the command line.
Your
Makefile.PL should look like this:
# pull in ExtUtils/AutoInstall.pm from 'inc'
use lib 'inc';
use ExtUtils::AutoInstall (
-core => [ # mandatory modules
'Module0' => '', # any version would suffice
],
'Feature1' => [
# do we want to install this feature by default?
-default => ( system('feature1 --version') == 0 ),
Module1 => '0.01',
],
'Feature2' => [
# associate tests to be disabled if this feature is missing
-tests => [ <t/feature2*.t> ],
# associate tests to be disabled if this feature is present
-skiptests => [ <t/nofeature2*.t> ],
Module2 => '0.02',
],
'Feature3' => { # hash reference works, too
# force installation even if tests fail
Module2 => '0.03',
}
);
WriteMakefile(
AUTHOR => 'Joe Hacker <joe@hacker.org>',
ABSTRACT => 'Perl Interface to Joe Hacker',
NAME => 'Joe::Hacker',
VERSION_FROM => 'Hacker.pm',
DISTNAME => 'Joe-Hacker',
);
Self-Download Code¶
If you do not wish to put a copy of ExtUtils::AutoInstall under
inc/, and
are confident that users will have internet access, you may replace the
"use lib 'inc';" line with this block of code:
# ExtUtils::AutoInstall Bootstrap Code, version 7.
BEGIN{my$p='ExtUtils::AutoInstall';my$v=0.45;$p->VERSION||0>=$v
or+eval"use $p $v;1"or+do{my$e=$ENV{PERL_EXTUTILS_AUTOINSTALL};
(!defined($e)||$e!~m/--(?:default|skip|testonly)/and-t STDIN or
eval"use ExtUtils::MakeMaker;WriteMakefile(PREREQ_PM=>{'$p',$v}
);1"and exit)and print"==> $p $v required. Install it from CP".
"AN? [Y/n] "and<STDIN>!~/^n/i and print"*** Installing $p\n"and
do{if (eval '$>' and lc(`sudo -V`) =~ /version/){system('sudo',
$^X,"-MCPANPLUS","-e","CPANPLUS::install $p");eval"use $p $v;1"
||system('sudo', $^X, "-MCPAN", "-e", "CPAN::install $p")}eval{
require CPANPLUS;CPANPLUS::install$p};eval"use $p $v;1"or eval{
require CPAN;CPAN::install$p};eval"use $p $v;1"||die"*** Please
manually install $p $v from cpan.org first...\n"}}}
If the user did not have ExtUtils::AutoInstall installed, the block of code
above will automatically download and install it.
However, due to its space-compressed (and obfuscated) nature, you should think
twice before employing this block of code; it is usually much more desirable
to just use Module::Install instead.
SEE ALSO¶
perlmodlib, ExtUtils::MakeMaker, Sort::Versions, CPAN, CPANPLUS, Module::Install
ACKNOWLEDGEMENTS¶
The test script included in the
ExtUtils::AutoInstall distribution
contains code adapted from Michael Schwern's
Test::More under the
Perl License. Please consult to
t/AutoInstall.t for details.
See the
AUTHORS file in this module's source distribution for the list of
contributors.
AUTHORS¶
Autrijus Tang <autrijus@autrijus.org>
COPYRIGHT¶
Copyright 2001, 2002, 2003, 2004 by Autrijus Tang <autrijus@autrijus.org>.
This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
See <
http://www.perl.com/perl/misc/Artistic.html>