We'll I haven't completely got it working, but it is darn close. I
ended up switching to WxWidgets, which will work with some
coaxing. Most of this kludge is based on bug
reports from Marc Lehmann. Thanks Marc!
First off, we need to create a list of all the Gtk2 files that aren't
picked up automatically by pp. I use this script to create
the list and run pp. Note that I am running the script
under cygwin, but I want to use the ActiveState Perl to run
pp so we end up with a native Windows app. (BTW, I tried
our Strawberry Perl, but it had issues with some of the dependencies due
to a lack of pkgconfig.)
#!/bin/sh
# ppkludge - Automatically package the Gtk2 dependencies with pp
# This is a tweaked version of a script written by Marc Lehmann. Thanks
# for sharing this solution; I would have never figured this out!
#
# The original can be found at: http://data.plan9.de/ppwin
# Here is Marc Lehmann's original comment:
# Convert a gtk2-perl program to a standalone .exe, including all
# libraries and runtime files required for running as well as required
# datafiles. I _literaly_ sold my soul to the devil and paid with blood
# for this. Microsoft die die die die die die die die die die die die
GTK2="/cygdrive/c/Progra~1/Common~1/Gtk/2.0"
(
cat <<EOF
c:\Perl\site\lib\auto\Cairo\Cairo.dll;root/Cairo.dll
c:\Perl\site\lib\auto\Glib\Glib.dll;root/Glib.dll
c:\Perl\site\lib\auto\Gtk2\Gtk2.dll;root/Gtk2.dll
# Here down, needed for systems w/o gtk
`cygpath -w $GTK2/etc`;root/etc
`cygpath -w $GTK2/lib/pango`;root/lib/pango
`cygpath -w $GTK2/lib/gtk-2.0`;root/lib/gtk-2.0
`cygpath -w $GTK2/share/themes/MS-Windows/gtk-2.0`;root/share/themes/MS-Windows/gtk-2.0
EOF
cd "$GTK2/bin" || exit
for dll in *.dll; do
echo "`cygpath -w $GTK2/bin/$dll`;root/$dll"
done
) >addlist
trap "/cygwin/bin/rm addlist" 0
PATH=/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/perl/bin
/cygdrive/c/perl/bin/perl /perl/bin/pp -o test.exe -I lib -A addlist test.pl
This will add the required file to the par/exe archive under the
root/ directory. Now when you start your script, you need
to unzip these files into the par cache directory. Use the following package,
PAR::Kludge, in you script to do so.
package PAR::Kludge;
# This is a package implementing the fix discovered by Marc Lehmann. Thanks
# for sharing this solution; I would have never figured this out!
# The original can be found at: http://txt.schmorp.de/2629b6fdba568e7cda3ed953cbaf8613.txt
use strict;
use warnings;
our $VERSION = '0.30';
BEGIN {
my $dbg; for(@ARGV){ $dbg++ if /^-d|^--debug/;}
print "Running kludge\n" if $dbg;
if (%PAR::LibCache) {
print "kludging\n" if $dbg;
@INC = grep ref, @INC; # weed out all paths except pars loader refs
while (my ($filename, $zip) = each %PAR::LibCache) {
for ($zip->memberNames) {
next unless m!^root/(.*)!;
print "zip: $_\n" if $dbg;
$zip->extractMember ($_, "$ENV{PAR_TEMP}/$1")
unless -e "$ENV{PAR_TEMP}/$1";
}
}
if ($^O eq "MSWin32") {
$ENV{GTK_RC_FILES} = "$ENV{PAR_TEMP}/share/themes/MS-Windows/gtk-2.0/gtkrc";
}
print "Inc:\n", join("\n",@INC),"\n" if $dbg;
print "Temp:\n", $ENV{PAR_TEMP},"\n" if $dbg;
print "Path:\n", $ENV{PATH},"\n" if $dbg;
# print "Chdir to $ENV{PAR_TEMP}\n" if $dbg;
# chdir $ENV{PAR_TEMP} if $ENV{PAR_TEMP};
# use lib "$ENV{PAR_TEMP}/inc/lib";
}
}
1;
All this is all well and good, but it doesn't actually work. I use
glade to design the interface and Gtk2::GladeXML to render it. The
packaged app will work fine until you try to hook up the events with the
$gui-<signal_autoconnect_from_package($self). Leave
that command out and you have a beautifully packaged app (that doesn't
do anything). Add the line and kplow!
The included script and PAR::Kludge packages can downloaded here. If anyone figures out how to
get this working, please let me know!