lib/base.pm Establish IS-A relationship at compile time
lib/base/t/base.t See if base works
lib/base/t/compile-time.t See if base works
-lib/base/t/fields-base.t See if fields work
lib/base/t/fields-5.6.0.t See if fields work
lib/base/t/fields-5.8.0.t See if fields work
+lib/base/t/fields-base.t See if fields work
lib/base/t/fields.t See if fields work
lib/base/t/isa.t See if base's behaviour doesn't change
lib/base/t/lib/Dummy.pm Test module for base.pm
lib/Module/Build/t/new_from_context.t Module::Build
lib/Module/Build/t/notes.t Module::Build
lib/Module/Build/t/parents.t Module::Build
+lib/Module/Build/t/PL_files.t Module::Build tests
lib/Module/Build/t/pod_parser.t Module::Build
lib/Module/Build/t/ppm.t Module::Build
lib/Module/Build/t/runthrough.t Module::Build
lib/Module/Build/t/tilde.t Module::Build
lib/Module/Build/t/use_tap_harness.t Module::Build
lib/Module/Build/t/versions.t Module::Build
+lib/Module/Build/t/write_default_maniskip.t Module::Build tests
lib/Module/Build/t/xs.t Module::Build
lib/Module/Build/Version.pm Module::Build
lib/Module/Build/YAML.pm Module::Build
'Module::Build' =>
{
'MAINTAINER' => 'kwilliams',
- 'DISTRIBUTION' => 'DAGOLDEN/Module-Build-0.33_02.tar.gz',
+ 'DISTRIBUTION' => 'DAGOLDEN/Module-Build-0.33_05.tar.gz',
'FILES' => q[lib/Module/Build lib/Module/Build.pm],
'EXCLUDED' => [ qw{ t/par.t t/signature.t scripts/bundle.pl}, ],
'CPAN' => 1,
use vars qw($VERSION @ISA);
@ISA = qw(Module::Build::Base);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
# Okay, this is the brute-force method of finding out what kind of
__END__
+=for :stopwords
+bindoc binhtml destdir distcheck distclean distdir distmeta distsign disttest
+fakeinstall html installdirs installsitebin installsitescript installvendorbin
+installvendorscript libdoc libhtml pardist ppd ppmdist realclean skipcheck
+testall testcover testdb testpod testpodcoverage versioninstall
=head1 NAME
If you run the C<Build> script without any arguments, it runs the
C<build> action, which in turn runs the C<code> and C<docs> actions.
-This is analogous to the MakeMaker 'make all' target.
+This is analogous to the C<MakeMaker> I<make all> target.
=item clean
[version 0.20]
-This action builds your codebase.
+This action builds your code base.
By default it just creates a C<blib/> directory and copies any C<.pm>
and C<.pod> files from your C<lib/> directory into the C<blib/>
Creates the F<META.yml> file that describes the distribution.
-F<META.yml> is a file containing various bits of "metadata" about the
+F<META.yml> is a file containing various bits of I<metadata> about the
distribution. The metadata includes the distribution name, version,
abstract, prerequisites, license, and various other data about the
distribution. This file is created as F<META.yml> in YAML format.
[version 0.20]
-This will generate documentation (e.g. Unix man pages and html
+This will generate documentation (e.g. Unix man pages and HTML
documents) for any installable items under B<blib/> that
contain POD. If there are no C<bindoc> or C<libdoc> installation
targets defined (as will be the case on systems that don't support
Unix manpages) no action is taken for manpages. If there are no
C<binhtml> or C<libhtml> installation targets defined no action is
-taken for html documents.
+taken for HTML documents.
=item fakeinstall
Build a PPD file for your distribution.
This action takes an optional argument C<codebase> which is used in
-the generated ppd file to specify the (usually relative) URL of the
+the generated PPD file to specify the (usually relative) URL of the
distribution. By default, this value is the distribution name without
any path information.
[version 0.23]
Generates a PPM binary distribution and a PPD description file. This
-action also invokes the 'ppd' action, so it can accept the same
+action also invokes the C<ppd> action, so it can accept the same
C<codebase> argument described under that action.
This uses the same mechanism as the C<dist> action to tar & zip its
[version 0.32]
-This action prints out a Perl data structure of all prerequsites and the versions
+This action prints out a Perl data structure of all prerequisites and the versions
required. The output can be loaded again using C<eval()>. This can be useful for
external tools that wish to query a Build script for prerequisites.
=item testall
-[verion 0.2807]
+[version 0.2807]
[Note: the 'testall' action and the code snippets below are currently
in alpha stage, see
NOTE: There is some preliminary support for options to use the more
familiar long option style. Most options can be preceded with the
C<--> long option prefix, and the underscores changed to dashes
-(e.g. --use-rcfile). Additionally, the argument to boolean options is
+(e.g. C<--use-rcfile>). Additionally, the argument to boolean options is
optional, and boolean options can be negated by prefixing them with
-'no' or 'no-' (e.g. --noverbose or --no-verbose).
+C<no> or C<no-> (e.g. C<--noverbose> or C<--no-verbose>).
=over 4
--install_path html=/home/ken/docs/html
If you wish to locate your resource file in a different location, you
-can set the environment variable 'MODULEBUILDRC' to the complete
+can set the environment variable C<MODULEBUILDRC> to the complete
absolute path of the file containing your options.
=item arch
"Architecture-dependent" module files, usually produced by compiling
-XS, Inline, or similar code.
+XS, L<Inline>, or similar code.
=item script
=item binhtml
-This is the same as C<bindoc> above, but applies to html documents.
+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.
+This is the same as C<bindoc> above, but applies to HTML documents.
=back
binhtml => installhtml1dir installsitehtml1dir installvendorhtml1dir [*]
libhtml => installhtml3dir installsitehtml3dir installvendorhtml3dir [*]
- * Under some OS (eg. MSWin32) the destination for html documents is
+ * 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
C<installdirs> to "core" to overwrite the module in its present
location.
-(Note that the 'script' line is different from MakeMaker -
+(Note that the 'script' line is different from C<MakeMaker> -
unfortunately there's no such thing as "installsitescript" or
"installvendorscript" entry in C<Config.pm>, so we use the
"installsitebin" and "installvendorbin" entries to at least get the
binhtml => /home/ken/html
libhtml => /home/ken/html
-Note that this is I<different> from how MakeMaker's C<PREFIX>
+Note that this is I<different> from how C<MakeMaker>'s C<PREFIX>
parameter works. C<install_base> just gives you a default layout under the
directory you specify, which may have little to do with the
C<installdirs=site> layout.
=item prefix
-Provided for compatibility with ExtUtils::MakeMaker's PREFIX argument.
+Provided for compatibility with C<ExtUtils::MakeMaker>'s PREFIX argument.
C<prefix> should be used when you wish Module::Build to install your
modules, documentation and scripts in the same place
-ExtUtils::MakeMaker does.
+C<ExtUtils::MakeMaker> does.
The following are equivalent.
perl Makefile.PL PREFIX=/tmp/foo
Because of the very complex nature of the prefixification logic, the
-behavior of PREFIX in MakeMaker has changed subtly over time.
+behavior of PREFIX in C<MakeMaker> has changed subtly over time.
Module::Build's --prefix logic is equivalent to the PREFIX logic found
-in ExtUtils::MakeMaker 6.30.
+in C<ExtUtils::MakeMaker> 6.30.
-If you do not need to retain compatibility with ExtUtils::MakeMaker or
-are starting a fresh Perl installation we recommand you use
-C<install_base> instead (and C<INSTALL_BASE> in ExtUtils::MakeMaker).
+If you do not need to retain compatibility with C<ExtUtils::MakeMaker> or
+are starting a fresh Perl installation we recommend you use
+C<install_base> instead (and C<INSTALL_BASE> in C<ExtUtils::MakeMaker>).
See L<Module::Build::Cookbook/Instaling in the same location as
ExtUtils::MakeMaker> for further information.
=head1 MOTIVATIONS
There are several reasons I wanted to start over, and not just fix
-what I didn't like about MakeMaker:
+what I didn't like about C<MakeMaker>:
=over 4
=item *
-I don't like the core idea of MakeMaker, namely that C<make> should be
+I don't like the core idea of C<MakeMaker>, namely that C<make> should be
involved in the build process. Here are my reasons:
=over 4
=item *
-There are several architectural decisions in MakeMaker that make it
+There are several architectural decisions in C<MakeMaker> that make it
very difficult to customize its behavior. For instance, when using
-MakeMaker you do C<use ExtUtils::MakeMaker>, but the object created in
+C<MakeMaker> you do C<use ExtUtils::MakeMaker>, but the object created in
C<WriteMakefile()> is actually blessed into a package name that's
created on the fly, so you can't simply subclass
C<ExtUtils::MakeMaker>. There is a workaround C<MY> package that lets
-you override certain MakeMaker methods, but only certain explicitly
-preselected (by MakeMaker) methods can be overridden. Also, the method
+you override certain C<MakeMaker> methods, but only certain explicitly
+preselected (by C<MakeMaker>) methods can be overridden. Also, the method
of customization is very crude: you have to modify a string containing
the Makefile text for the particular target. Since these strings
aren't documented, and I<can't> be documented (they take on different
values depending on the platform, version of perl, version of
-MakeMaker, etc.), you have no guarantee that your modifications will
-work on someone else's machine or after an upgrade of MakeMaker or
+C<MakeMaker>, etc.), you have no guarantee that your modifications will
+work on someone else's machine or after an upgrade of C<MakeMaker> or
perl.
=item *
-It is risky to make major changes to MakeMaker, since it does so many
+It is risky to make major changes to C<MakeMaker>, since it does so many
things, is so important, and generally works. C<Module::Build> is an
entirely separate package so that I can work on it all I want, without
worrying about backward compatibility.
Module::Build::API - API Reference for Module Authors
+=for :stopwords apache bsd distdir distsign gpl installdirs lgpl mit mozilla packlists
=head1 DESCRIPTION
is performed. See also the L<add_to_cleanup()|/"add_to_cleanup(@files)">
method.
+=item auto_configure_requires
+
+[version 0.34]
+
+This parameter determines whether Module::Build will add itself
+automatically to configure_requires (and build_requires) if Module::Build
+is not already there. The default value is true.
+
=item auto_features
[version 0.26]
[version 0.28]
If true, this parameter tells Module::Build to create a F<.packlist>
-file during the C<install> action, just like ExtUtils::MakeMaker does.
+file during the C<install> action, just like C<ExtUtils::MakeMaker> does.
The file is created in a subdirectory of the C<arch> installation
location. It is used by some other tools (CPAN, CPANPLUS, etc.) for
determining what files are part of an install.
[version 0.19]
-This parameter lets you use Module::Build::Compat during the
+This parameter lets you use C<Module::Build::Compat> during the
C<distdir> (or C<dist>) action to automatically create a Makefile.PL
-for compatibility with ExtUtils::MakeMaker. The parameter's value
+for compatibility with C<ExtUtils::MakeMaker>. The parameter's value
should be one of the styles named in the L<Module::Build::Compat>
documentation.
use C<Pod::Text> (or C<Pod::Readme> if it's installed) on the file
indicated by C<dist_version_from> and put the result in the F<README>
file. This is by no means the only recommended style for writing a
-README, but it seems to be one common one used on the CPAN.
+F<README>, but it seems to be one common one used on the CPAN.
If you generate a F<README> in this way, it's probably a good idea to
create a separate F<INSTALL> file if that information isn't in the
An optional parameter specifying a set of C<.PL> files in your
distribution. These will be run as Perl scripts prior to processing
-the rest of the files in your distribution. They are usually used as
-templates for creating other files dynamically, so that a file like
+the rest of the files in your distribution with the name of the file
+they're generating as an argument. They are usually used as templates
+for creating other files dynamically, so that a file like
C<lib/Foo/Bar.pm.PL> might create the file C<lib/Foo/Bar.pm>.
The files are specified with the C<.PL> files as hash keys, and the
'lib/funny.PL' => [],
}
+Here's an example of a simple PL file.
+
+ my $output_file = shift;
+ open my $fh, ">", $output_file or die "Can't open $output_file: $!";
+
+ print $fh <<'END';
+ #!/usr/bin/perl
+
+ print "Hello, world!\n";
+ END
+
+PL files are not installed by default, so its safe to put them in
+F<lib/> and F<bin/>.
+
+
=item pm_files
[version 0.19]
in a "normal" Module::Build-style distribution. This parameter is
mainly intended to support alternative layouts of files.
-For instance, if you have an old-style MakeMaker distribution for a
+For instance, if you have an old-style C<MakeMaker> distribution for a
module called C<Foo::Bar> and a F<Bar.pm> file at the top level of the
distribution, you could specify your layout in your C<Build.PL> like
this:
or as a string giving the name of a single script file.
The default is to install any scripts found in a F<bin> directory at
-the top level of the distribution.
+the top level of the distribution, minus any keys of L<PL_files>.
For backward compatibility, you may use the parameter C<scripts>
instead of C<script_files>. Please consider this usage deprecated,
print $build->pedantic, $/;
$build->pedantic(0);
-If the default value is a hash reference, this generetes a special-case
+If the default value is a hash reference, this generates a special-case
accessor method, wherein individual key/value pairs may be set or fetched:
print "stuff{foo} is: ", $build->stuff( 'foo' ), $/;
Returns a hash reference indicating the C<build_requires>
prerequisites that were passed to the C<new()> method.
+=item can_action( $action )
+
+Returns a reference to the method that defines C<$action>, or false
+otherwise. This is handy for actions defined (or maybe not!) in subclasses.
+
+[version 0.32_xx]
+
=item cbuilder()
[version 0.2809]
Among the files created in C<_build/> is a F<_build/prereqs> file
containing the set of prerequisites for this distribution, as a hash
of hashes. This file may be C<eval()>-ed to obtain the authoritative
-set of prereqs, which might be different from the contents of
+set of prerequisites, which might be different from the contents of
F<META.yml> (because F<Build.PL> might have set them dynamically).
But fancy developers take heed: do not put any fancy custom runtime
code in the F<_build/prereqs> file, leave it as a static declaration
failure (the opposite of how C<system()> works, but more intuitive).
Note that if you supply a single argument to C<do_system()>, it
-will/may be processed by the systems's shell, and any special
+will/may be processed by the system's shell, and any special
characters will do their special things. If you supply multiple
arguments, no shell will get involved and the command will be executed
directly.
With no argument, it returns a reference to a hash containing all
elements and their respective values. This hash should not be modified
-directly; use the multi-argument below form to change values.
+directly; use the multiple argument below form to change values.
The single argument form returns the value associated with the
element C<$type>.
-The multi-argument form allows you to set the paths for element types.
-C<$value> must be a relative path using unix-like paths. (A series of
-directories seperated by slashes. Eg 'foo/bar'.) The return value is a
+The multiple argument form allows you to set the paths for element types.
+C<$value> must be a relative path using Unix-like paths. (A series of
+directories separated by slashes, e.g. C<foo/bar>.) The return value is a
localized path based on C<$value>.
Assigning the value C<undef> to an element causes it to be removed.
With no argument, it returns a reference to a hash containing all
elements and their respective values. This hash should not be modified
-directly; use the multi-argument below form to change values.
+directly; use the multiple argument below form to change values.
The single argument form returns the value associated with the
element C<$type>.
-The multi-argument form allows you to set the paths for element types.
+The multiple argument form allows you to set the paths for element types.
The supplied C<$path> should be an absolute path to install elements
of C<$type>. The return value is C<$path>.
This is the name of the original action invoked by the user. This
value is set when the user invokes F<Build.PL>, the F<Build> script,
-or programatically through the L<dispatch()|/"dispatch($action, %args)">
+or programmatically through the L<dispatch()|/"dispatch($action, %args)">
method. It does not change as sub-actions are executed as
dependencies are evaluated.
different entities involved in the build. See the example in the
C<current()> method.
-The C<notes()> method is essentally a glorified hash access. With no
+The C<notes()> method is essentially a glorified hash access. With no
arguments, C<notes()> returns the entire hash of notes. With one argument,
C<notes($key)> returns the value associated with the given key. With two
arguments, C<notes($key, $value)> sets the value associated with the given key
The two argument form returns the value associated with the
element C<$type>.
-The multi-argument form allows you to set the paths for element types.
-C<$value> must be a relative path using unix-like paths. (A series of
-directories seperated by slashes. Eg 'foo/bar'.) The return value is a
+The multiple argument form allows you to set the paths for element types.
+C<$value> must be a relative path using Unix-like paths. (A series of
+directories separated by slashes, e.g. C<foo/bar>.) The return value is a
localized path based on C<$value>.
Assigning the value C<undef> to an element causes it to be removed.
or any execution of C<./Build> had command line options specified that
override valid properties.
-The C<runtime_params()> method is essentally a glorified read-only hash. With
+The C<runtime_params()> method is essentially a glorified read-only hash. With
no arguments, C<runtime_params()> returns the entire hash of properties
specified on the command line. With one argument, C<runtime_params($key)>
returns the value associated with the given key.
=item allow_mb_mismatch()
+=item auto_configure_requires()
+
=item autosplit()
=item base_dir()
A list of additional resources available for users of the
distribution. This can include links to a homepage on the web, a
-bugtracker, the repository location, a even subscription page for the
+bug tracker, the repository location, a even subscription page for the
distribution mailing list.
See L<http://module-build.sourceforge.net/META-spec-current.html#resources>.
This is relatively straightforward, and is the best way to do things
if your My::Builder class contains lots of code. The
C<create_build_script()> method will ensure that the current value of
-C<@INC> (including the C</nonstandard/library/path>) is propogated to
+C<@INC> (including the C</nonstandard/library/path>) is propagated to
the Build script, so that My::Builder can be found when running build
-actions.
+actions. If you find that you need to C<chdir> into a different directories
+in your subclass methods or actions, be sure to always return to the original
+directory (available via the C<base_dir()> method before returning control
+to the parent class. This is important to avoid data serialization problems.
For very small additions, Module::Build provides a C<subclass()>
method that lets you subclass Module::Build more conveniently, without
Note that if you want to provide both a F<Makefile.PL> and a
F<Build.PL> for your distribution, you probably want to add the
-following to C<WriteMakefile> in your F<Makefile.PL> so that MakeMaker
+following to C<WriteMakefile> in your F<Makefile.PL> so that C<MakeMaker>
doesn't try to run your F<Build.PL> as a normal F<.PL> file:
PL_FILES => {},
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
BEGIN { require 5.00503 }
$p->{requires} = delete $p->{prereq} if defined $p->{prereq};
$p->{script_files} = delete $p->{scripts} if defined $p->{scripts};
- # Convert to arrays
+ # Convert to from shell strings to arrays
for ('extra_compiler_flags', 'extra_linker_flags') {
$p->{$_} = [ $self->split_like_shell($p->{$_}) ] if exists $p->{$_};
}
+ # Convert to arrays
+ for ('include_dirs') {
+ $p->{$_} = [ $p->{$_} ] if exists $p->{$_} && !ref $p->{$_}
+ }
+
$self->add_to_cleanup( @{delete $p->{add_to_cleanup}} )
if $p->{add_to_cleanup};
}
}
-# Returns the absolute path of the perl interperter used to invoke
+# Returns the absolute path of the perl interpreter used to invoke
# this process. The path is derived from $^X or $Config{perlpath}. On
# some platforms $^X contains the complete absolute path of the
# interpreter, on other it may contain a relative path, or simply
########################################################################
# Add the default properties.
+__PACKAGE__->add_property(auto_configure_requires => 1);
__PACKAGE__->add_property(blib => 'blib');
__PACKAGE__->add_property(build_class => 'Module::Build');
__PACKAGE__->add_property(build_elements => [qw(PL support pm xs pod script)]);
return $p->{$member} = $parser->$method();
}
-sub version_from_file { # Method provided for backwards compatability
+sub version_from_file { # Method provided for backwards compatibility
return Module::Build::ModuleInfo->new_from_file($_[1])->version();
}
-sub find_module_by_name { # Method provided for backwards compatability
+sub find_module_by_name { # Method provided for backwards compatibility
return Module::Build::ModuleInfo->find_module_by_name(@_[1,2]);
}
return if $self->{_completed_actions}{$action}++;
local $self->{action} = $action;
- my $method = "ACTION_$action";
- die "No action '$action' defined, try running the 'help' action.\n" unless $self->can($method);
+ my $method = $self->can_action( $action );
+ die "No action '$action' defined, try running the 'help' action.\n" unless $method;
return $self->$method();
}
+sub can_action {
+ my ($self, $action) = @_;
+ return $self->can( "ACTION_$action" );
+}
+
# cuts the user-specified options out of the command-line args
sub cull_options {
my $self = shift;
}
}
-# decide whether or not an option requires/has an opterand
+# decide whether or not an option requires/has an operand
sub _optional_arg {
my $self = shift;
my $opt = shift;
$args{$_} = [ $self->split_like_shell($args{$_}) ] if exists $args{$_};
}
+ # Convert to arrays
+ for ('include_dirs') {
+ $args{$_} = [ $args{$_} ] if exists $args{$_} && !ref $args{$_}
+ }
+
# Hashify these parameters
for ($self->hash_properties, 'config') {
next unless exists $args{$_};
for my $subkey (keys %{$args{$key}}) {
next if !defined $args{$key}{$subkey};
my $subkey_ext = $self->_detildefy($args{$key}{$subkey});
- if ( $subkey eq 'html' ) { # translate for compatability
+ if ( $subkey eq 'html' ) { # translate for compatibility
$args{$key}{binhtml} = $subkey_ext;
$args{$key}{libhtml} = $subkey_ext;
} else {
sub prereq_data {
my $self = shift;
- my @types = @{ $self->prereq_action_types };
+ my @types = ('configure_requires', @{ $self->prereq_action_types } );
my $info = { map { $_ => $self->$_() } grep { %{$self->$_()} } @types };
return $info;
}
exclude => [ file_qr('\.bat$') ])}
or die "Couldn't find any POD files to test\n";
- { package Module::Build::PodTester; # Don't want to pollute the main namespace
+ { package # hide from PAUSE
+ Module::Build::PodTester; # Don't want to pollute the main namespace
Test::Pod->import( tests => scalar @files );
pod_file_ok($_) foreach @files;
}
$self->log_info("HTMLifying $infile -> $outfile\n");
$self->log_verbose("pod2html @opts\n");
- Pod::Html::pod2html(@opts); # or warn "pod2html @opts failed: $!";
+ eval { Pod::Html::pod2html(@opts); 1 }
+ or $self->log_warn("pod2html @opts failed: $@");
}
}
sub do_create_license {
my $self = shift;
- $self->log_info("Creating LICENSE file");
+ $self->log_info("Creating LICENSE file\n");
my $l = $self->license
or die "No license specified";
});
}
+
+=begin private
+
+ my $has_include = $build->_eumanifest_has_include;
+
+Returns true if the installed version of ExtUtils::Manifest supports
+#include and #include_default directives. False otherwise.
+
+=end private
+
+=cut
+
+# #!include and #!include_default were added in 1.50
+sub _eumanifest_has_include {
+ my $self = shift;
+
+ require ExtUtils::Manifest;
+ return ExtUtils::Manifest->VERSION >= 1.50 ? 1 : 0;
+ return 0;
+}
+
+
+=begin private
+
+ my $maniskip_file = $build->_default_maniskip;
+
+Returns the location of the installed MANIFEST.SKIP file used by
+default.
+
+=end private
+
+=cut
+
+sub _default_maniskip {
+ my $self = shift;
+
+ my $default_maniskip;
+ for my $dir (@INC) {
+ $default_maniskip = File::Spec->catfile($dir, "ExtUtils", "MANIFEST.SKIP");
+ last if -r $default_maniskip;
+ }
+
+ return $default_maniskip;
+}
+
+
+=begin private
+
+ my $content = $build->_slurp($file);
+
+Reads $file and returns the $content.
+
+=end private
+
+=cut
+
+sub _slurp {
+ my $self = shift;
+ my $file = shift;
+ open my $fh, "<", $file or croak "Can't open $file: $!";
+ local $/;
+ return <$fh>;
+}
+
+
sub _write_default_maniskip {
my $self = shift;
my $file = shift || 'MANIFEST.SKIP';
my $fh = IO::File->new("> $file")
or die "Can't open $file: $!";
- # This is derived from MakeMaker's default MANIFEST.SKIP file with
- # some new entries
-
- print $fh <<'EOF';
-# Avoid version control files.
-\bRCS\b
-\bCVS\b
-,v$
-\B\.svn\b
-\B\.cvsignore$
-
-# Avoid Makemaker generated and utility files.
-\bMakefile$
-\bblib
-\bMakeMaker-\d
-\bpm_to_blib$
-\bblibdirs$
-^MANIFEST\.SKIP$
-
-# Avoid VMS specific Makmaker generated files
-\bDescrip.MMS$
-\bDESCRIP.MMS$
-\bdescrip.mms$
+ my $content = $self->_eumanifest_has_include ? "#!include_default\n"
+ : $self->_slurp( $self->_default_maniskip );
+
+ $content .= <<'EOF';
# Avoid Module::Build generated and utility files.
\bBuild$
\bBUILD.COM$
\bbuild.com$
-# Avoid Devel::Cover generated files
-\bcover_db
-
-# Avoid temp and backup files.
-~$
-\.tmp$
-\.old$
-\.bak$
-\#$
-\.#
-\.rej$
-
-# Avoid OS-specific files/dirs
-# Mac OSX metadata
-\B\.DS_Store
-# Mac OSX SMB mount metadata files
-\B\._
# Avoid archives of this distribution
EOF
# Skip, for example, 'Module-Build-0.27.tar.gz'
- print $fh '\b'.$self->dist_name.'-[\d\.\_]+'."\n";
+ $content .= '\b'.$self->dist_name.'-[\d\.\_]+'."\n";
+
+ print $fh $content;
- $fh->close();
+ return;
}
sub ACTION_manifest {
ExtUtils::Manifest::mkmanifest();
}
-# Case insenstive regex for files
+# Case insensitive regex for files
sub file_qr {
return File::Spec->case_tolerant ? qr($_[0])i : qr($_[0]);
}
return $_ = {$_ => 1};
}
- return $_ = { map {$_,1} $self->_files_in('bin') };
+ my %pl_files = map { File::Spec->canonpath($_) => 1 }
+ keys %{ $self->PL_files || {} };
+ return $_ = { map {$_ => 1} grep !$pl_files{$_}, $self->_files_in('bin') };
}
BEGIN { *scripts = \&script_files; }
}
elsif ( ref $version eq 'version' ||
ref $version eq 'Module::Build::Version' ) { # version objects
- my $string = $version->stringify;
- # normalize leading-v: "v1.2" -> "v1.2.0"
- $version = substr($string,0,1) eq 'v' ? $version->normal : $string;
+ $version = $version->is_qv ? $version->normal : $version->stringify;
}
elsif ( $version =~ /^[^v][^.]*\.[^.]+\./ ) { # no leading v, multiple dots
# normalize string tuples without "v": "1.2.3" -> "v1.2.3"
# XXX we are silently omitting the url for any unknown license
}
- if (exists $p->{configure_requires}) {
- foreach my $spec (keys %{$p->{configure_requires}}) {
- warn ("Warning: $spec is listed in 'configure_requires', but ".
- "it is not found in any of the other prereq fields.\n")
- unless grep exists $p->{$_}{$spec},
- grep !/conflicts$/, @{$self->prereq_action_types};
- }
- }
-
# copy prereq data structures so we can modify them before writing to META
my %prereq_types;
for my $type ( 'configure_requires', @{$self->prereq_action_types} ) {
}
# add current Module::Build to configure_requires if there
- # isn't a configure_requires already specified
- if ( ! $prereq_types{'configure_requires'} ) {
- for my $t ('configure_requires', 'build_requires') {
- $prereq_types{$t}{'Module::Build'} = $VERSION;
- }
+ # isn't one already specified (but not ourself, so we're not circular)
+ if ( $self->dist_name ne 'Module-Build'
+ && $self->auto_configure_requires
+ && ! exists $prereq_types{'configure_requires'}{'Module::Build'}
+ ) {
+ $prereq_types{configure_requires}{'Module::Build'} = $VERSION;
}
for my $t ( keys %prereq_types ) {
my @pm_files = grep {exists $dist_files{$_}} keys %{ $self->find_pm_files };
# First, we enumerate all packages & versions,
- # seperating into primary & alternative candidates
+ # separating into primary & alternative candidates
my( %prime, %alt );
foreach my $file (@pm_files) {
next if $dist_files{$file} =~ m{^t/}; # Skip things in t/
if ( $result->{err} ) {
# Use the selected primary package, but there are conflicting
- # errors amoung multiple alternative packages that need to be
+ # errors among multiple alternative packages that need to be
# reported
$self->log_warn(
"Found conflicting versions for package '$package'\n" .
return \%prime;
}
-# seperate out some of the conflict resolution logic from
+# separate out some of the conflict resolution logic from
# $self->find_dist_packages(), above, into a helper function.
#
sub _resolve_module_versions {
}
sub link_c {
- my ($self, $to, $file_base) = @_;
+ my ($self, $spec) = @_;
my $p = $self->{properties}; # For convenience
- my $spec = $self->_infer_xs_spec($file_base);
-
$self->add_to_cleanup($spec->{lib_file});
my $objects = $p->{objects} || [];
if $self->up_to_date([$spec->{obj_file}, @$objects],
$spec->{lib_file});
- my $module_name = $self->module_name;
- $module_name ||= $spec->{module_name};
+ my $module_name = $spec->{module_name} || $self->module_name;
$self->cbuilder->link(
module_name => $module_name,
}
# .o -> .(a|bundle)
- $self->link_c($spec->{archdir}, $file_base);
+ $self->link_c($spec);
}
sub do_system {
$source = [$source] unless ref $source;
$derived = [$derived] unless ref $derived;
- return 0 if grep {not -e} @$derived;
+ # empty $derived means $source should always run
+ return 0 if @$source && !@$derived || grep {not -e} @$derived;
my $most_recent_source = time / (24*60*60);
foreach my $file (@$source) {
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
+use File::Basename ();
use File::Spec;
use IO::File;
use Config;
# Convert INSTALLVENDORLIB and friends.
(
map {
- my $name = "INSTALL".$_."LIB";
+ my $name = $_;
$name => sub {
- my @ret = (config => { lc $name => shift });
+ my @ret = (config => lc($name) . "=" . shift );
print STDERR "# Converted to @ret\n";
return @ret;
}
- } keys %convert_installdirs
+ } qw(
+ INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH
+ INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB
+ INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN
+ INSTALLSCRIPT INSTALLSITESCRIPT INSTALLVENDORSCRIPT
+ INSTALLMAN1DIR INSTALLSITEMAN1DIR INSTALLVENDORMAN1DIR
+ INSTALLMAN3DIR INSTALLSITEMAN3DIR INSTALLVENDORMAN3DIR
+ )
),
# Some names they have in common
%prereq = ( %{$build->requires}, %{$build->build_requires} );
%prereq = map {$_, $prereq{$_}} sort keys %prereq;
- delete $prereq{perl};
+ delete $prereq{perl};
$MM_Args{PREREQ_PM} = \%prereq;
$MM_Args{INSTALLDIRS} = $build->installdirs eq 'core' ? 'perl' : $build->installdirs;
$MM_Args{EXE_FILES} = [ sort keys %{$build->script_files} ] if $build->script_files;
$MM_Args{PL_FILES} = $build->PL_files || {};
-
+
+ if ($build->recursive_test_files) {
+ $MM_Args{TESTS} = join q{ }, $package->_test_globs($build);
+ }
+
local $Data::Dumper::Terse = 1;
my $args = Data::Dumper::Dumper(\%MM_Args);
$args =~ s/\{(.*)\}/($1)/s;
}
}
+sub _test_globs {
+ my ($self, $build) = @_;
+
+ return map { File::Spec->catfile($_, '*.t') }
+ @{$build->rscan_dir('t', sub { -d $File::Find::name })};
+}
sub subclass_dir {
my ($self, $build) = @_;
sub makefile_to_build_macros {
my @out;
+ my %config; # must accumulate and return as a hashref
while (my ($macro, $trans) = each %macro_to_build) {
# On some platforms (e.g. Cygwin with 'make'), the mere presence
# of "EXPORT: FOO" in the Makefile will make $ENV{FOO} defined.
# Therefore we check length() too.
next unless exists $ENV{$macro} && length $ENV{$macro};
my $val = $ENV{$macro};
- push @out, ref($trans) ? $trans->($val) : ($trans => $val);
+ my @args = ref($trans) ? $trans->($val) : ($trans => $val);
+ while (@args) {
+ my ($k, $v) = splice(@args, 0, 2);
+ if ( $k eq 'config' ) {
+ if ( $v =~ /^([^=]+)=(.*)$/ ) {
+ $config{$1} = $2;
+ }
+ else {
+ warn "Couldn't parse config '$v'\n";
+ }
+ }
+ else {
+ push @out, ($k => $v);
+ }
+ }
}
+ push @out, (config => \%config) if %config;
return @out;
}
1;
__END__
+=for :stopwords passthrough
=head1 NAME
=head1 DESCRIPTION
-Because ExtUtils::MakeMaker has been the standard way to distribute
+Because C<ExtUtils::MakeMaker> has been the standard way to distribute
modules for a long time, many tools (CPAN.pm, or your system
-administrator) may expect to find a working Makefile.PL in every
+administrator) may expect to find a working F<Makefile.PL> in every
distribution they download from CPAN. If you want to throw them a
-bone, you can use Module::Build::Compat to automatically generate a
-Makefile.PL for you, in one of several different styles.
+bone, you can use C<Module::Build::Compat> to automatically generate a
+F<Makefile.PL> for you, in one of several different styles.
-Module::Build::Compat also provides some code that helps out the
-Makefile.PL at runtime.
+C<Module::Build::Compat> also provides some code that helps out the
+F<Makefile.PL> at runtime.
=head1 METHODS
=item create_makefile_pl($style, $build)
-Creates a Makefile.PL in the current directory in one of several
-styles, based on the supplied Module::Build object C<$build>. This is
+Creates a F<Makefile.PL> in the current directory in one of several
+styles, based on the supplied C<Module::Build> object C<$build>. This is
typically controlled by passing the desired style as the
-C<create_makefile_pl> parameter to Module::Build's C<new()> method;
-the Makefile.PL will then be automatically created during the
+C<create_makefile_pl> parameter to C<Module::Build>'s C<new()> method;
+the F<Makefile.PL> will then be automatically created during the
C<distdir> action.
The currently supported styles are:
=item small
-A small Makefile.PL will be created that passes all functionality
-through to the Build.PL script in the same directory. The user must
-already have Module::Build installed in order to use this, or else
+A small F<Makefile.PL> will be created that passes all functionality
+through to the F<Build.PL> script in the same directory. The user must
+already have C<Module::Build> installed in order to use this, or else
they'll get a module-not-found error.
=item passthrough
-This is just like the C<small> option above, but if Module::Build is
+This is just like the C<small> option above, but if C<Module::Build> is
not already installed on the user's system, the script will offer to
use C<CPAN.pm> to download it and install it before continuing with
the build.
=item traditional
-A Makefile.PL will be created in the "traditional" style, i.e. it will
+A F<Makefile.PL> will be created in the "traditional" style, i.e. it will
use C<ExtUtils::MakeMaker> and won't rely on C<Module::Build> at all.
-In order to create the Makefile.PL, we'll include the C<requires> and
+In order to create the F<Makefile.PL>, we'll include the C<requires> and
C<build_requires> dependencies as the C<PREREQ_PM> parameter.
You don't want to use this style if during the C<perl Build.PL> stage
you ask the user questions, or do some auto-sensing about the user's
-environment, or if you subclass Module::Build to do some
-customization, because the vanilla Makefile.PL won't do any of that.
+environment, or if you subclass C<Module::Build> to do some
+customization, because the vanilla F<Makefile.PL> won't do any of that.
=back
=item run_build_pl(args => \@ARGV)
-This method runs the Build.PL script, passing it any arguments the
+This method runs the F<Build.PL> script, passing it any arguments the
user may have supplied to the C<perl Makefile.PL> command. Because
-ExtUtils::MakeMaker and Module::Build accept different arguments, this
+C<ExtUtils::MakeMaker> and C<Module::Build> accept different arguments, this
method also performs some translation between the two.
C<run_build_pl()> accepts the following named parameters:
=item write_makefile()
-This method writes a 'dummy' Makefile that will pass all commands
-through to the corresponding Module::Build actions.
+This method writes a 'dummy' F<Makefile> that will pass all commands
+through to the corresponding C<Module::Build> actions.
C<write_makefile()> accepts the following named parameters:
=item 1.
-Just include a Build.PL script (without a Makefile.PL
-script), and give installation directions in a README or INSTALL
+Just include a F<Build.PL> script (without a F<Makefile.PL>
+script), and give installation directions in a F<README> or F<INSTALL>
document explaining how to install the module. In particular, explain
-that the user must install Module::Build before installing your
+that the user must install C<Module::Build> before installing your
module.
Note that if you do this, you may make things easier for yourself, but
=item 2.
-Include a Build.PL script and a "traditional" Makefile.PL,
+Include a F<Build.PL> script and a "traditional" F<Makefile.PL>,
created either manually or with C<create_makefile_pl()>. Users won't
-ever have to install Module::Build if they use the Makefile.PL, but
-they won't get to take advantage of Module::Build's extra features
+ever have to install C<Module::Build> if they use the F<Makefile.PL>, but
+they won't get to take advantage of C<Module::Build>'s extra features
either.
For good measure, of course, test both the F<Makefile.PL> and the
=item 3.
-Include a Build.PL script and a "pass-through" Makefile.PL
-built using Module::Build::Compat. This will mean that people can
+Include a F<Build.PL> script and a "pass-through" F<Makefile.PL>
+built using C<Module::Build::Compat>. This will mean that people can
continue to use the "old" installation commands, and they may never
notice that it's actually doing something else behind the scenes. It
will also mean that your installation process is compatible with older
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Config;
package Module::Build::Cookbook;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
=head1 NAME
=head2 Installing in the same location as ExtUtils::MakeMaker
With the introduction of C<--prefix> in Module::Build 0.28 and
-C<INSTALL_BASE> in ExtUtils::MakeMaker 6.31 its easy to get them both
+C<INSTALL_BASE> in C<ExtUtils::MakeMaker> 6.31 its easy to get them both
to install to the same locations.
First, ensure you have at least version 0.28 of Module::Build
-installed and 6.31 of ExtUtils::MakeMaker. Prior versions have
+installed and 6.31 of C<ExtUtils::MakeMaker>. Prior versions have
differing (and in some cases quite strange) installation behaviors.
The following installation flags are equivalent between
-ExtUtils::MakeMaker and Module::Build.
+C<ExtUtils::MakeMaker> and C<Module::Build>.
MakeMaker Module::Build
PREFIX=... --prefix ...
INC=... --extra_compiler_flags ...
POLLUTE=1 --extra_compiler_flags -DPERL_POLLUTE
-For example, if you are currently installing MakeMaker modules with
+For example, if you are currently installing C<MakeMaker> modules with
this command:
perl Makefile.PL PREFIX=~
where C<prefix> will place your modules.
In contrast, C<install_base> has predictable, easy to explain
-installation locations. Now that Module::Build and MakeMaker both
+installation locations. Now that C<Module::Build> and C<MakeMaker> both
have C<install_base> there is little reason to use C<prefix> other
than to preserve your existing installation locations. If you are
starting a fresh Perl installation we encourage you to use
modules are available - SVN::Notify::Config and Net::SSH;
=item 2. If the S::N::Config module is loaded, I automatically
-generate testfiles for it during Build (using the C<PL_files>
+generate test files for it during Build (using the C<PL_files>
property).
=item 3. If the C<ssh_feature> is available, I ask if the user wishes
=head2 Bundling Module::Build
Note: This section probably needs an update as the technology improves
-(see scripts/bundle.pl in the distribution).
+(see contrib/bundle.pl in the distribution).
Suppose you want to use some new-ish features of Module::Build,
e.g. newer than the version of Module::Build your users are likely to
package Module::Build::Dumper;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
# This is just a split-out of a wrapper function to do Data::Dumper
# stuff "the right way". See:
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use File::Spec;
([\$*]) # sigil - $ or *
(
( # optional leading package name
- (?:::|\')? # possibly starting like just :: (ala $::VERSION)
+ (?:::|\')? # possibly starting like just :: (Ì la $::VERSION)
(?:\w+(?:::|\'))* # Foo::Bar:: ...
)?
VERSION
$vers{$pkg} = $v;
push( @pkgs, 'main' );
- # first non-comement line in undeclared packge defines package main
+ # first non-comment line in undeclared package defines package main
} elsif ( !exists($vers{main}) && $pkg eq 'main' && $line =~ /\w+/ ) {
$need_vers = 1;
$vers{main} = '';
__END__
+=for :stopwords ModuleInfo
+
=head1 NAME
-ModuleInfo - Gather package and POD information from a perl module files
+ModuleInfo - Gather package and POD information from a perl module file
=head1 DESCRIPTION
=item new_from_file($filename, collect_pod => 1)
-Construct a ModuleInfo object given the path to a file. Takes an optional
-arguement C<collect_pod> which is a boolean that determines whether
+Construct a C<ModuleInfo> object given the path to a file. Takes an optional
+argument C<collect_pod> which is a boolean that determines whether
POD data is collected and stored for reference. POD data is not
collected by default. POD headings are always collected.
=item new_from_module($module, collect_pod => 1, inc => \@dirs)
-Construct a ModuleInfo object given a module or package name. In addition
+Construct a C<ModuleInfo> object given a module or package name. In addition
to accepting the C<collect_pod> argument as described above, this
-method accepts a C<inc> arguemnt which is a reference to an array of
+method accepts a C<inc> argument which is a reference to an array of
of directories to search for the module. If none are given, the
default is @INC.
=item find_module_by_name($module, \@dirs)
Returns the path to a module given the module or package name. A list
-of directories can be passed in as an optional paramater, otherwise
+of directories can be passed in as an optional parameter, otherwise
@INC is searched.
Can be called as either an object or a class method.
Returns the entry in C<@dirs> (or C<@INC> by default) that contains
the module C<$module>. A list of directories can be passed in as an
-optional paramater, otherwise @INC is searched.
+optional parameter, otherwise @INC is searched.
Can be called as either an object or a class method.
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Data::Dumper;
use IO::File;
while (my ($modname, $spec) = each %%p) {
my $status = Module::Build->check_installed_status($modname, $spec);
if ((!$status->{ok}) xor ($type =~ /conflicts$/)) { return 0; }
+ if ( ! eval "require $modname; 1" ) { return 0; }
}
}
return 1;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
# This code is mostly borrowed from ExtUtils::MM_Unix 6.10_03, with a
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Base;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Base;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Base;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Base;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Base;
use vars qw(@ISA);
C<Module::Build::Base> and override a few methods. Please see
L<Module::Build> for the docs.
-=head2 Overriden Methods
+=head2 Overridden Methods
=over 4
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Base;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Base;
return $self;
}
+# Open group says username should be portable filename characters,
+# but some Unix OS working with ActiveDirectory wind up with user-names
+# with back-slashes in the name. The new code below is very liberal
+# in what it accepts.
sub _detildefy {
my ($self, $value) = @_;
- $value =~ s[^~(\w[-\w]*)?(?=/|$)] # tilde with optional username
+ $value =~ s[^~([^/]+)?(?=/|$)] # tilde with optional username
[$1 ?
((getpwnam $1)[7] || "~$1") :
($ENV{HOME} || (getpwuid $>)[7])
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Base;
use vars qw(@ISA);
@ISA = qw(Module::Build::Base);
+# Need to look up the feature settings. The preferred way is to use the
+# VMS::Feature module, but that may not be available to dual life modules.
+
+my $use_feature;
+BEGIN {
+ if (eval { local $SIG{__DIE__}; require VMS::Feature; }) {
+ $use_feature = 1;
+ }
+}
+
+# Need to look up the UNIX report mode. This may become a dynamic mode
+# in the future.
+sub _unix_rpt {
+ my $unix_rpt;
+ if ($use_feature) {
+ $unix_rpt = VMS::Feature::current("filename_unix_report");
+ } else {
+ my $env_unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
+ $unix_rpt = $env_unix_rpt =~ /^[ET1]/i;
+ }
+ return $unix_rpt;
+}
+
+# Need to look up the EFS character set mode. This may become a dynamic
+# mode in the future.
+sub _efs {
+ my $efs;
+ if ($use_feature) {
+ $efs = VMS::Feature::current("efs_charset");
+ } else {
+ my $env_efs = $ENV{'DECC$EFS_CHARSET'} || '';
+ $efs = $env_efs =~ /^[ET1]/i;
+ }
+ return $efs;
+}
+
=head1 NAME
# Remove the tilde
$spec =~ s/^~//;
- # Remove any slash folloing the tilde if present.
+ # Remove any slash following the tilde if present.
$spec =~ s#^/##;
# break up the paths for the merge
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Base;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Config;
my $basename = basename($0);
$basename =~ s/(?:\.bat)?$//i;
- if ( $basename eq $self->build_script ) {
+ if ( lc $basename eq lc $self->build_script ) {
if ( $self->build_bat ) {
+ $self->log_info("Deleting $basename.bat\n");
my $full_progname = $0;
$full_progname =~ s/(?:\.bat)?$/.bat/i;
- # Vodoo required to have a batch file delete itself without error;
+ # Voodoo required to have a batch file delete itself without error;
# Syntax differs between 9x & NT: the later requires a null arg (???)
require Win32;
my $null_arg = (Win32::IsWinNT()) ? '""' : '';
}
# This routine was copied almost verbatim from the 'pl2bat' utility
-# distributed with perl. It requires too much vodoo with shell quoting
+# distributed with perl. It requires too much voodoo with shell quoting
# differences and shortcomings between the various flavors of Windows
# to reliably shell out
sub pl2bat {
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
use strict;
use vars qw($VERSION);
-$VERSION = '0.33_02';
+$VERSION = '0.33_05';
$VERSION = eval $VERSION;
use vars qw(@ISA);
use strict;
use vars qw($VERSION);
-$VERSION = 0.74;
+$VERSION = 0.77;
eval "use version $VERSION";
if ($@) { # can't locate version files, use our own
use 5.005_04;
use strict;
-use vars qw(@ISA $VERSION $CLASS *qv);
+use vars qw(@ISA $VERSION $CLASS *declare *qv);
-$VERSION = 0.000;
+$VERSION = 0;
$CLASS = 'version';
push @ISA, "version::vpp";
+local $^W;
*version::qv = \&version::vpp::qv;
+*version::declare = \&version::vpp::declare;
+*version::_VERSION = \&version::vpp::_VERSION;
+if ($] > 5.009001 && $] <= 5.010000) {
+ no strict 'refs';
+ *{'version::stringify'} = \*version::vpp::stringify;
+ *{'version::(""'} = \*version::vpp::stringify;
+}
# Preloaded methods go here.
sub import {
- my ($class) = @_;
- my $callpkg = caller();
no strict 'refs';
+ my ($class) = shift;
+
+ # Set up any derived class
+ unless ($class eq 'version') {
+ local $^W;
+ *{$class.'::declare'} = \&version::declare;
+ *{$class.'::qv'} = \&version::qv;
+ }
+
+ my %args;
+ if (@_) { # any remaining terms are arguments
+ map { $args{$_} = 1 } @_
+ }
+ else { # no parameters at all on use line
+ %args =
+ (
+ qv => 1,
+ 'UNIVERSAL::VERSION' => 1,
+ );
+ }
+
+ my $callpkg = caller();
- *{$callpkg."::qv"} =
- sub {return bless version::qv(shift), $class }
- unless defined(&{"$callpkg\::qv"});
+ if (exists($args{declare})) {
+ *{$callpkg."::declare"} =
+ sub {return $class->declare(shift) }
+ unless defined(&{$callpkg.'::declare'});
+ }
+
+ if (exists($args{qv})) {
+ *{$callpkg."::qv"} =
+ sub {return $class->qv(shift) }
+ unless defined(&{"$callpkg\::qv"});
+ }
+
+ if (exists($args{'UNIVERSAL::VERSION'})) {
+ local $^W;
+ *UNIVERSAL::VERSION = \&version::_VERSION;
+ }
+ if (exists($args{'VERSION'})) {
+ *{$callpkg."::VERSION"} = \&version::_VERSION;
+ }
}
1;
+
# replace everything from here to the end with the current version/vpp.pm
package version::vpp;
use strict;
+use POSIX qw/locale_h/;
use locale;
use vars qw ($VERSION @ISA @REGEXS);
-$VERSION = 0.76;
+$VERSION = '0.77';
push @REGEXS, qr/
^v? # optional leading 'v'
my ($class, $value) = @_;
my $self = bless ({}, ref ($class) || $class);
- if ( ref($value) && eval("$value->isa('version')") ) {
+ if ( ref($value) && eval('$value->isa("version")') ) {
# Can copy the elements directly
$self->{version} = [ @{$value->{version} } ];
$self->{qv} = 1 if $value->{qv};
return $self;
}
- require POSIX;
- my $currlocale = POSIX::setlocale(&POSIX::LC_ALL);
- my $radix_comma = ( POSIX::localeconv()->{decimal_point} eq ',' );
+ my $currlocale = setlocale(LC_ALL);
+
+ # if the current locale uses commas for decimal points, we
+ # just replace commas with decimal places, rather than changing
+ # locales
+ if ( localeconv()->{decimal_point} eq ',' ) {
+ $value =~ tr/,/./;
+ }
if ( not defined $value or $value =~ /^undef$/ ) {
# RT #19517 - special case for undef comparison
$value = _un_vstring($value);
# exponential notation
- if ( $value =~ /\d+.?\d*e-?\d+/ ) {
+ if ( $value =~ /\d+.?\d*e[-+]?\d+/ ) {
$value = sprintf("%.9f",$value);
- $value =~ s/(0+)$//;
+ $value =~ s/(0+)$//; # trim trailing zeros
}
- # if the original locale used commas for decimal points, we
- # just replace commas with decimal places, rather than changing
- # locales
- if ( $radix_comma ) {
- $value =~ tr/,/./;
- }
-
# This is not very efficient, but it is morally equivalent
# to the XS code (as that is the reference implementation).
# See vutil/vutil.c for details
$start = $last = $pos = $s;
# pre-scan the input string to check for decimals/underbars
- while ( substr($value,$pos,1) =~ /[._\d]/ ) {
+ while ( substr($value,$pos,1) =~ /[._\d,]/ ) {
if ( substr($value,$pos,1) eq '.' ) {
if ($alpha) {
Carp::croak("Invalid version format ".
$alpha = 1;
$width = $pos - $last - 1; # natural width of sub-version
}
+ elsif ( substr($value,$pos,1) eq ','
+ and substr($value,$pos+1,1) =~ /[0-9]/ ) {
+ # looks like an unhandled locale
+ $saw_period++;
+ $last = $pos;
+ }
$pos++;
}
&& substr($value,$pos+1,1) =~ /\d/ ) {
$s = ++$pos;
}
+ elsif ( substr($value,$pos,1) eq ','
+ && substr($value,$pos+1,1) =~ /\d/ ) {
+ $s = ++$pos;
+ }
elsif ( substr($value,$pos,1) =~ /\d/ ) {
$s = $pos;
}
return ($self);
}
+*parse = \&new;
+
sub numify
{
my ($self) = @_;
}
sub qv {
- my ($value) = @_;
+ my $value = shift;
+ my $class = 'version';
+ if (@_) {
+ $class = ref($value) || $value;
+ $value = shift;
+ }
$value = _un_vstring($value);
$value = 'v'.$value unless $value =~ /(^v|\d+\.\d+\.\d)/;
- my $version = version->new($value); # always use base class
+ my $version = $class->new($value);
return $version;
}
+*declare = \&qv;
+
sub is_qv {
my ($self) = @_;
return (exists $self->{qv});
return $value;
}
-# Thanks to Yitzchak Scott-Thoennes for this mode of operation
-{
- local $^W;
- *UNIVERSAL::VERSION # Module::Build::ModuleInfo doesn't see this now
- = sub {
- my ($obj, $req) = @_;
- my $class = ref($obj) || $obj;
-
- no strict 'refs';
- eval "require $class" unless %{"$class\::"}; # already existing
- return undef if $@ =~ /Can't locate/ and not defined $req;
-
- if ( not %{"$class\::"} and $] >= 5.008) { # file but no package
- require Carp;
- Carp::croak( "$class defines neither package nor VERSION"
- ."--version check failed");
- }
-
- my $version = eval "\$$class\::VERSION";
- if ( defined $version ) {
- local $^W if $] <= 5.008;
- $version = version::vpp->new($version);
- }
+sub _VERSION {
+ my ($obj, $req) = @_;
+ my $class = ref($obj) || $obj;
- if ( defined $req ) {
- unless ( defined $version ) {
- require Carp;
- my $msg = $] < 5.006
- ? "$class version $req required--this is only version "
- : "$class does not define \$$class\::VERSION"
- ."--version check failed";
+ no strict 'refs';
+ eval "require $class" unless %{"$class\::"}; # already existing
+ return undef if $@ =~ /Can't locate/ and not defined $req;
+
+ if ( not %{"$class\::"} and $] >= 5.008) { # file but no package
+ require Carp;
+ Carp::croak( "$class defines neither package nor VERSION"
+ ."--version check failed");
+ }
+
+ my $version = eval "\$$class\::VERSION";
+ if ( defined $version ) {
+ local $^W if $] <= 5.008;
+ $version = version::vpp->new($version);
+ }
- if ( $ENV{VERSION_DEBUG} ) {
- Carp::confess($msg);
- }
- else {
- Carp::croak($msg);
- }
+ if ( defined $req ) {
+ unless ( defined $version ) {
+ require Carp;
+ my $msg = $] < 5.006
+ ? "$class version $req required--this is only version "
+ : "$class does not define \$$class\::VERSION"
+ ."--version check failed";
+
+ if ( $ENV{VERSION_DEBUG} ) {
+ Carp::confess($msg);
+ }
+ else {
+ Carp::croak($msg);
}
+ }
- $req = version::vpp->new($req);
+ $req = version::vpp->new($req);
- if ( $req > $version ) {
- require Carp;
- if ( $req->is_qv ) {
- Carp::croak(
- sprintf ("%s version %s required--".
- "this is only version %s", $class,
- $req->normal, $version->normal)
- );
- }
- else {
- Carp::croak(
- sprintf ("%s version %s required--".
- "this is only version %s", $class,
- $req->stringify, $version->stringify)
- );
- }
+ if ( $req > $version ) {
+ require Carp;
+ if ( $req->is_qv ) {
+ Carp::croak(
+ sprintf ("%s version %s required--".
+ "this is only version %s", $class,
+ $req->normal, $version->normal)
+ );
+ }
+ else {
+ Carp::croak(
+ sprintf ("%s version %s required--".
+ "this is only version %s", $class,
+ $req->stringify, $version->stringify)
+ );
}
}
+ }
- return defined $version ? $version->stringify : undef;
- };
+ return defined $version ? $version->stringify : undef;
}
1; #this line is important and will help the module return a true value
}
open my $OUT, "$mode $filename"
or die "Can't open $filename for writing: $!";
+ binmode($OUT, ':utf8') if $] >= 5.008;
print $OUT Dump(@_);
close $OUT;
}
my $filename = shift;
open my $IN, $filename
or die "Can't open $filename for reading: $!";
+ binmode($IN, ':utf8') if $] >= 5.008;
return Load(do { local $/; <$IN> });
close $IN;
-}
+}
sub _yaml_chunk {
my ($indent, $values) = @_;
Provides just enough YAML support so that Module::Build works even if YAML.pm is not installed.
-Currently, this amounts to the ability to write META.yml files when "perl Build distmeta"
+Currently, this amounts to the ability to write META.yml files when C<perl Build distmeta>
is executed via the Dump() and DumpFile() functions/methods.
=head1 AUTHOR
--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib';
+use MBTest tests => 8;
+use DistGen;
+use Module::Build;
+
+my $dist;
+
+# Test that PL files don't get installed even in bin or lib
+{
+ $dist = DistGen->new( dir => MBTest->tmpdir );
+ $dist->regen;
+ $dist->chdir_in;
+
+ my $distname = $dist->name;
+ $dist->change_build_pl({
+ module_name => $distname,
+ PL_files => {
+ 'bin/foo.PL' => 'bin/foo',
+ 'lib/Bar.pm.PL' => 'lib/Bar.pm',
+ },
+ });
+
+ $dist->add_file("bin/foo.PL", <<'END');
+open my $fh, ">", $ARGV[0] or die $!;
+print $fh "foo\n";
+END
+
+ $dist->add_file("lib/Bar.pm.PL", <<'END');
+open my $fh, ">", $ARGV[0] or die $!;
+print $fh "bar\n";
+END
+
+ $dist->regen;
+
+ my $mb = Module::Build->new_from_context( install_base => "test_install" );
+ $mb->dispatch("install");
+
+ ok -e "test_install/bin/foo", "Generated PL_files installed from bin";
+ ok -e "test_install/lib/perl5/Bar.pm", " and from lib";
+
+ ok !-e "test_install/bin/foo.PL", "PL_files not installed from bin";
+ ok !-e "test_install/lib/perl5/Bar.pm.PL", " nor from lib";
+
+ is slurp("test_install/bin/foo"), "foo\n", "Generated bin contains correct content";
+ is slurp("test_install/lib/perl5/Bar.pm"), "bar\n", " so does the lib";
+
+ $dist->chdir_original if $dist->did_chdir;
+}
+
+# Test an empty PL target list runs the PL but doesn't
+# add it to MANIFEST or cleanup
+{
+ $dist = DistGen->new( dir => MBTest->tmpdir );
+ $dist->regen;
+ $dist->chdir_in;
+
+ my $distname = $dist->name;
+ $dist->change_build_pl({
+ module_name => $distname,
+ PL_files => {
+ 'Special.PL' => [],
+ },
+ });
+
+ $dist->add_file("Special.PL", <<'END');
+open my $fh, ">", "foo" or die $!;
+print $fh "foo\n";
+END
+
+ $dist->regen;
+
+ my $mb = Module::Build->new_from_context();
+ $mb->dispatch("code");
+
+ ok( -f "foo", "special PL file ran" );
+
+ my $cleanup = $mb->cleanup;
+
+ my %cleanup = map { $_ => 1 } $mb->cleanup;
+ is($cleanup{foo}, undef, "generated special file not added to cleanup");
+
+
+}
use strict;
use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib';
-use MBTest tests => 52;
+use MBTest tests => 60;
use_ok 'Module::Build';
ensure_blib('Module::Build');
is_deeply $mb->extra_linker_flags, ['-L/foo', '-L/bar'], "Should split shell string into list";
}
+# Test include_dirs.
+{
+ ok my $mb = Module::Build->new(
+ module_name => $dist->name,
+ include_dirs => [qw(/foo /bar)],
+ );
+ is_deeply $mb->include_dirs, ['/foo', '/bar'], 'Should have include dirs';
+
+ # Try a string.
+ ok $mb = Module::Build->new(
+ module_name => $dist->name,
+ include_dirs => '/foo',
+ );
+ is_deeply $mb->include_dirs, ['/foo'], 'Should have string include dir';
+
+ # Try again with command-line args
+ eval { Module::Build->run_perl_script(
+ 'Build.PL', [],
+ ['--include_dirs', '/foo', '--include_dirs', '/bar' ],
+ ) };
+
+ ok $mb = Module::Build->resume;
+ is_deeply $mb->include_dirs, ['/foo', '/bar'], 'Should have include dirs';
+
+ eval { Module::Build->run_perl_script(
+ 'Build.PL', [],
+ ['--include_dirs', '/foo' ],
+ ) };
+
+ ok $mb = Module::Build->resume;
+ is_deeply $mb->include_dirs, ['/foo'], 'Should have single include dir';
+}
# cleanup
$dist->remove;
'Should be non-verbose';
(my $libdir2 = $libdir) =~ s/libdir/lbiidr/;
+ my $libarch2 = File::Spec->catdir($libdir2, 'arch');
SKIP: {
require ExtUtils::Install;
skip "Needs ExtUtils::Install 1.32 or later", 2
if ExtUtils::Install->VERSION < 1.32;
- my @make_args = ('INSTALLDIRS=vendor', "INSTALLVENDORLIB=$libdir2");
+ my @make_args = ('INSTALLDIRS=vendor', "INSTALLVENDORLIB=$libdir2", "INSTALLVENDORARCH=$libarch2");
if ($is_vms_mms) { # VMS MMK/MMS macros use different syntax.
$make_args[0] = '/macro=("' . join('","',@make_args) . '")';
ok ! -e 'Makefile.PL', "Makefile.PL cleaned up";
}
+{
+ $dist->add_file('t/deep/foo.t', q{});
+ $dist->regen;
+
+ my $mb;
+ stdout_of( sub {
+ $mb = Module::Build->new_from_context( recursive_test_files => 1 );
+ });
+
+ create_makefile_pl('traditional', $mb);
+ my $args = extract_writemakefile_args() || {};
+ is $args->{TESTS},
+ join( q{ },
+ File::Spec->catfile(qw(t *.t)),
+ File::Spec->catfile(qw(t deep *.t))
+ ),
+ 'Makefile.PL has correct TESTS line for recursive test files';
+}
+
# cleanup
$dist->remove;
use Tie::CPHash;
use Data::Dumper;
+my $vms_mode;
+my $vms_lower_case;
+
BEGIN {
+ $vms_mode = 0;
+ $vms_lower_case = 0;
if( $^O eq 'VMS' ) {
# For things like vmsify()
require VMS::Filespec;
VMS::Filespec->import;
+ $vms_mode = 1;
+ $vms_lower_case = 1;
+ my $vms_efs_case = 0;
+ my $unix_rpt = 0;
+ if (eval { local $SIG{__DIE__}; require VMS::Feature; }) {
+ $unix_rpt = VMS::Feature::current("filename_unix_report");
+ $vms_efs_case = VMS::Feature::current("efs_case_preserve");
+ } else {
+ my $env_unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
+ $unix_rpt = $env_unix_rpt =~ /^[ET1]/i;
+ my $efs_case = $ENV{'DECC$EFS_CASE_PRESERVE'} || '';
+ $vms_efs_case = $efs_case =~ /^[ET1]/i;
+ }
+ $vms_mode = 0 if $unix_rpt;
+ $vms_lower_case = 0 if $vms_efs_case;
}
}
BEGIN {
if ( $opts{clean} ) {
$self->clean() if -d $dist_dirname;
} else {
- # TODO: This might leave dangling directories. Eg if the removed file
- # is 'lib/Simple/Simon.pm', The directory 'lib/Simple' will be left
+ # TODO: This might leave dangling directories; e.g. if the removed file
+ # is 'lib/Simple/Simon.pm', the directory 'lib/Simple' will be left
# even if there are no files left in it. However, clean() will remove it.
my @files = keys %{$self->{pending}{remove}};
foreach my $file ( @files ) {
tie %names, 'Tie::CPHash';
foreach my $file ( keys %{$self->{filedata}} ) {
my $filename = $self->_real_filename( $file );
+ $filename = lc($filename) if $vms_lower_case;
my $dirname = File::Basename::dirname( $filename );
$names{$filename} = 0;
File::Find::finddepth( sub {
my $name = File::Spec->canonpath( $File::Find::name );
+ if ($vms_mode) {
+ if ($name ne '.') {
+ $name =~ s/\.\z//;
+ $name = vmspath($name) if -d $name;
+ }
+ }
if ($^O eq 'VMS') {
- $name =~ s/\.\z//;
- $name = vmspath($name) if -d $name;
$name = File::Spec->rel2abs($name) if $name eq File::Spec->curdir();
}
print "Removing '$name'\n" if $VERBOSE;
File::Path::rmtree( $_ );
}
- }, ($^O eq "VMS" ? './' : File::Spec->curdir) );
+ }, ($^O eq 'VMS' ? './' : File::Spec->curdir) );
chdir( $here );
}
=head2 Editing Files
Note that C<$filename> should always be specified with unix-style paths,
-and are relative to the distribution root directory. Eg 'lib/Module.pm'
+and are relative to the distribution root directory, e.g. C<lib/Module.pm>.
No filesystem action is performed until the distribution is regenerated.
use strict;
use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib';
-use MBTest tests => 51;
+use MBTest tests => 53;
use_ok 'Module::Build';
ensure_blib('Module::Build');
# Test for valid META.yml
{
+ my $mb_prereq = { 'Module::Build' => $Module::Build::VERSION };
my $node = $mb->prepare_metadata( {} );
# exists() doesn't seem to work here
is $node->{abstract}, $metadata{dist_abstract};
is_deeply $node->{author}, $metadata{dist_author};
is $node->{license}, $metadata{license};
+ is_deeply $node->{configure_requires}, $mb_prereq, 'Add M::B to configure_requires';
like $node->{generated_by}, qr{Module::Build};
ok defined( $node->{'meta-spec'}{version} ),
"'meta-spec' -> 'version' field present in META.yml";
is_deeply $node->{resources}, $metadata{meta_add}{resources};
}
+{
+ my $mb_prereq = { 'Module::Build' => 0 };
+ $mb->configure_requires( $mb_prereq );
+ my $node = $mb->prepare_metadata( {} );
+
+
+ # exists() doesn't seem to work here
+ is_deeply $node->{configure_requires}, $mb_prereq, 'Add M::B to configure_requires';
+}
+
$dist->clean;
---
$dist->regen;
my $provides = new_build()->prepare_metadata()->{provides};
- is $provides->{'Simple'}{version}, '0.60.128', "Check version";
- is $provides->{'Simple::Simon'}{version}, '0.61.129', "Check version";
+ is $provides->{'Simple'}{version}, 'v0.60.128', "Check version";
+ is $provides->{'Simple::Simon'}{version}, 'v0.61.129', "Check version";
is ref($provides->{'Simple'}{version}), '', "Versions from prepare_metadata() aren't refs";
is ref($provides->{'Simple::Simon'}{version}), '', "Versions from prepare_metadata() aren't refs";
}
package Simple;
our $VERSION = '1.23';
---
- <<'---', # declared & defined on seperate lines with 'our'
+ <<'---', # declared & defined on separate lines with 'our'
package Simple;
our $VERSION;
$VERSION = '1.23';
use Module::Build;
use Module::Build::ConfigData;
+use Config;
my $manpage_support = Module::Build::ConfigData->feature('manpage_support');
my $HTML_support = Module::Build::ConfigData->feature('HTML_support');
plan skip_all => 'C_support not enabled';
} elsif ( ! $have_c_compiler ) {
plan skip_all => 'C_support enabled, but no compiler found';
+ } elsif ( !$Config{usedl} ) {
+ plan skip_all => 'Perl not compiled for dynamic loading'
} elsif ( ! eval {require Archive::Tar} ) {
plan skip_all => "Archive::Tar not installed to read archives.";
} elsif ( ! eval {IO::Zlib->VERSION(1.01)} ) {
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib';
+use MBTest 'no_plan';
+
+use_ok 'Module::Build';
+ensure_blib 'Module::Build';
+
+{
+ chdir MBTest->tmpdir();
+
+ my $build = Module::Build->new(
+ dist_name => "Foo-Bar",
+ dist_version => '1.23',
+ );
+
+ my $skip = "mskip.txt"; # for compatibility
+ $build->_write_default_maniskip($skip);
+
+ ok -r $skip, "Default maniskip written";
+ my $have = slurp($skip);
+
+ my $head;
+ if( $build->_eumanifest_has_include ) {
+ $head = "#!include_default\n";
+ }
+ else {
+ $head = slurp($build->_default_maniskip);
+ }
+
+ like $have, qr/^\Q$head\E/, "default MANIFEST.SKIP used";
+ like $have, qr/^# Avoid Module::Build generated /ms, "Module::Build specific entries";
+ like $have, qr/Foo-Bar-/, "distribution tarball entry";
+}
use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib';
use MBTest;
use Module::Build;
+use Config;
{
my ($have_c_compiler, $C_support_feature) = check_compiler();
plan skip_all => 'C_support enabled, but no compiler found';
} elsif ( $^O eq 'VMS' ) {
plan skip_all => 'Child test output confuses harness';
+ } elsif ( !$Config{usedl} ) {
+ plan skip_all => 'Perl not compiled for dynamic loading'
} else {
plan tests => 23;
}