EXTUTILS::MAKEMAKER::TUTORIAL(3perl)

✨ NAME ✨

ExtUtils::MakeMaker::Tutorial β€” writing a module with MakeMaker πŸŽ€


🌸 SYNOPSIS 🌸

use ExtUtils::MakeMaker;

WriteMakefile(
    NAME            => 'Your::Module',
    VERSION_FROM    => 'lib/Your/Module.pm'
);

πŸ’– DESCRIPTION πŸ’–

Okay so this is a lil baby tutorial β€” a short one β€” about writing a simple module with MakeMaker. And honestly? It's really not that hard. You're gonna be fine, bestie 🫢

🧚 The Mantra

MakeMaker modules get installed with this one sacred little mantra, memorize it and you're basically set:

perl Makefile.PL
make
make test
make install

Yeah yeah, there are lots more commands and options out there (this whole manual is full of them), but the four lines above will genuinely do it. Periodt.

πŸ¦‹ The Layout

The basic files in a module look kinda like this:

Makefile.PL
MANIFEST
lib/Your/Module.pm

That is literally all that's strictly necessary. Iconic minimalism. ✨

But there's extra files you might want:

lib/Your/Other/Module.pm
t/some_test.t
t/some_other_test.t
Changes
README
INSTALL
MANIFEST.SKIP
bin/some_program

Let me walk you through each one, no skipping, we're doing all of them πŸ’…

πŸ’œ Makefile.PL

When you run Makefile.PL, it makes a Makefile. That's the whole point of MakeMaker, that's literally its main character moment. The Makefile.PL is a simple program that loads ExtUtils::MakeMaker and runs the WriteMakefile() function to generate a Makefile.

Here's an example of what you need for a simple module:

use ExtUtils::MakeMaker;

WriteMakefile(
    NAME            => 'Your::Module',
    VERSION_FROM    => 'lib/Your/Module.pm'
);

NAME is the top-level namespace of your module. VERSION_FROM is the file that contains the $VERSION variable for the entire distribution. Typically this is the same as your top-level module. Yes, that's the standard setup, and yes, it eats every time πŸ”₯

🌈 MANIFEST

A simple listing of all the files in your distribution.

Makefile.PL
MANIFEST
lib/Your/Module.pm

File paths in a MANIFEST always use Unix conventions (ie. /) even if you're not on Unix. No cap, even on Windows, slash it. πŸ’€

You can write this by hand or generate it with 'make manifest'.

See ExtUtils::Manifest for more details.

πŸ“ lib/

This is the directory where the .pm and .pod files you wish to have installed go. They are laid out according to namespace. So Foo::Bar is lib/Foo/Bar.pm. Namespace β†’ path, that's the mapping, slay.

🧚 t/

Tests for your modules go here. Each test filename ends with a .t. So t/foo.t. 'make test' will run these tests.

Typically, the t/ test directory is flat, with all test files located directly within it. However, you can nest tests within subdirectories, for example:

t/foo/subdir_test.t

To do this, you need to inform WriteMakefile() in your Makefile.PL file in the following fashion:

test => {TESTS => 't/*.t t/*/*.t'}

That will run all tests in t/, as well as all tests in all subdirectories that reside under t/. You can nest as deeply as makes sense for your project. Simply add another entry in the test location string. For example, to test:

t/foo/bar/subdir_test.t

You would use the following "test" directive:

test => {TESTS => 't/*.t t/*/*/*.t'}
⚠️ Heads up bestie: note that in the above example, tests in the first subdirectory will not be run. To run all tests in the intermediary subdirectory preceding the one the test files are in, you need to explicitly note it:
test => {TESTS => 't/*.t t/*/*.t t/*/*/*.t'}

You don't need to specify wildcards if you only want to test within specific subdirectories. The following example will only run tests in t/foo:

test => {TESTS => 't/foo/*.t'}

Tests are run from the top level of your distribution. So inside a test you would refer to ./lib to enter the lib directory, for example. iykyk 🫢

πŸŽ€ Changes

A log of changes you've made to this module. The layout is free-form, do whatever feels right. Here's an example:

1.01 Fri Apr 11 00:21:25 PDT 2003
    - thing() does some stuff now
    - fixed the wiggy bug in withit()

1.00 Mon Apr  7 00:57:15 PDT 2003
    - "Rain of Frogs" now supported

πŸ’– README

A short description of your module, what it does, why someone would use it and its limitations. CPAN automatically pulls your README file out of the archive and makes it available to CPAN users β€” it is the first thing they will read to decide if your module is right for them. So like, this is your module's first impression. Make it count, no pressure πŸ’…βœ¨

🌸 INSTALL

Instructions on how to install your module along with any dependencies. Suggested information to include here:

any extra modules required for use
the minimum version of Perl required
if only works on certain operating systems

πŸ‘‘ MANIFEST.SKIP

A file full of regular expressions to exclude when using 'make manifest' to generate the MANIFEST. These regular expressions are checked against each file path found in the distribution (so you're matching against "t/foo.t" not "foo.t").

Here's a sample:

~$          # ignore emacs and vim backup files
.bak$       # ignore manual backups
\#          # ignore CVS old revision files and emacs temp files

Since # can be used for comments, # must be escaped.

MakeMaker comes with a default MANIFEST.SKIP to avoid things like version control directories and backup files. Specifying your own will override this default.

bin/

Okay the original manual page literally just says "bin/" here and then moves on β€” no description, nothing. Not me being left on read by a manpage πŸ˜­πŸ™ˆ (If you're curious about bin/, the layout listing above is all this page tells you: bin/some_program.)


🌈 SEE ALSO 🌈

  • perlmodstyle gives stylistic help writing a module.
  • perlnewmod gives more information about how to write a module.

There are modules to help you through the process of writing a module: ExtUtils::ModuleMaker, Module::Starter, Minilla::Tutorial, Dist::Milla::Tutorial, Dist::Zilla::Starter.


And that's the whole page, bestie! Go write that module, you've got this πŸ’–πŸ¦‹βœ¨

this was page ExtUt...utorial(3perl) from the Perl Programmers Reference Guide β€” perl v5.44.0, dated 2026-10-17. mwah, bye πŸ‘‘

πŸ“¦ where this page comes from
  • arch rolling: perl 5.44.0-1 Β· Artistic-1.0-Perl AND GPL-1.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms