UPDATE: this Tutorial is geared toward the ActiveState ActivePerl for Win32. THX ybiC! Added a dropped <READMORE> tag. Added lots 'o stuff from $code or die and ybiC. This will continue to grow and change.

WARNING: my ispell failed and I need to fix it ... if I offend anyone with my poor typing or spelling, consider them manners. I don't mind if you don't like my manners. I don't like 'em myself. They're pretty bad. I grieve over them on long winter evenings. <- The Big Sleep ... gawd I * L O V E * that line!


You want to make a Perl Package Manager ( PPM ) package but every time you try to make the module, it fails. Or the resulting package isn't quite right. Or you missed something, like the pod 2 html files and their introduction into the ActiveState ActivePerl Documentation index.


Being a good monk, you have read How do I make a PPM package? and followed the instructions verbatim. Maybe you even read perlwin32 - Perl under Win32 - Usage Hints. But things still don't DWIM.

So what now? Well, there are several catches to building a module under Win32. Some can be overcome freely. Some may cost money. Some may be unattainable at this time. Here are some things I've found so far.


  1. nmake complains about something called cl.exe

  2. Well, you may be trying to compile an XS module. These are modules that require some kind of external library and need a full-blown C compiler to build the dll ( dynamic link library ). nmake looks for cl.exe because that is M$ VC++'s compiler. One might try running to CygWin, "a UNIX environment for Windows". Another might try MingW, "a collection of header files and import libraries that allow one to use GCC and produce native Windows32 programs that do not rely on any 3rd-party DLLs".

    IMHO, stick with the compiler used for your perl distribution. ActiveState uses Micro$oft VisualC++. One can find "Eductational" versions that may work, but I went with the "Standard Edition". Unless you have a lot of $$$, I don't advocate getting the "Professional" or "Enterprise" editions. I think I paid $79 USD for my copy.

    When you install it, have it update your environment variables ( %ENV for the perl-ers ). You can do what you want with the IDE ( Integrated Development Environment - I use NT Emacs myself ).

    If you want to use CPAN to get and build your modules not found in the usual places ( see my home node for a small list ) for PPM, you'll need a few other tools ...

    Get these installed and run perl -MCPAN -e shell because that's how one runs CPAN! Point all the questions to your downloaded files from above. I advocate implementing a /usr-type layout similar to *nix and adding it to your %PATH%.

    Go grab your favorite modules via the install package nomenclature. Of course, one can use the old fashioned "ftp it to my disk, un-tar-gzip it and run nmake" style, too.

    What will result is a directory in which the module's source resides within. If one uses CPAN's install, it will go through the make process, sometimes failing. If one decides to follow the manual path, follow the README or INSTALL directions.

    Many modules engineered with Win32 in mind have a makefile.msc file. If CPAN fails, look for this. If it exists, do a nmake /f makefile.msc. This can be especially important if the module contains some XS. Modify the module's provided instructions to include this /f maskefile.msc bit through out.

  3. Great! But no matter what I do, the tests fail!

  4. Well, that might happen, especially of the test scripts are xenophobically aligned with *nix. Try running the test scripts the long way ( perl testscript which should not make a difference but occasionally do ).

  5. I nmaked it fine; it tested fine. Now what?

  6. Well, in that directory where the source resides and the namake was performed, there should be a blib directory. From the doc listed above:

    "The resulting files are placed in the blib directory that is created when you run nmake. These files should be packed into an archive like this:

    tar cvf package.tar blib
    gzip --best package.tar

    You now have an archive called package.tar.gz. Then you generate the PPD file by:

    nmake ppd

    You have to edit the resulting PPD file and add the location of the package archive into <CODEBASE HREF="" />. The location is relative to the PPD file."

    Note that other modifications may need to be made to the resulting ppd file.

  7. What about the perldocs in the ActiveState ActivePerl Documentation html index?

  8. Well, use pod2html module.pm against all the peritent pm files. As all modules differ in this, you'll have to figure out for yourself which ones are "pertinent".

    Before one does the previous step ( OOOPPPSSSS! ), create a directory structure under blib like html\site\lib\Compress, where one replaces the Compress with the "master" level ... i.e. Win32 for a standard Win32 module. Move the html file(s) from above into this "master" level directory.

    Now goto ( I know there's no goto in perl! ) to the previous step. Refresh or reload your "ActiveState ActivePerl Documentation" Start menu item. Voila!

  9. Well done! But how do I distribute this to the masses that continually create a massive din in eager anticipation for this module!

  10. Easy, now! Getting a little extra ego with your Wheaties, ain't-cha! Hmmm ... I know little about din-producing masses. But setting up a PPM distribution point is, perhaps, the easiest part of the whole endeavor. Remember before when I quoted about the ppd file? That path entered in the CODEBASE HREF portion is critial. Also, find a place to house it. But, with my own humble PPM respository as an example:

    The 'root' is http://idnopheq.perlmonk.org. The ppd files shall reside in http://idnopheq.perlmonk.org/perl/packages. In the ppd file's CODEBASE HREF, I have a relative path to this of x86/Win32/package.tar.gz. The tar.gz file is placed in http://idnopheq.perlmonk.org/perl/packages/x86/Win32/, a la CODEBASE HREF. One can freely follow my lead here, or come up with something more to their aesthetical testes.

    UPDATE: Thanks to $code or die!!!!

    See ($code or die) Re: Repository code (HowTo build and distribute a PPMed module for Win32) about setting your new repository up for search capabilities. Aw, heck! I'll just quote it, but don't forget to ++ the node!

    <cite> Right, I have been re-reading PPM.pm and understand how the search command works.

    When you do search Module-Name, it run's the function list_available(). This function returns a list of .ppd files in the repository. It does it differently depending on what type of repository it is, e.g.: file://, UNC, SOAP, or http://. We're interested in the last bit of the function concerning http.

    If the repository is an http:// repository (not soap), then it calls the function read_href() which returns the text on the page. list_available() expects either a directory listing (Apache or IIS format) or a default.prk format file - ActiveState's Visual Package Manager that's part of the Perl Dev Kit.

    For the search to work properly (without implimenting a SOAP interface or .prk) your repository must return something that resembles a directory listing, which PPM.pm parses.

    Thankfully, PPM.pm keeps the "libwww-perl/" part of the user agent. So we can write a small script that will return a directory listing for ppm and a nicely formatted page for regular browsers. This is a small working example of what to do:

    use strict; use CGI qw( :all ); my $user_agent = user_agent(); my $html_redirection = ''; if ($user_agent =~ m#libwww-perl/#) { # it's a perl bot - probably ppm, so return a # compatible directory listing print_dir_listing(); } else { # it's probably a regular browser, redirect... print redirect(-uri => $html_redirection); } sub print_dir_listing { # Get the current directory, (cwd doesn't necessarily work in IIS) (my $cwd = $0) =~ s[\\][/]g; $cwd =~ s[/([^/]*)$][]; print header({-type => "text/plain"}); opendir FOLDER, $cwd or die "I don't have permission $!"; print a({-href => $_}, $_ ), "\n" for grep { /\.ppd$/ } readdir FO +LDER; closedir FOLDER; }

    Save this to index.pl or something and make sure it's the default document. Then change $html_redirection variable to the URL where you want your actual users to go to and you're set. You can of course do something more dynamic for the actual users page, such as parse the XML in the PPD files to give user's full information on the modules (version, description, author etc) without having to edit an html file every time you change a package or add a new one. I leave that as an exercise for the reader :) </cite>

    Many THX to $code or die for this information. HAVE YOU ++ IT YET?

  11. But the $%^&ing thing still doesn't work or the tests fail!

  12. Well, one may look to overloading functions to meet Win32's oddities. But sometimes that doesn't work. Like fork doesn't always work. These are the items that cannot necessarily be overcomed. explitive happens. And, anyway, why aren't you running an *nix or BSD derivative?

  13. I fear *nix and all that it implies! That's why!

  14. As with so many things, TIMTOWTDI and YMMV.

  15. I can't afford the $$$ for the C compiler, and the free ones fail me. What do I do?

  16. Fear not! I've been there; done that. Email me at idnopheq at permonk.org or drop me a /msg in the chatterbox, and I'll see what I can do! Failing that, post a request in the Monastary. If my lurid and sordid personal and/or professional life precludes me from helping, the other fine monks in this fine establishment may be able to help.

UPDATE: the below is based off of subsequent posts and other information I found ... THX to all for their recommendations!

Further Reading


In reply to HowTo build and distribute a PPMed module for Win32 by idnopheq

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":