http://www.perlmonks.org?node_id=671479

Introduction

I need to compile Perl modules for Windows. In particular I want to compile Gtk2, but it would seem that it's one of the hardest to compile.

The easy answer of course is to install PPM (randyk tells us how to do it without a working compiler.), but that relies on someone else having a working compiling environment and the same version of Perl as you do, why let them have all the fun anyway. I am using Strawberry Perl 5.10, and unfortunatly it would seem that no-one has recompiled anything exciting for Perl 5.10 and put it up in their repositories, they've all probably given up with the hideous number of failures in the ActiveState PPM repository for 5.10. So as convenient PPM is, it's not a universal solution. Having a working compiler environment is a universal solution, provided you're prepared to swear and curse a bit...

Usually planetscape response with genuinly helpful replies like this or this, and there is this tutorial as well. Unfortunatly the material is slightly dated, but probably still current.

Another common comment is about using the same compiler as your Perl install (often by Corion), this issue is avoided in this case by using Strawberry Perl, which presumably comes with the very same compiler that was used to compile Strawberry Perl (gcc in the form of minGW).

Setup

So far I have:

Problems with "undefinded reference to" errors

Starting with Glib because I think that Gtk might be dependent on it, our first compile gives us a thousand or so undefined reference to errors, which syphilis tells me indicates that the compiler can't find some library files. There are three possible reasons for this:

  1. the compiler hasn't been told where the libray file is
  2. the library isn't where the compiler thinks it is, or it's got the wrong name (see the comment above about renaming libraries with a .a file extension)
  3. the library is missing or not installed ("easy" solution, find it, install it)

We managed to make it compile by appending missing Glib libraries to EXTRALIBS and LDLOADLIBS in the Makefile in the general form of $ENV{'GTK_BASEPATH'}.'\lib\'.$lib_file. This works, Glib compiles. Huzzah! Now shouldn't Makefile.PL do this for us? Or throw an error if $ENV{'GTK_BASEPATH'} is not set or null?

This can be generalised for any undefined reference to errors by checking the #     LIBS => comment in the Makefile kindly left there by MakeMaker (in this case -lglib, -lgobject, and -lgthread) and locating the library files listed there and appending their complete paths to EXTRALIBS and LDLOADLIBS.

Missing header files

Next on the list is cairo, which only requires cairo.a added to the library paths. Easy you think. Not quite. Cairo suffers from the other common compiler issue, 'missing' header files, in this case cairo.h. I use 'missing' in quotes because like before, it's more likely that the compiler hasn't been told where the header file is, rather than it's absent. In this case it's simply a matter of adding the path to the directory containing the header file in question INC entry in the Makefile. Now the phrase 'INC' may appear hundreds of times in the Makefile so the key here is to look for 'INC =' ('INC=' won't work because MakeMaker tends to use that format for it's comments). Do that and it's done.

Missing dll reference libraries

On to Gtk2, which exhibits both of the previous issues, and an additional one. After compiling and installing Glib and Ciaro, explicitly linking their libraries, and include directories, there still seem to be at least one library file missing. These are the dll reference libraries, which have not been created or installed by the Makefile. Again syphilis comes to the rescue with instructions on how to use dlltool:

  1. During the building of the Glib module, a file named Glib.def is created. Using Visual Studio's lib utility create, from Glib.def, an import lib named Glib.a as follows:
    lib /OUT:Glib.a /DEF:Glib.def
    With MinGW, the same can be achieved with:
    dlltool --input-def Glib.def --output-lib Glib.a --dllname Glib.dll
  2. Repeat step 1 for the Cairo module.
  3. Copy Glib.a to
    C:/strawberry/perl/site/lib/auto/Glib
  4. and copy Cairo.a to
    C:/strawberry/perl/site/lib/auto/Cairo
    I'm assuming a standard Strawberry Perl directory structure - modify accordingly.
  5. Open the generated Makefile and, to the EXTRALIBS and LDLOADLIBS entries (in the MakeMaker const_loadlibs section), append:
    C:\strawberry\perl\site\lib\auto\Glib\Glib.a C:\strawberry\perl\site\ +lib\auto\Cairo\Cairo.a

Conclusion

The compiler environment provided with Strawberry Perl is complete, but when a module requires additional libraries there will be some Makefile editing required. The irritating part of this problem is that the locations for all the library and header files is specified in the $ENV{'LIB') and $ENV{'INCLUDE'} environment variables, which have been incorporated into CPAN's Config.pm (well they have explicitly by my reconfiguring script) and passed to Makefile.PL. My initial assumption is that Makefile.PL is either discarding this information or it's not doing enough with it to explicitly incorporate it into the Makefile. Now that we have a more standardised compiler environment with minGW that works with both Strawberry Perl and ActiveState Perl, perhaps module developers can be more certain about the compiler environment available to Perl and CPAN, hence might be able to make more robust Makefiles for Windows. Alternativly Makemaker could be updated to do this for them.

Capturing output from the make utility

Thanks to syphilis's reply we can capture compiler and make output can be captured with the following commands:

perl Makefile.PL >p.txt 2>&1 dmake >d.txt 2>&1 dmake test >t.txt 2>&1 dmake install >i.txt 2>&1

Please comment and tell me if I need or should do something.

Other Resources

Finally there are also these resources online:

UPDATE: We have complied Glib, incorporated material into meditation. More updates... progress. Also I want Gtk2 not Gtk. Our most gracious mentor syphilis (give him all your ++) has managed to compile Gtk2, I have now replicated this feat.

UPDATE: I have now added all our work to the root node. Please comment if I have made any gross errors, or misleading anyone.


PS: this is a work in progress, I haven't yet finished reading through all the materials I've linked to. This meditation is as much a reference for me to work from as it is to inform. Eventually I hope to unify all this into a How-I-Did-It kinda post.

1 Thanks to syphilis for mentioning this