Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

pp -o output.exe myfile.pl (on Linux)

Status
Not open for further replies.

zackiv31

Programmer
May 25, 2006
148
US
is it possible to compile windows exe on a linux box?

Code:
pp -o output.exe myfile.pl

After doing this.. if I try to run it on linux (i know i shouldn't), it complains about a module.. so does linking modules not work with the above code? It specifically Complains about DateTime... but thats the first module I've listed... I'm using about 6 of them.

The Ultimate Goal:
I want to create an exe that can run alone on a windows box. I copied this exe to my XP machine and when I run the 3meg file on my box it gives me an error:
Program too big to fit in memory.

What gives? I'm new to pp
 
You can't compile a program in Linux and expect it to run in Windows. Windows and Linux are binary incompatible at their very core. It's the same reason why Windows programs won't run under Linux (without the help of Wine or Crossover, but even they aren't perfect; they just try their best to translate the system calls but they aren't 100% good at what they do).

Something else to note about PP is that it only searches @INC for modules. So if you use a local library, i.e. 'use lib "./lib";', you need to explicitly define that in the PP command.

Example:

Code:
pp -I ./lib -M attributes -o output input.pl

That's the kind of command I have to run on one of my programs, because I use a local lib, and I also use threads::shared, which implies attributes, but pp doesn't know that by default, so I use "-M attributes" to explicitly load the attributes module as well.

If you want to compile a program, on Linux, and make it work in Windows, I'd highly recommend you install Windows inside a virtual machine (I recommend VirtualBox), and compile it in there using a Windows version of Perl.

Even using Wine with Win32 ActivePerl isn't a very good idea, because as I said, Wine isn't perfect at running Windows apps, and using Wine to compile an app that you expect to run on Windows is just asking for trouble.

-------------
Cuvou.com | My personal homepage
Project Fearless | My web blog
 
Ok I'll have to install ActivePerl on my XP box..

so is there a simple switch to 'pp' to compile in all the modules I have listed? Just to test this out on Linux before I struggle with ActivePerl
 
How are your modules listed?

If they're just like this,

Code:
#!/usr/bin/perl -w

use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use Tk;
use Tk::PNG;
use Tk::ROText;

then pp will do a pretty good job of automatically including all those modules.

If you have something like this:

Code:
#!/usr/bin/perl -w

use strict;
use warnings;

use lib "./lib";
use Time::Format qw(time_format);
use Time::Zone;
use Net::IRC;

Then strict and warnings would be included, but if Time::Format, Time::Zone, and Net::IRC are all in your "./lib" folder, you need to do the "-I ./lib" thing on the command line.

For the most part, just compile it and see if it runs. Usually if there are any problems with modules, usually it's only 1 or 2 modules that are wacky. If it's missing a module that you had in a local lib (and not in @INC), just make sure the -I switch was used. If it's a module you didn't even think you used, just compile again with -M for that module (i.e. I use threads and threads::shared, and threads::shared implies attributes, but I didn't know that til I compiled and tested and it said attributes.pm was missing).

-------------
Cuvou.com | My personal homepage
Project Fearless | My web blog
 
It gives me an error with DateTime... this seems like a pretty standard package...

Code:
#!/usr/bin/perl

use strict;
use Data::Dumper;
use DateTime;
use HTML::LinkExtractor;
use HTML::Entities;
use Spreadsheet::ParseExcel;
use Spreadsheet::WriteExcel;
use LWP::Simple qw( get ); #     use LWP::Simple qw( get );

I tried compiling with this

Code:
pp -M=DateTime myfile.pl


still results in this:

Code:
me@x61u:~/$ ./a.out 
Can't locate DateTime/Locale/en.pm in @INC (@INC contains: CODE(0x1234690) /tmp/par-me/cache-6cabf90c7de7b8393d9407c0cc4e2093608623c4/inc/lib /tmp/par-me/cache-6cabf90c7de7b8393d9407c0cc4e2093608623c4/inc CODE(0x9af7b0) CODE(0x9afa40)) at (eval 21) line 3.
 
Ok figured out the package manager for ActivePerl.. but I'm having trouble install SpreadSheet::WriteExcel.

I checked out this page:


and next to windows, it says it failed... So I think thats why its not showing up in my Perl Package Manager.

I've linked to two external repositories, bribes and uwinnipeg.. but they don't have the ppm either.

How can I install this package? Where can I find it? Is it possible to manually download a package from CPAN and install it myself under windows? The PackageManager simplifies it so well, but for this one it isn't working.. hmmm
 
pp -M DateTime::Locale::en

Probably DateTime dynamically loads this module after detecting your locale and that's why pp doesn't find it.

Does the perl source run for you? If it runs as a perl source but won't run as a compiled binary, it means that you do indeed have DateTime::Locale::en installed, just that pp isn't finding it because it doesn't have an explicit use anywhere.

-------------
Cuvou.com | My personal homepage
Project Fearless | My web blog
 
My script runs perfectly fine as itself... pp'ing it is still giving me issues.

Code:
 pp -M DateTime::Locale::en -M DateTime::TimeZone query.pl

I included the second module because it's giving me this error:

Code:
The timezone 'EST' could not be loaded, or is an invalid name.

for this line:
Code:
my $d = DateTime->now(time_zone => 'EST')
 
Getting weirder and weirder... I print out all the time zone names on my box before I try to assign.. and it prints out all the time zones, but tells me that my TimeZone could not be loaded... wt!

Code:
print Dumper(DateTime::TimeZone->all_names);
my $tz = DateTime::TimeZone->new(name => 'America/New_York');

Still giving:
Code:
The timezone 'America/New_York' could not be loaded, or is an invalid name.
 
Slowly figuring this out, someone yell at me if I should stop posting in this thread.

I have to explicitly pp -M the "DateTime::TimeZone::America::New_York" module in my pp build... but I have a problem with this.

I will be running the script and it may dynamically need to reference other time zones, UMT, GMT... HongKong, whatever..

How Can I compile all of these into the .exe without listing all 100+ of them with the -M option. I tried a

Code:
pp -M DateTime::TimeZone::* myfile.pl

but of course the * is invalid. how can I do this?

here's the head of my file again:

Code:
!/usr/bin/perl

use strict;

use Data::Dumper;
use DateTime;
use DateTime::TimeZone;
use HTML::LinkExtractor;
use HTML::Entities;
use Spreadsheet::ParseExcel;
use Spreadsheet::WriteExcel;
use LWP::Simple qw( get ); #     use LWP::Simple qw( get );
 
Best way I could see to do it:

List all of them in 'use' statements in your file.

If there's a ridiculous amount of them, you could even just write a quick Perl script to scan the perl module's directory and automatically add every module to an output file with "use"s on them, and then copy/paste the output into your script.

Other than that, dynamic modules are a pain to compile. It wouldn't be any easier with PerlApp because you'd still need to browse and select every module in the "extra included modules" thing.

-------------
Cuvou.com | My personal homepage
Project Fearless | My web blog
 
There are a lot:

At the bottom it has a
DateTime::TimeZoneCatalog

but that doesn't seem to work... I guess there's nothing I can really do then..


Here's my final use block for working set for only EST:

Code:
!/usr/bin/perl

use strict;

use Data::Dumper;
use DateTime;
use DateTime::TimeZoneCatalog;
use DateTime::TimeZone::EST;
use DateTime::Locale::en;
use HTML::LinkExtractor;
use HTML::Entities;
use Spreadsheet::ParseExcel;
use Spreadsheet::WriteExcel;
use LWP::Simple qw( get ); #     use LWP::Simple qw( get );
 
Maybe...

Code:
sub scanDir {
   # home made recursive directory scanner
   my $dir = shift;

   my @mods = ();

   opendir (DIR, $dir);
   foreach my $file (sort(grep(!/^\./, readdir(DIR)))) {
      if (-d "$dir/$file") {
        # Recurse.
        push (@mods, &scanDir("$dir/$file");
      }
      elsif ($file =~ /\.pm$/i) {
        # Perl module.
        $file =~ s/\.pm$//i;
        push (@mods,"$dir/$file");
      }
   }

   return @mods;
}

# Scan the DateTime directory.
my @mods = &scanDir("/usr/lib/perl-5.8.8/DateTime");
# you'd make that the actual path to the lib

# Now @mods should contain things like this...
@mods = (
   '/usr/lib/perl-5.8.8/DateTime/TimeZoneCatalog',
   '/usr/lib/perl-5.8.8/DateTime/TimeZone/EST',
   '/usr/lib/perl-5.8.8/DateTime/Locale/en',
   # etc...
);

# so filter them back into normal module names

open (OUTPUT, ">out.txt");

map {
   $_ =~ s~^/usr/lib/perl\-5\.8\.8/~~i;
   $_ =~ s~/~::~g;
   print OUTPUT "use $_;\n";
} @mods;

close (OUTPUT);

# should get ya an out.txt along the lines of
use DateTime::TimeZoneCatalog;
use DateTime::TimeZone::EST;
use DateTime::Locale::en;
# etc. for all the modules

Of course, your final executable size might be considerably larger for including every one of those modules... but that's one way I would do it if I was making this program and it was really important to have those modules.

And then I'd probably convert that script above to work for any gang of modules and keep it around for future use (maybe have it smart enough to search @INC and all it needs for input is a kind of regular expression, DateTime::*)

-------------
Cuvou.com | My personal homepage
Project Fearless | My web blog
 
I face the same problem.
Here is how I solved it:

Step 1:
pp -p filename.pl -o filename.par

Step 2:
Open filename.par with a ZIP archiver
Drag and drop relevant contents of c:\perl\site\lib into it
(that adds the DateTime, Locale and some other classes required)

Step 3:
pp filename.par -o filename.exe

That works for me.

I recently released a project that needed this as open source. You can see it here: (see Source Code tab for source - click on trunk)

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top