views:

203

answers:

4

I'm trying to set up a large-ish project, written in Perl. The IBM MakeMaker tutorial has been very helpful so far, but I don't understand how to link all the modules into the main program. In my project root, I have MANIFEST, Makefile.PL, README, a bin directory, and a lib directory. In my bin directory, I have my main script (Main.pl). In the lib directory, I have each of my modules, divided up into their own respective directories (i.e. Utils::Util1 and Utils::Utils2 in the utils directory, etc). In each module directory, there is also a t directory, containing tests

My MANIFEST file has the following:

bin/Main.pl
lib/Utils/Util1.pm
lib/Utils/Util2.pm
lib/Utils/t/Utils1.t
lib/Utils/t/Utils2.t
Makefile.PL
MANIFEST
README

Makefile.PL is the following:

use ExtUtils::MakeMaker;
WriteMakefile(
    'NAME'=>'Foo',
    'VERSION_FROM'=>'bin/Main.pl',
    'PREREQ_PM'=>{
    "XML::Simple"=> 2.18}, #The libraries that we need and their
             #minimum version numbers
    'EXE_FILES' =>[("bin/Main.pl")]
);

After I make and run, the program crashes, complaining that it cannot find Utils::Util1, and when I run 'make test, it says no tests defined. Can anyone make any suggestions? I have never done a large scale project like this in perl, and I will need to add many more modules

+2  A: 

By default, tests are looked for in a top-level t directory (or a test.pl file, but that has some limitations, so should be avoided).

You say "After I make and run"...make puts things into a blib directory structure ready to be installed, but doesn't do anything special to make running a script access them. (make test is special; it does add appropriate paths from blib to perl's @INC to be able to run the tests.) You will need to do a "make install" to install the modules where your script will find them (or use a tool like PAR to package them together with your script).

ysth
+2  A: 

Try this structure:

bin/Main.pl
lib/Utils/Util1.pm
lib/Utils/Util2.pm
Makefile.PL
MANIFEST
README
t/Utils1.t
t/Utils2.t

As ysth said, make does not install your modules, it just builds them in a blib directory. (In your case it just copies them there, but if you had XS code, it would be compiled with a C compiler.) Use make install to install your modules for regular scripts to use.

If you want to run your script between make and make install, you can do:

perl -Mblib bin/Main.pl

The -Mblib instructs perl to temporarily add the appropriate directories to the search path, so you can try out an uninstalled module. (make test does that automatically.)

cjm
+4  A: 

Might I also suggest module-starter? It'll automatically create a skeleton project which "Just Works". I learned what little I know about Perl modules organization by reading the generated skeleton files. It's all well-documented, and quite easy to use as a base for growing a larger project in. You can check out the getting-started docs to see what it gives you.

Running module-starter will give you a Perl distribution, consisting of a number of modules (use the command line option --module, such as:

module-starter --distro=Project --module=Project::Module::A,Project::Module::B [...]

to create multiple modules in a single distribution). It's then up to you whether you'd prefer to organize your project as a single distribution consisting of a number of modules working together, or as a number of distributions which can be released separately but which depend on each other (as configured in your Build or Makefile.PL file) to provide a complete system.

Gaurav
Thanks. I read through that and couldn't find anything about doing projects, only about making modules
Tim
Tim: I've modified my answer to clarify how distributions and modules can work together in Perl. Hope it helps? Please do modify your question or reply again if one of us is still confused :).
Gaurav
This seems like a really good idea, and I'll have to use it for my next project. I already set up a makemaker project, but this answers my question a lot better than your initial post
Tim
+5  A: 

If you are just starting to create Perl modules (which is also Perl's equivalent of a project), don't use Makemaker. Module::Build is the way to go, and it's now part of the standard library. Makemaker is for us old salts who haven't converted to Module::Build yet. :)

You should never start off a Perl project by trying to create the structure yourself. It's too much work and you'll always forget something. For your first go, try something like Module::Starter, but if you are doing to do this quite a bit, you might then convert that to Distribution::Cooker so you can customize your files and contents.

brian d foy