Helping ordinary people create extraordinary websites!
GET OUR NEWSLETTER
Your Email:
 

Building Perl projects with MakeMaker

By Sean Dague
2005-05-01


Anatomy of a MakeMaker Project

On the cover of Programming Perl, 3rd Edition is the phrase "There's More Than One Way To Do It". This is the mantra of the Perl community. The flexibility of the language allows for many vastly different but functionally equivalent solutions to any given problem.

Building Perl projects with MakeMaker is no different than any other aspect of Perl: there are many ways to do it. For simplicity I will present only one approach. I consider this to be a set of best practices, based on my experience with many of the respected projects that exist on CPAN, the Comprehensive Perl Archive Network (see Resources later in this article). As you become accustomed to building projects with MakeMaker, feel free to develop your own style for constructing them.

A basic Perl project will consist of a number of files and directories contained within your project's directory. I'll touch on each one briefly, then revisit each in turn as I construct a Perl application.

Makefile.PL
The heart of a Perl project is the Makefile.PL file. Makefile.PL is a Perl script that generates a gnu Makefile for your entire project. This is done through the invocation of the WriteMakefile function that is contained within the ExtUtils::MakeMaker library. A simple Makefile.PL looks something like:

Minimal Makefile.PL

use ExtUtils::MakeMaker;

WriteMakefile(
'NAME' => 'myproject',
'VERSION_FROM' => 'lib/MyModule.pm', # finds $VERSION
);
In this example I have passed WriteMakefile the only two pieces of information that are required: NAME and VERSION. Name is specified explicitly. Version is specified implicitly through the use of the VERSION_FROM variable. This indicates to MakeMaker which module contains the authoritative $VERSION variable for the project.

All other variables required to construct the Makefile will be fetched from the Perl interpreter defaults. These include things like PREFIX, for the prefix in which the applications should be installed (generally defaulting to /usr or /usr/local), MAN1PATH, for the location where section 1 (user command) man pages should be installed, and INSTALLSITELIB, the location where libraries should be installed. For a complete list of variables, refer to the ExtUtils::MakeMaker man page, or the HTML documentation located at Perl.com (see Resources).

MANIFEST
The second most important file in a Perl project is the MANIFEST. The MANIFEST is a list of all files that are a part of the project. When Makefile.PL is run, it first examines MANIFEST, and checks that all the files required for the project are present. If they are not, it will generate a list of missing files, and will not build the master Makefile.

MANIFEST is also used beyond mere consistency checking. One of the additional targets provided by MakeMaker is dist, which I will discuss later. make dist uses MANIFEST to generate its tar file. It is crucial to keep this file up to date.

One should note that MakeMaker provides a target for generating the MANIFEST called manifest. By typing make manifest all files in the current directory and all subdirectories are added to the MANIFEST. The manifest target does not exclude any files by default. You can change this by creating a MANIFEST.SKIP file. For more information, please see the ExtUtils::Manifest man page.

lib and bin directories
How you organize the files of your project is often a matter of religion. UNIX has a tradition of having sibling directories, lib and bin, at many levels throughout the directory structure. I have found that if you use this same convention in Perl projects, it is far easier to keep track of the role of each file. This is especially true with large multi-developer projects.

The lib directory in UNIX refers to libraries potentially used by multiple applications. In the case of Perl, this means Perl Module (.pm) files, each of which generally start with a package declaration, and Perl Library (.pl) files (which generally don't have a package declaration, but consist solely of subroutine declarations). MakeMaker looks for Perl Modules in the project top level directory, and in the lib directory by default, though this is configurable.

The bin directory in UNIX is where binaries and other runnable programs are stored. In the bin directory you should place all scripts that begin with some variation of #!/usr/bin/perl. Do not be concerned whether or not your #! line will be appropriate on another platform. As you will see later, MakeMaker will take care of this problem during installation.

Many people like appending a .pl extension to all Perl programs for clarity. This is not required for those programs to run. MakeMaker will work equally well with or without the suffix. For this reason I tend not to suffix my Perl applications with any special endings.

t/, the test case directory
One of the most important parts of the MakeMaker framework is the ability to have automated test cases. This function is provided by the Test::Harness module, which specifies a well-defined interface for creating test scripts containing one or more test cases.

During the test phase of building a Perl Project, MakeMaker will run all files in the t subdirectory that have the .t ending as test scripts. It will also run test.pl in the project root directory as a test script, so be careful not to accidentally create such a program unless you actually intend for it to conform to the Test::Harness interface.

The test phase is an integral step in the Perl build process. It is so integral that often an application will not install unless all the tests succeed. Writing robust test scripts will not only make it much easier for you to guarantee the quality of your project, but will also allow others to more easily port your code to a new environment. Instead of merely stating that it does work on X hardware, they can inform you that test cases 15-18 in testabc.t failed. This gives you far more information about what actually went wrong, and will lead to a faster and more reliable fix.

I will describe in depth how to write test scripts and test cases later in this article.

Plain Old Documentation
One of the biggest issues for most projects is keeping documentation in sync with the code that actually implements it. When code is updated to include a new feature or change the way an existing one behaves, it can become difficult and time consuming to track down and modify all the documentation pertaining to that feature. This becomes especially true if documentation needs to be kept in multiple formats, for instance man pages and HTML.

One of the very important features that Perl provides is an embedded documentation markup language, POD (Plain Old Documentation). POD is extremely simple, and consists of very few markup commands. POD markup text is considered a comment by the Perl interpreter, so you may have POD documentation distributed throughout your code. The core Perl distribution comes with parsers that convert POD to text, HTML, and man page format. There are contributed modules on CPAN for direct translation to Latex, PDF, and Postscript as well.

During the Perl build process, MakeMaker will check all scripts and modules for POD documentation. On a UNIX platform, it will generate section 1 for all executables, and section 3 man pages for each library. You may optionally also generate HTML documentation during installation. If you have properly documented your program in POD, after a user installs your program, then he or she can run man your-program and get full documentation on it. This is better than expecting the user to chase down a readme file somewhere, and it creates a familiar interface for your documentation.

More information on POD can be found in Programming Perl, 3rd Edition, by running man perlpod, or online at Perl.com (see Resources).

Tutorial Pages:
» The Module that Makes Makefiles and Much More
» Programming Products vs. Programs
» Anatomy of a MakeMaker Project
» Your First MakeMaker Project (make)
» Building Test Cases (make test)
» Installation (make install)
» Distributing Your Code (make dist)
» Conclusion
» Resources


First published by IBM DeveloperWorks


 | Bookmark
Related Tutorials:
» Random subroutines in Perl
» Log Script Use
» Creating Perl Modules for Web Sites
» Bit Vector, Using Perl Vec
» Build a Perl/CGI Voting System
» Perl Range Operator

Advertise with Us!


Tutorials Scripts Web Hosting Developer Manuals
Resources