desemondo has asked for the wisdom of the Perl Monks concerning the following question:

Background

Its been quite interesting reading all the many varied writeups and tutorials on building modules for Windows.

To keep this focused, I know about PPM. The sole reason I have begun down this path is that modules provided on the ActiveState repository, are often several versions behind CPAN. (which is often months and sometimes even years).

I realise that building modules for Win32 is a difficult task, but I'm willing to do whatever necessary to figure this out. Plus i have been finding this quite interesting so far. The trigger for this was my interest in getting Win32::API. And File::Spec is a dependancy of it that needs a compiler

Also, to clarify, I don't have any prior knowledge or experience compiling c code. But I'm keen to learn, and so far, I've never found a learning adventure that didn't provide some kind of rewards.


Building PathTools-3.30

I have started with PathTools, which I believe should work on Windows. (I realise that there will always be some modules that just won't work on windows, and I accept that.)

I have browsed the very helpful tutorials on modules, Installing Modules but times have definitely moved on since these were written. I went looking for Visual Studio 2003, but found its been replaced twice, So I downloaded the Visual Studio 2008 Express package.

Making PathTools

Visual Studio installed fine, and nmake was detecting it. "Sweet!" I thought.
C:\temp\file_spec\PathTools-3.30>perl Makefile.PL Checking if your kit is complete... Looks good Writing Makefile for Cwd C:\temp\file_spec\PathTools-3.30>nmake Microsoft (R) Program Maintenance Utility Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. cp lib/File/Spec/Mac.pm blib\lib\File\Spec\Mac.pm cp lib/File/Spec/OS2.pm blib\lib\File\Spec\OS2.pm cp lib/File/Spec/VMS.pm blib\lib\File\Spec\VMS.pm cp lib/File/Spec/Cygwin.pm blib\lib\File\Spec\Cygwin.pm cp lib/File/Spec/Epoc.pm blib\lib\File\Spec\Epoc.pm cp lib/File/Spec/Functions.pm blib\lib\File\Spec\Functions.pm cp lib/File/Spec.pm blib\lib\File\Spec.pm cp Cwd.pm blib\lib\Cwd.pm cp lib/File/Spec/Unix.pm blib\lib\File\Spec\Unix.pm cp lib/File/Spec/Win32.pm blib\lib\File\Spec\Win32.pm C:\Perl\bin\perl.exe C:\Perl\lib\ExtUtils\xsubpp -typemap C:\ +Perl\lib\ExtUtils\typemap Cwd.xs > Cwd.xsc && C:\ Perl\bin\perl.exe -MExtUtils::Command -e mv Cwd.xsc Cwd.c cl -c -nologo -GF -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSO +LE -DNO_STRICT -DHAVE_DES_FCRYPT -DNO_HASH_SEED -D USE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMPLICIT_CONTEXT -DPERL +_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX - MD -Zi -DNDEBUG -O1 -DVERSION=\"3.30\" -DXS_VERSION=\"3.30\" "-IC +:\Perl\lib\CORE" Cwd.c Cwd.c Cwd.xs(89) : warning C4996: 'getcwd': The POSIX name for this item is +deprecated. Instead, use the ISO C++ conformant na me: _getcwd. See online help for details. C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\direct +.h(121) : see declaration of 'getcwd' Cwd.xs(77) : warning C4101: 'symlink' : unreferenced local variable Running Mkbootstrap for Cwd () C:\Perl\bin\perl.exe -MExtUtils::Command -e chmod 644 Cwd.bs C:\Perl\bin\perl.exe -MExtUtils::Mksymlists -e "Mksymlists('N +AME'=>\"Cwd\", 'DLBASE' => 'Cwd', 'DL_FUNCS' => { }, 'FUNCLIST' => [], 'IMPORTS' => { }, 'DL_VARS' => []);" link -out:blib\arch\auto\Cwd\Cwd.dll -dll -nologo -nodefaultli +b -debug -opt:ref,icf -libpath:"C:\Perl\lib\CORE" -machine:x86 Cwd.obj C:\Perl\lib\CORE\perl58.lib oldnames.lib kern +el32.lib user32.lib gdi32.lib winspool.lib comdlg 32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib u +uid.lib ws2_32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib -def:Cwd.def Creating library blib\arch\auto\Cwd\Cwd.lib and object blib\arch\au +to\Cwd\Cwd.exp C:\Perl\bin\perl.exe -MExtUtils::Command -e chmod 755 blib\arc +h\auto\Cwd\Cwd.dll C:\Perl\bin\perl.exe -MExtUtils::Command -e cp Cwd.bs blib\arc +h\auto\Cwd\Cwd.bs C:\Perl\bin\perl.exe -MExtUtils::Command -e chmod 644 blib\arc +h\auto\Cwd\Cwd.bs C:\temp\file_spec\PathTools-3.30>

Then came the problems

C:\temp\file_spec\PathTools-3.30>nmake test Microsoft (R) Program Maintenance Utility Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. C:\Perl\bin\perl.exe "-MExtUtils::Command::MM" "-e" "test_harn +ess(0, 'blib\lib', 'blib\arch')" t/*.t t/crossplatform....ok 10/71 skipped: various reasons t/cwd..............ok 2/30 skipped: various reasons t/Functions........ok t/rel2abs2rel......ok t/Spec.............ok 126/598 skipped: various reasons t/taint............ok t/tmpdir...........ok t/win32............Undefined subroutine &Cwd::getdcwd called at t/win3 +2.t line 22. t/win32............ok 1/4# Looks like you planned 4 tests but only ran + 1. # Looks like your test died just after 1. t/win32............dubious Test returned status 255 (wstat 65280, 0xff00) DIED. FAILED tests 2-4 Failed 3/4 tests, 25.00% okay Failed Test Stat Wstat Total Fail List of Failed ---------------------------------------------------------------------- +--------- t/win32.t 255 65280 4 6 2-4 138 subtests skipped. Failed 1/8 test scripts. 3/731 subtests failed. Files=8, Tests=731, 3 wallclock secs ( 0.00 cusr + 0.00 csys = 0.00 + CPU) Failed 1/8 test programs. 3/731 subtests failed. NMAKE : fatal error U1077: 'C:\Perl\bin\perl.exe' : return code '0xff' Stop.
So... win32.t is failing. (plus others which I was soon to find out) So I ran it directly using this:
C:\Perl\bin\perl.exe "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib\lib', 'blib\arch')" t/win32.t Then I see the real error. (A pop-up msg)
perl.exe - unable to Locate Component This application has failed to start because MSVCR90.dll was not found +. Re-installing the application may fix this problem

So I give Microsoft the benefit of the doubt, I tried reinstalling Perl. no joy. Same error
Then I tried copying the dll into my temp directory just to see what happens. New error this time:
MS Visual C++ Runtime Library Program: C:\Perl\bin\perl.exe R6034 An Application has made an attempt to load the C runtime library incor +rectly.

And finally the questions


Update: Well, I managed to get MinGW working, albeit, until it was actually working it was a bit touch and go... I kept trying various things, and I think my final working result was due to the following. I've jotted them down below for anyone else whos interested.

Run perl -V:make and perl -V:cc, if they still report make='nmake'; and cc='cl'; respectively, Perl won't create the Makefile file properly (at least for using with MinGW).

On my system I found that C:\Perl\Site\Bin was not in my PATH, only C:\Perl\Bin was... Once I updated that the perl -V:xxx commands gave the correct results, make='dmake'; and cc='gcc'; respectively.

Then, you should be able to follow the standard Mantra:
perl Makefile.pl
dmake
dmake test
dmake install

During my troubles, I found that -n switch on dmake quite helpful for troubleshooting, as it shows you what dmake is about to do, without actually doing it. And also the -v switch for verbose error logging.

Would anyone be kind enough to explain why MinGW compiles a fully portable dll and Visual Studio doesn't? Is it just Microsoft trying to dominate everything with their "you must use all our products. And anyway our stuff is incompatible with everyone else - and we like it that way..." kind of approach? Or is it a new industry standard for software development?

And finally, Thanks to everyone for their responses and feedback.

Replies are listed 'Best First'.
Re: Compiling modules for win32 ActivePerl
by syphilis (Archbishop) on Sep 30, 2009 at 07:19 UTC
    If I were to ditch Visual Studio 2008, and go with MinGW, how do I set up the environment?

    You would just delete Visual Studio 2008 (or at least remove it from the path) and run ppm install MinGW. Nothing else needs to be done - MinGW and dmake will be installed and and made locatable, so you're right to go. (However, things might be stuffed up if Visual Studio is also getting found.)

    If anyone here has tried both MS VisualStudio and the gcc tools to compile Perl modules specifically for Win32, which do you prefer and why?

    Unless you're using the same compiler that was used to build ActivePerl (which is Visual Studio 6.0 for x86 builds of ActivePerl) you're better off with MinGW, imo. The reason is that MinGW uses the same C runtime (msvcrt.dll) as Visual Studio 6.0, so there's no mixing of C runtimes going on. In some situations, this is quite crucial.

    If you really want to use Visual Studio 2008 as your compiler, you should build perl with that compiler.

    Cheers,
    Rob
      thanks for the encouragement - i've gone with MinGW as you suggested. I don't think I persisted with MinGW long enough. Due to the vast amount of other material saying that you should use an MS compiler if using ActiveState I think I gave in too easily.

      ... so there's no mixing of C runtimes going on. In some situations, this is quite crucial.
      Is this what caused the earlier issue when compiling with VS? ie. Because my Perl wasn't built with Visual Studio it was missing some thing(s)?

      ah, well still got a lot more to learn here.
Re: Compiling modules for win32 ActivePerl
by CountZero (Bishop) on Sep 30, 2009 at 06:18 UTC
    Last time (fairly recently) I installed ActiveState Perl 5.10, I first installed the whole MinGW suite of programs and utilities and only then AS Perl. During the install it automatically detected I had the MinGW C-compiler and dmake and configured itself so it now uses dmake and the C-compiler.

    Still, not all is OK. Some modules seem to need a tool called dlltool which is missing and I haven't yet been able to find and install it. But even without this, most (for various definitions of the word) of the modules compile.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Still, not all is OK. Some modules seem to need a tool called dlltool which is missing and I haven't yet been able to find and install it

      It's part of the binutils package, so you just need to grab a binutils binary and extract it to your MinGW installation.
      If you ppm install MinGW you'll certainly get dlltool.exe.

      Cheers,
      Rob
        Actually, the install wizzard of AS Perl 5.10 did try to install through PPM (some elements of) MinGW, but maybe because I already had a minimal MinGW, it failed to get the binutils. I have downloaded it now by hand and will see if I can retrofit it.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Still, not all is OK. Some modules seem to need a tool called dlltool which is missing and I haven't yet been able to find and install it.

      You need binutils.

      <rant>

      strawberry perl is fantastic, but it still too disjointed from msys/mingw, which is too disjointed from gnuwin32. They all have similar goals, and need to cooperate more easily with each other.

      For example perl won't build with sh Configure under msys, so msys is stuck at perl5.6.1. Strawberry perl developers helped craft a dmake specific makefile to compile perl with mingw, but now it doesn't come with sh, so every module which builds easily under linux with sh configure needs special steps for win32. Even ExtUtils::MakeMaker (and related modules) needed special tweaks.

      Instead of msys sh configure being a familiar unifying interface, or gnuwin32 providing the latest binaries (lots are outdated), everything from zlib to libtiff to imagemagick to Image::Magick needs special steps.

      Strawberry perl hopes it is A 100% Open Source Perl for Windows that is exactly the same as Perl everywhere else but without GNU build system it falls short.

      They could all learn some things from http://portableapps.com/

      </rant>

      Sorry about the small rant, dlltool comes with binutils.

        I'm not sure what you're getting at. Problems building perl are of no consequence for a Strawberry user because Strawberry provides a binary. And modules that you build with 'sh configure'? Huh? I've never come across anything like that. The CPAN standard way is either 'perl Makefile.PL' or 'perl Build.PL'.

        As for portableapps.com - that appears to be a tool for carrying your Windows programs around from one Windows machine to another. Strawberry perl, on the other hand, is an attempt to get a primarily Unixy program (perl) to run on Windows.

Re: Compiling modules for win32 ActivePerl
by afoken (Chancellor) on Sep 30, 2009 at 05:35 UTC

    Try strawberry perl, it comes with compiler and build utilities packaged and working. No need to mess with Microsoft tools.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      damn... I wish I had found out about strawberry perl 12 months ago... we've since rolled out a bunch of machines (500+) at work and I can't see us easily replacing Perl on them until those machines are replaced in about 3 years time.
      Still, thanks anyway for responding. I will get an install of StawberryPerl on a test machine and have a play with it.

      Cheers
Re: Compiling modules for win32 ActivePerl
by stbey (Novice) on Sep 30, 2009 at 09:58 UTC
Re: Compiling modules for win32 ActivePerl
by Anonymous Monk on Sep 30, 2009 at 06:11 UTC