668 lines
20 KiB
Plaintext
668 lines
20 KiB
Plaintext
package ExtUtils::MakeMaker::FAQ;
|
|
|
|
our $VERSION = '7.70';
|
|
$VERSION =~ tr/_//d;
|
|
|
|
1;
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
ExtUtils::MakeMaker::FAQ - Frequently Asked Questions About MakeMaker
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
FAQs, tricks and tips for L<ExtUtils::MakeMaker>.
|
|
|
|
|
|
=head2 Module Installation
|
|
|
|
=over 4
|
|
|
|
=item How do I install a module into my home directory?
|
|
|
|
If you're not the Perl administrator you probably don't have
|
|
permission to install a module to its default location. Ways of handling
|
|
this with a B<lot> less manual effort on your part are L<perlbrew>
|
|
and L<local::lib>.
|
|
|
|
Otherwise, you can install it for your own use into your home directory
|
|
like so:
|
|
|
|
# Non-unix folks, replace ~ with /path/to/your/home/dir
|
|
perl Makefile.PL INSTALL_BASE=~
|
|
|
|
This will put modules into F<~/lib/perl5>, man pages into F<~/man> and
|
|
programs into F<~/bin>.
|
|
|
|
To ensure your Perl programs can see these newly installed modules,
|
|
set your C<PERL5LIB> environment variable to F<~/lib/perl5> or tell
|
|
each of your programs to look in that directory with the following:
|
|
|
|
use lib "$ENV{HOME}/lib/perl5";
|
|
|
|
or if $ENV{HOME} isn't set and you don't want to set it for some
|
|
reason, do it the long way.
|
|
|
|
use lib "/path/to/your/home/dir/lib/perl5";
|
|
|
|
=item How do I get MakeMaker and Module::Build to install to the same place?
|
|
|
|
Module::Build, as of 0.28, supports two ways to install to the same
|
|
location as MakeMaker.
|
|
|
|
We highly recommend the install_base method, its the simplest and most
|
|
closely approximates the expected behavior of an installation prefix.
|
|
|
|
1) Use INSTALL_BASE / C<--install_base>
|
|
|
|
MakeMaker (as of 6.31) and Module::Build (as of 0.28) both can install
|
|
to the same locations using the "install_base" concept. See
|
|
L<ExtUtils::MakeMaker/INSTALL_BASE> for details. To get MM and MB to
|
|
install to the same location simply set INSTALL_BASE in MM and
|
|
C<--install_base> in MB to the same location.
|
|
|
|
perl Makefile.PL INSTALL_BASE=/whatever
|
|
perl Build.PL --install_base /whatever
|
|
|
|
This works most like other language's behavior when you specify a
|
|
prefix. We recommend this method.
|
|
|
|
2) Use PREFIX / C<--prefix>
|
|
|
|
Module::Build 0.28 added support for C<--prefix> which works like
|
|
MakeMaker's PREFIX.
|
|
|
|
perl Makefile.PL PREFIX=/whatever
|
|
perl Build.PL --prefix /whatever
|
|
|
|
We highly discourage this method. It should only be used if you know
|
|
what you're doing and specifically need the PREFIX behavior. The
|
|
PREFIX algorithm is complicated and focused on matching the system
|
|
installation.
|
|
|
|
=item How do I keep from installing man pages?
|
|
|
|
Recent versions of MakeMaker will only install man pages on Unix-like
|
|
operating systems by default. To generate manpages on non-Unix operating
|
|
systems, make the "manifypods" target.
|
|
|
|
For an individual module:
|
|
|
|
perl Makefile.PL INSTALLMAN1DIR=none INSTALLMAN3DIR=none
|
|
|
|
If you want to suppress man page installation for all modules you have
|
|
to reconfigure Perl and tell it 'none' when it asks where to install
|
|
man pages.
|
|
|
|
|
|
=item How do I use a module without installing it?
|
|
|
|
Two ways. One is to build the module normally...
|
|
|
|
perl Makefile.PL
|
|
make
|
|
make test
|
|
|
|
...and then use L<blib> to point Perl at the built but uninstalled module:
|
|
|
|
perl -Mblib script.pl
|
|
perl -Mblib -e '...'
|
|
|
|
The other is to install the module in a temporary location.
|
|
|
|
perl Makefile.PL INSTALL_BASE=~/tmp
|
|
make
|
|
make test
|
|
make install
|
|
|
|
And then set PERL5LIB to F<~/tmp/lib/perl5>. This works well when you
|
|
have multiple modules to work with. It also ensures that the module
|
|
goes through its full installation process which may modify it.
|
|
Again, L<local::lib> may assist you here.
|
|
|
|
=item How can I organize tests into subdirectories and have them run?
|
|
|
|
Let's take the following test directory structure:
|
|
|
|
t/foo/sometest.t
|
|
t/bar/othertest.t
|
|
t/bar/baz/anothertest.t
|
|
|
|
Now, inside of the C<WriteMakefile()> function in your F<Makefile.PL>, specify
|
|
where your tests are located with the C<test> directive:
|
|
|
|
test => {TESTS => 't/*.t t/*/*.t t/*/*/*.t'}
|
|
|
|
The first entry in the string will run all tests in the top-level F<t/>
|
|
directory. The second will run all test files located in any subdirectory under
|
|
F<t/>. The third, runs all test files within any subdirectory within any other
|
|
subdirectory located under F<t/>.
|
|
|
|
Note that you do not have to use wildcards. You can specify explicitly which
|
|
subdirectories to run tests in:
|
|
|
|
test => {TESTS => 't/*.t t/foo/*.t t/bar/baz/*.t'}
|
|
|
|
=item PREFIX vs INSTALL_BASE from Module::Build::Cookbook
|
|
|
|
The behavior of PREFIX is complicated and depends closely on how your
|
|
Perl is configured. The resulting installation locations will vary
|
|
from machine to machine and even different installations of Perl on the
|
|
same machine. Because of this, its difficult to document where prefix
|
|
will place your modules.
|
|
|
|
In contrast, INSTALL_BASE has predictable, easy to explain installation
|
|
locations. Now that Module::Build and MakeMaker both have INSTALL_BASE
|
|
there is little reason to use PREFIX other than to preserve your existing
|
|
installation locations. If you are starting a fresh Perl installation we
|
|
encourage you to use INSTALL_BASE. If you have an existing installation
|
|
installed via PREFIX, consider moving it to an installation structure
|
|
matching INSTALL_BASE and using that instead.
|
|
|
|
=item Generating *.pm files with substitutions eg of $VERSION
|
|
|
|
If you want to configure your module files for local conditions, or to
|
|
automatically insert a version number, you can use EUMM's C<PL_FILES>
|
|
capability, where it will automatically run each F<*.PL> it finds to
|
|
generate its basename. For instance:
|
|
|
|
# Makefile.PL:
|
|
require 'common.pl';
|
|
my $version = get_version();
|
|
my @pms = qw(Foo.pm);
|
|
WriteMakefile(
|
|
NAME => 'Foo',
|
|
VERSION => $version,
|
|
PM => { map { ($_ => "\$(INST_LIB)/$_") } @pms },
|
|
clean => { FILES => join ' ', @pms },
|
|
);
|
|
|
|
# common.pl:
|
|
sub get_version { '0.04' }
|
|
sub process { my $v = get_version(); s/__VERSION__/$v/g; }
|
|
1;
|
|
|
|
# Foo.pm.PL:
|
|
require 'common.pl';
|
|
$_ = join '', <DATA>;
|
|
process();
|
|
my $file = shift;
|
|
open my $fh, '>', $file or die "$file: $!";
|
|
print $fh $_;
|
|
__DATA__
|
|
package Foo;
|
|
our $VERSION = '__VERSION__';
|
|
1;
|
|
|
|
You may notice that C<PL_FILES> is not specified above, since the default
|
|
of mapping each .PL file to its basename works well.
|
|
|
|
If the generated module were architecture-specific, you could replace
|
|
C<$(INST_LIB)> above with C<$(INST_ARCHLIB)>, although if you locate
|
|
modules under F<lib>, that would involve ensuring any C<lib/> in front
|
|
of the module location were removed.
|
|
|
|
=back
|
|
|
|
=head2 Common errors and problems
|
|
|
|
=over 4
|
|
|
|
=item "No rule to make target `/usr/lib/perl5/CORE/config.h', needed by `Makefile'"
|
|
|
|
Just what it says, you're missing that file. MakeMaker uses it to
|
|
determine if perl has been rebuilt since the Makefile was made. It's
|
|
a bit of a bug that it halts installation.
|
|
|
|
Some operating systems don't ship the CORE directory with their base
|
|
perl install. To solve the problem, you likely need to install a perl
|
|
development package such as perl-devel (CentOS, Fedora and other
|
|
Redhat systems) or perl (Ubuntu and other Debian systems).
|
|
|
|
=back
|
|
|
|
=head2 Philosophy and History
|
|
|
|
=over 4
|
|
|
|
=item Why not just use <insert other build config tool here>?
|
|
|
|
Why did MakeMaker reinvent the build configuration wheel? Why not
|
|
just use autoconf or automake or ppm or Ant or ...
|
|
|
|
There are many reasons, but the major one is cross-platform
|
|
compatibility.
|
|
|
|
Perl is one of the most ported pieces of software ever. It works on
|
|
operating systems I've never even heard of (see perlport for details).
|
|
It needs a build tool that can work on all those platforms and with
|
|
any wacky C compilers and linkers they might have.
|
|
|
|
No such build tool exists. Even make itself has wildly different
|
|
dialects. So we have to build our own.
|
|
|
|
|
|
=item What is Module::Build and how does it relate to MakeMaker?
|
|
|
|
Module::Build is a project by Ken Williams to supplant MakeMaker.
|
|
Its primary advantages are:
|
|
|
|
=over 8
|
|
|
|
=item * pure perl. no make, no shell commands
|
|
|
|
=item * easier to customize
|
|
|
|
=item * cleaner internals
|
|
|
|
=item * less cruft
|
|
|
|
=back
|
|
|
|
Module::Build was long the official heir apparent to MakeMaker. The
|
|
rate of both its development and adoption has slowed in recent years,
|
|
though, and it is unclear what the future holds for it. That said,
|
|
Module::Build set the stage for I<something> to become the heir to
|
|
MakeMaker. MakeMaker's maintainers have long said that it is a dead
|
|
end and should be kept functioning, while being cautious about extending
|
|
with new features.
|
|
|
|
=back
|
|
|
|
=head2 Module Writing
|
|
|
|
=over 4
|
|
|
|
=item How do I keep my $VERSION up to date without resetting it manually?
|
|
|
|
Often you want to manually set the $VERSION in the main module
|
|
distribution because this is the version that everybody sees on CPAN
|
|
and maybe you want to customize it a bit. But for all the other
|
|
modules in your dist, $VERSION is really just bookkeeping and all that's
|
|
important is it goes up every time the module is changed. Doing this
|
|
by hand is a pain and you often forget.
|
|
|
|
Probably the easiest way to do this is using F<perl-reversion> in
|
|
L<Perl::Version>:
|
|
|
|
perl-reversion -bump
|
|
|
|
If your version control system supports revision numbers (git doesn't
|
|
easily), the simplest way to do it automatically is to use its revision
|
|
number (you are using version control, right?).
|
|
|
|
In CVS, RCS and SVN you use $Revision$ (see the documentation of your
|
|
version control system for details). Every time the file is checked
|
|
in the $Revision$ will be updated, updating your $VERSION.
|
|
|
|
SVN uses a simple integer for $Revision$ so you can adapt it for your
|
|
$VERSION like so:
|
|
|
|
($VERSION) = q$Revision$ =~ /(\d+)/;
|
|
|
|
In CVS and RCS version 1.9 is followed by 1.10. Since CPAN compares
|
|
version numbers numerically we use a sprintf() to convert 1.9 to 1.009
|
|
and 1.10 to 1.010 which compare properly.
|
|
|
|
$VERSION = sprintf "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/g;
|
|
|
|
If branches are involved (ie. $Revision: 1.5.3.4$) it's a little more
|
|
complicated.
|
|
|
|
# must be all on one line or MakeMaker will get confused.
|
|
$VERSION = do { my @r = (q$Revision$ =~ /\d+/g); sprintf "%d."."%03d" x $#r, @r };
|
|
|
|
In SVN, $Revision$ should be the same for every file in the project so
|
|
they would all have the same $VERSION. CVS and RCS have a different
|
|
$Revision$ per file so each file will have a different $VERSION.
|
|
Distributed version control systems, such as SVK, may have a different
|
|
$Revision$ based on who checks out the file, leading to a different $VERSION
|
|
on each machine! Finally, some distributed version control systems, such
|
|
as darcs, have no concept of revision number at all.
|
|
|
|
|
|
=item What's this F<META.yml> thing and how did it get in my F<MANIFEST>?!
|
|
|
|
F<META.yml> is a module meta-data file pioneered by Module::Build and
|
|
automatically generated as part of the 'distdir' target (and thus
|
|
'dist'). See L<ExtUtils::MakeMaker/"Module Meta-Data">.
|
|
|
|
To shut off its generation, pass the C<NO_META> flag to C<WriteMakefile()>.
|
|
|
|
|
|
=item How do I delete everything not in my F<MANIFEST>?
|
|
|
|
Some folks are surprised that C<make distclean> does not delete
|
|
everything not listed in their MANIFEST (thus making a clean
|
|
distribution) but only tells them what they need to delete. This is
|
|
done because it is considered too dangerous. While developing your
|
|
module you might write a new file, not add it to the MANIFEST, then
|
|
run a C<distclean> and be sad because your new work was deleted.
|
|
|
|
If you really want to do this, you can use
|
|
C<ExtUtils::Manifest::manifind()> to read the MANIFEST and File::Find
|
|
to delete the files. But you have to be careful. Here's a script to
|
|
do that. Use at your own risk. Have fun blowing holes in your foot.
|
|
|
|
#!/usr/bin/perl -w
|
|
|
|
use strict;
|
|
|
|
use File::Spec;
|
|
use File::Find;
|
|
use ExtUtils::Manifest qw(maniread);
|
|
|
|
my %manifest = map {( $_ => 1 )}
|
|
grep { File::Spec->canonpath($_) }
|
|
keys %{ maniread() };
|
|
|
|
if( !keys %manifest ) {
|
|
print "No files found in MANIFEST. Stopping.\n";
|
|
exit;
|
|
}
|
|
|
|
find({
|
|
wanted => sub {
|
|
my $path = File::Spec->canonpath($_);
|
|
|
|
return unless -f $path;
|
|
return if exists $manifest{ $path };
|
|
|
|
print "unlink $path\n";
|
|
unlink $path;
|
|
},
|
|
no_chdir => 1
|
|
},
|
|
"."
|
|
);
|
|
|
|
|
|
=item Which tar should I use on Windows?
|
|
|
|
We recommend ptar from Archive::Tar not older than 1.66 with '-C' option.
|
|
|
|
=item Which zip should I use on Windows for '[ndg]make zipdist'?
|
|
|
|
We recommend InfoZIP: L<http://www.info-zip.org/Zip.html>
|
|
|
|
|
|
=back
|
|
|
|
=head2 XS
|
|
|
|
=over 4
|
|
|
|
=item How do I prevent "object version X.XX does not match bootstrap parameter Y.YY" errors?
|
|
|
|
XS code is very sensitive to the module version number and will
|
|
complain if the version number in your Perl module doesn't match. If
|
|
you change your module's version # without rerunning Makefile.PL the old
|
|
version number will remain in the Makefile, causing the XS code to be built
|
|
with the wrong number.
|
|
|
|
To avoid this, you can force the Makefile to be rebuilt whenever you
|
|
change the module containing the version number by adding this to your
|
|
WriteMakefile() arguments.
|
|
|
|
depend => { '$(FIRST_MAKEFILE)' => '$(VERSION_FROM)' }
|
|
|
|
|
|
=item How do I make two or more XS files coexist in the same directory?
|
|
|
|
Sometimes you need to have two and more XS files in the same package.
|
|
There are three ways: C<XSMULTI>, separate directories, and bootstrapping
|
|
one XS from another.
|
|
|
|
=over 8
|
|
|
|
=item XSMULTI
|
|
|
|
Structure your modules so they are all located under F<lib>, such that
|
|
C<Foo::Bar> is in F<lib/Foo/Bar.pm> and F<lib/Foo/Bar.xs>, etc. Have your
|
|
top-level C<WriteMakefile> set the variable C<XSMULTI> to a true value.
|
|
|
|
Er, that's it.
|
|
|
|
=item Separate directories
|
|
|
|
Put each XS files into separate directories, each with their own
|
|
F<Makefile.PL>. Make sure each of those F<Makefile.PL>s has the correct
|
|
C<CFLAGS>, C<INC>, C<LIBS> etc. You will need to make sure the top-level
|
|
F<Makefile.PL> refers to each of these using C<DIR>.
|
|
|
|
=item Bootstrapping
|
|
|
|
Let's assume that we have a package C<Cool::Foo>, which includes
|
|
C<Cool::Foo> and C<Cool::Bar> modules each having a separate XS
|
|
file. First we use the following I<Makefile.PL>:
|
|
|
|
use ExtUtils::MakeMaker;
|
|
|
|
WriteMakefile(
|
|
NAME => 'Cool::Foo',
|
|
VERSION_FROM => 'Foo.pm',
|
|
OBJECT => q/$(O_FILES)/,
|
|
# ... other attrs ...
|
|
);
|
|
|
|
Notice the C<OBJECT> attribute. MakeMaker generates the following
|
|
variables in I<Makefile>:
|
|
|
|
# Handy lists of source code files:
|
|
XS_FILES= Bar.xs \
|
|
Foo.xs
|
|
C_FILES = Bar.c \
|
|
Foo.c
|
|
O_FILES = Bar.o \
|
|
Foo.o
|
|
|
|
Therefore we can use the C<O_FILES> variable to tell MakeMaker to use
|
|
these objects into the shared library.
|
|
|
|
That's pretty much it. Now write I<Foo.pm> and I<Foo.xs>, I<Bar.pm>
|
|
and I<Bar.xs>, where I<Foo.pm> bootstraps the shared library and
|
|
I<Bar.pm> simply loading I<Foo.pm>.
|
|
|
|
The only issue left is to how to bootstrap I<Bar.xs>. This is done
|
|
from I<Foo.xs>:
|
|
|
|
MODULE = Cool::Foo PACKAGE = Cool::Foo
|
|
|
|
BOOT:
|
|
# boot the second XS file
|
|
boot_Cool__Bar(aTHX_ cv);
|
|
|
|
If you have more than two files, this is the place where you should
|
|
boot extra XS files from.
|
|
|
|
The following four files sum up all the details discussed so far.
|
|
|
|
Foo.pm:
|
|
-------
|
|
package Cool::Foo;
|
|
|
|
require DynaLoader;
|
|
|
|
our @ISA = qw(DynaLoader);
|
|
our $VERSION = '0.01';
|
|
bootstrap Cool::Foo $VERSION;
|
|
|
|
1;
|
|
|
|
Bar.pm:
|
|
-------
|
|
package Cool::Bar;
|
|
|
|
use Cool::Foo; # bootstraps Bar.xs
|
|
|
|
1;
|
|
|
|
Foo.xs:
|
|
-------
|
|
#include "EXTERN.h"
|
|
#include "perl.h"
|
|
#include "XSUB.h"
|
|
|
|
MODULE = Cool::Foo PACKAGE = Cool::Foo
|
|
|
|
BOOT:
|
|
# boot the second XS file
|
|
boot_Cool__Bar(aTHX_ cv);
|
|
|
|
MODULE = Cool::Foo PACKAGE = Cool::Foo PREFIX = cool_foo_
|
|
|
|
void
|
|
cool_foo_perl_rules()
|
|
|
|
CODE:
|
|
fprintf(stderr, "Cool::Foo says: Perl Rules\n");
|
|
|
|
Bar.xs:
|
|
-------
|
|
#include "EXTERN.h"
|
|
#include "perl.h"
|
|
#include "XSUB.h"
|
|
|
|
MODULE = Cool::Bar PACKAGE = Cool::Bar PREFIX = cool_bar_
|
|
|
|
void
|
|
cool_bar_perl_rules()
|
|
|
|
CODE:
|
|
fprintf(stderr, "Cool::Bar says: Perl Rules\n");
|
|
|
|
And of course a very basic test:
|
|
|
|
t/cool.t:
|
|
--------
|
|
use Test::More tests => 1;
|
|
use Cool::Foo;
|
|
use Cool::Bar;
|
|
Cool::Foo::perl_rules();
|
|
Cool::Bar::perl_rules();
|
|
ok 1;
|
|
|
|
This tip has been brought to you by Nick Ing-Simmons and Stas Bekman.
|
|
|
|
An alternative way to achieve this can be seen in L<Gtk2::CodeGen>
|
|
and L<Glib::CodeGen>.
|
|
|
|
=back
|
|
|
|
=back
|
|
|
|
=head1 DESIGN
|
|
|
|
=head2 MakeMaker object hierarchy (simplified)
|
|
|
|
What most people need to know (superclasses on top.)
|
|
|
|
ExtUtils::MM_Any
|
|
|
|
|
ExtUtils::MM_Unix
|
|
|
|
|
ExtUtils::MM_{Current OS}
|
|
|
|
|
ExtUtils::MakeMaker
|
|
|
|
|
MY
|
|
|
|
The object actually used is of the class L<MY|ExtUtils::MY> which allows you to
|
|
override bits of MakeMaker inside your Makefile.PL by declaring
|
|
MY::foo() methods.
|
|
|
|
=head2 MakeMaker object hierarchy (real)
|
|
|
|
Here's how it really works:
|
|
|
|
ExtUtils::MM_Any
|
|
|
|
|
ExtUtils::MM_Unix
|
|
|
|
|
ExtUtils::Liblist::Kid ExtUtils::MM_{Current OS} (if necessary)
|
|
| |
|
|
ExtUtils::Liblist ExtUtils::MakeMaker |
|
|
| | |
|
|
| | |-----------------------
|
|
ExtUtils::MM
|
|
| |
|
|
ExtUtils::MY MM (created by ExtUtils::MM)
|
|
| |
|
|
MY (created by ExtUtils::MY) |
|
|
. |
|
|
(mixin) |
|
|
. |
|
|
PACK### (created each call to ExtUtils::MakeMaker->new)
|
|
|
|
NOTE: Yes, this is a mess. See
|
|
L<http://archive.develooper.com/makemaker@perl.org/msg00134.html>
|
|
for some history.
|
|
|
|
NOTE: When L<ExtUtils::MM> is loaded it chooses a superclass for MM from
|
|
amongst the ExtUtils::MM_* modules based on the current operating
|
|
system.
|
|
|
|
NOTE: ExtUtils::MM_{Current OS} represents one of the ExtUtils::MM_*
|
|
modules except L<ExtUtils::MM_Any> chosen based on your operating system.
|
|
|
|
NOTE: The main object used by MakeMaker is a PACK### object, *not*
|
|
L<ExtUtils::MakeMaker>. It is, effectively, a subclass of L<MY|ExtUtils::MY>,
|
|
L<ExtUtils::MakeMaker>, L<ExtUtils::Liblist> and ExtUtils::MM_{Current OS}
|
|
|
|
NOTE: The methods in L<MY|ExtUtils::MY> are simply copied into PACK### rather
|
|
than MY being a superclass of PACK###. I don't remember the rationale.
|
|
|
|
NOTE: L<ExtUtils::Liblist> should be removed from the inheritance hiearchy
|
|
and simply be called as functions.
|
|
|
|
NOTE: Modules like L<File::Spec> and L<Exporter> have been omitted for clarity.
|
|
|
|
|
|
=head2 The MM_* hierarchy
|
|
|
|
MM_Win95 MM_NW5
|
|
\ /
|
|
MM_BeOS MM_Cygwin MM_OS2 MM_VMS MM_Win32 MM_DOS MM_UWIN
|
|
\ | | | / / /
|
|
------------------------------------------------
|
|
| |
|
|
MM_Unix |
|
|
| |
|
|
MM_Any
|
|
|
|
NOTE: Each direct L<MM_Unix|ExtUtils::MM_Unix> subclass is also an
|
|
L<MM_Any|ExtUtils::MM_Any> subclass. This
|
|
is a temporary hack because MM_Unix overrides some MM_Any methods with
|
|
Unix specific code. It allows the non-Unix modules to see the
|
|
original MM_Any implementations.
|
|
|
|
NOTE: Modules like L<File::Spec> and L<Exporter> have been omitted for clarity.
|
|
|
|
=head1 PATCHING
|
|
|
|
If you have a question you'd like to see added to the FAQ (whether or
|
|
not you have the answer) please either:
|
|
|
|
=over 2
|
|
|
|
=item * make a pull request on the MakeMaker github repository
|
|
|
|
=item * raise a issue on the MakeMaker github repository
|
|
|
|
=item * file an RT ticket
|
|
|
|
=item * email makemaker@perl.org
|
|
|
|
=back
|
|
|
|
=head1 AUTHOR
|
|
|
|
The denizens of makemaker@perl.org.
|
|
|
|
=head1 SEE ALSO
|
|
|
|
L<ExtUtils::MakeMaker>
|
|
|
|
=cut
|