hello, world!
I have created a Perl library to solve a need -- making Perl libraries
in bulk:
http://holgerdanske.com/pub/dpchrist/perl5/Dist-MultiMaker/
Please review and comment.
TIA,
David
NAME
Dist::MultiMaker - maker for multiple Perl library distributions
SYNOPSIS
# MANIFEST
/first/target/Makefile.PL
/another/target/Makefile.PL
/third/Makefile.PL
# Makefile.PL
use Dist::MultiMaker;
WriteMakefile();
$ perl Makefile.PL [opts] [args]
$ make [args]
$ make test [args]
$ make install [args]
OPTIONS AND ARGUMENTS
opts:
--debug,-d Enable debugging messages
--indent-level=INDENT_LEVEL Set indentation level to INDENT_LEVEL
spaces
--make=MAKE Path to make(1)
--mkdir=MKDIR Path to mkdir(1)
--opt-inc=OPT_INC Name of temporary files for options
--perl5lib-inc=PERL5LIB_INC Name of temporary files for PERL5LIB
--perl=PERL Path to perl(1)
--ps4=PS4 Prompt for command tracing messages
--quiet,-q Silence information messages
--tmp=TMP Path to root of temporary file directory
--verbose,-v Enable additional information messages
--xtrace,-x Enable command tracing messages
Unknown opts and all args are passed through to target 'make
Makefile.PL' and/or 'make ..' commands.
DESCRIPTION
Suppose we have four Perl library distributions: A, B, C, and D.
Further suppose that the distributions are interdependent:
- D has prerequisites B and C
- B and C have prerequisite A
Or, viewed as a graph with dependents above and prerequisites below:
D
/ \
B C
\ /
A
Existing tools (e.g. cpan(1)) are capable of running maker scripts,
making, testing, and installing interdependent distributions, such
as the above. But, they are not well suited to development, due to
the requirements for packaging and installation.
Manual Approach to Developing Multiple Distributions
One approach to developing multiple distributions is to set the
PERL5LIB environment variable to include all of the distribution
blib/lib directories, and then edit-compile-test-repeat over the
various distributions in prerequisite order:
$
PERL5LIB=$PERL5LIB:<A>/blib/lib:<B>/blib/lib:<C>/blib/lib:<D>/blib/lib
<edit A, B, C, and/or D>
$ cd <A>
$ perl Makefile.PL
$ make
$ make test
$ cd <B>
$ perl Makefile.PL
$ make
$ make test
$ cd <C>
$ perl Makefile.PL
$ make
$ make test
$ cd <D>
$ perl Makefile.PL
$ make
$ make test
<goto 'edit' until done>
Developing Multiple Distributions with Dist::MultiMaker
Assume the following directory structure (shortened for brevity; see
the 'example' directory in the source distribution):
example
|-- A
| |-- MANIFEST
| |-- Makefile.PL
| |-- lib
| | `-- Dist
| | `-- MultiMaker
| | `-- Example
| | `-- A.pm
| `-- t
| |-- 00-manifest.t
| `-- Dist-MultiMaker-Example-A.t
|-- B ...
|-- C ...
`-- D ...
Setup
The developer begins by setting up a Dist::MultiMaker make area:
* The developer creates a distribution, Lib, to organize
Dist::MultiMaker activities:
$ cd <example>
$ h2xs -XAn Lib
* Within Lib, the developer creates a container directory,
MultiMaker, for MultiMaker make directories:
$ cd Lib
$ mkdir MultiMaker
* Within MultiMaker, the developer creates a MultiMaker make
directory, ABCD, for making A, B, C, and D:
$ cd MultiMaker
$ mkdir ABCD
* Within ABCD, the developer creates a Dist::MakeMaker manifest
file, MANIFEST, which lists the maker scripts for distributions
A, B, C, and D in prerequisite traversal order:
$ cd ABCD
$ vi MANIFEST
../../../A/Makefile.PL
../../../B/Makefile.PL
../../../C/Makefile.PL
../../../D/Makefile.PL
Note that Dist::MakerMaker manifest files may contain both
ExtUtils::MakeMaker maker scripts and Dist::MultiMaker maker
scripts, as Dist::MultiMaker supports recursion (see AB and
ABCD-recursive).
* The developer also creates a Dist::MakeMaker maker script,
Makefile.PL, which uses the Dist::MultiMaker module and calls
Dist::MultiMaker::WriteMakefile():
$ vi Makefile.PL
use Dist::MultiMaker;
WriteMakefile();
The directory structure is now:
example/
|-- A ...
|-- B ...
|-- C ...
|-- D ...
`-- Lib
|-- MANIFEST
|-- Makefile.PL
|-- MultiMaker
| `-- ABCD
| |-- MANIFEST
| `-- Makefile.PL
|-- lib
| `-- Dist
| `-- MultiMaker
| `-- Example
| `-- Lib.pm
`-- t
`-- Dist-MultiMaker-Example-Lib.t
Usage
Dist::MakeMaker is now ready to assist with development:
* The developer runs the Dist::MultiMaker maker script in the ABCD
make directory:
$ perl Makefile.PL
WriteMakefile() begins by reading MANIFEST. For each target
maker script listed, WriteMakefile() changes into the script's
directory, runs the script, and makes the target:
perl Makefile.PL
make all
The first commands create target makefiles:
A/Makefile
B/Makefile
C/Makefile
etc.
The second commands may create blib/lib sub-directories.
WriteMakefile() notes such directories for inclusion in the
PERL5LIB environment variable:
A/blib/lib
B/blib/lib
C/blib/lib
etc..
Once all the targets have been processed, WriteMakefile() writes
a Dist::MultiMaker makefile in the starting directory:
Lib/MultiMaker/ABCD/Makefile
This makefile contains all of the rules and most of the
information needed for passing through make(1) commands to the
target makefiles. The rest of the information is contained in
OPT_INC and PERL5LIB_INC temporary files stored under the TMP
directory (see options --opt-inc, --perl5lib-inc, and --tmp).
Note that additional arguments to Dist::MultiMaker maker scripts
are passed through to target maker scripts:
$ perl Makefile.PL verbose
* The developer can now issue make(1) commands against the
Dist::MultiMaker makefile. This makefile will pass through
commands to the target makefiles:
$ make
$ make test
$ make install
$ make dist
$ make disttest
$ make ...
Note that additional arguments received by the Dist::MultiMaker
makefile will be passed through to the target makefiles:
$ make test TEST_VERBOSE=1
FUNCTIONS
Dist::MultiMaker implements one function, WriteMakefile(), which is
by exported by default.
WriteMakefile
WriteMakefile
See DESCRIPTION, above, for operation and usage.
WriteMakefile() does not accept any arguments.
WriteMakefile() recognizes and removes the following options from
the command-line argument array, @ARGV. All other array elements are
passed through to target makefiles:
--debug,-d
Enable debugging messages. Default value is the value of the
DIST_MULTIMAKER_DEBUG environment variable. If that is false,
default value is the value of the DEBUG environment variable. If
that is false, default value is false.
--indent-level=INDENT_LEVEL
Set indentation level to INDENT_LEVEL spaces. Default value is
the value of the DIST_MULTIMAKER_INDENT_LEVEL environment
variable. If that is false, default value is the value of the
INDENT_LEVEL environment variable. If that is false, default
value is 4.
--make=MAKE
Path to make(1). Default value is the value of the
DIST_MULTIMAKER_MAKE environment variable. If that is false,
default value is the value of the MAKE environment variable. If
that is false, default value is 'gmake' on BSD operating systems
and 'make' on non-BSD operating systems.
--mkdir=MKDIR
Path to mkdir(1). Default value is the value of the
DIST_MULTIMAKER_MKDIR environment variable. If that is false,
default value is the value of the MKDIR environment variable. If
that is false, default value is 'mkdir'.
--opt-inc=OPT_INC
Name of Dist::MultiMaker temporary files for communicating
options between parent maker script invocations and child maker
script invocations. Default value is the value of the
DIST_MULTIMAKER_OPT_INC environment variable. If that is false,
default value is 'opt.inc'.
--perl5lib-inc=OPT_INC
Name of Dist::MultiMaker temporary files for communicating
PER5LIB paths between parent maker script invocations, child
maker script invocations, and makefile invocations. Default
value is the value of the DIST_MULTIMAKER_PERL5LIB_INC
environment variable. If that is false, default value is
'perl5lib.inc'.
--perl=PERL
Path to perl(1). Default value is the value of the
DIST_MULTIMAKER_PERL environment variable. If that is false,
default value is the value of the PERL environment variable. If
that is false, default value is the name used to execute the
current copy of perl(1).
--ps4=PS4
Prompt for command tracing messages. Default value is the value
of the DIST_MULTIMAKER_PS4 environment variable. If that is
false, default value is the value of the PS4 environment
variable. If that is false, default value is '+'.
--quiet,-q
Silence information messages. Default value is the value of the
DIST_MULTIMAKER_QUIET environment variable. If that is false,
default value is the value of the QUIET environment variable. If
that is false, default value is false.
--tmp=TMP
Path to root of temporary file directory. Default value is the
value of the DIST_MULTIMAKER_TMP environment variable. If that
is false, default value is the value of the TMP environment
variable. If that is false, default value is
$HOME/perl5/tmp/Dist/MultiMaker.
--verbose,-v
Enable additional information messages. Default value is the
value of the DIST_MULTIMAKER_VERBOSE environment variable. If
that is false, default value is the value of the VERBOSE
environment variable. If that is false, default value is false.
--xtrace,-x
Enable command tracing messages. Default value is the value of
the DIST_MULTIMAKER_XTRACE If that is false, default value is
the value of the XTRACE environment variable. If that is false,
default value is false.
ENVIRONMENT VARIABLES
The following environment variables affect operation of this module:
DEBUG=BOOLEAN
Default value for --debug option, if DIST_MULTIMAKER_DEBUG is
false.
DIST_MULTIMAKER_DEBUG=BOOLEAN
Default value for --debug option.
DIST_MULTIMAKER_DEBUGX=BOOLEAN
Enable low-level debugging messages
DIST_MULTIMAKER_INDENT_LEVEL=INTEGER
Default value for --indent-level option.
DIST_MULTIMAKER_MAKE=STRING
Default value for --make option.
DIST_MULTIMAKER_MKDIR=STRING
Default value for --mkdir option.
DIST_MULTIMAKER_OPT_INC=STRING
Default value for --opt-inc option.
DIST_MULTIMAKER_PERL5LIB_INC=STRING
Default value for --perl5lib-inc option.
DIST_MULTIMAKER_PERL=STRING
Default value for --perl option.
DIST_MULTIMAKER_PS4=STRING
Default value for --ps4 option.
DIST_MULTIMAKER_QUIET=BOOLEAN
Default value for --quiet option.
DIST_MULTIMAKER_TMP=STRING
Default value for --tmp option.
DIST_MULTIMAKER_VERBOSE=BOOLEAN
Default value for --verbose option.
DIST_MULTIMAKER_XTRACE=BOOLEAN
Default value for --xtrace option.
INDENT_LEVEL=INTEGER
Default value for --indent-level option, if
DIST_MULTIMAKER_INDENT_LEVEL is false.
MAKE=STRING
Default value for --make option, if DIST_MULTIMAKER_INDENT_MAKE
is false.
MKDIR=STRING
Default value for --mkdir option, if DIST_MULTIMAKER_MKDIR is
false.
OSTYPE=STRING
If DIST_MULTIMAKER_MAKE and MAKE are both false, sets default
value for --make option to 'gmake' on BSD operating systems and
to 'make' on non-BSD operating systems.
PERL=STRING
Default value for --perl option, if DIST_MULTIMAKER_PERL is
false.
PS4=STRING
Default value for --ps4 option, if DIST_MULTIMAKER_PS4 is false.
QUIET=BOOLEAN
Default value for --quiet option, if DIST_MULTIMAKER_QUIET is
false.
TMP=STRING
Default value for --tmp option, if DIST_MULTIMAKER_TMP is false.
VERBOSE=BOOLEAN
Default value for --verbose option, if DIST_MULTIMAKER_VERBOSE
is false.
XTRACE=BOOLEAN
Default value for --xtrace option, if DIST_MULTIMAKER_XTRACE is
false.
EXPORT
WriteMakefile
INSTALLATION
To install this software, run the following commands in the source
distribution root directory:
perl Makefile.PL
make
make test
make install
PREREQUISITES
This software requires the following Perl modules:
Carp
Cwd
Data::Dumper
Fcntl
File::Basename
File::Spec::Functions
Getopt::Long
And the program:
GNU Make
COPYRIGHT AND LICENSE
Copyright 2019 by David Paul Christensen dpchr...@holgerdanske.com
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.24.1
or, at your option, any later version of Perl 5 you may have
available.