perlapp

"No perl found at C:\perl\bin\perl.exe" when using PerlApp

Question: 

When I try to use PerlApp I get the following error: "No perl found at C:\perl\bin\perl.exe" -- but that file is really there. What's going on, and how can I fix it?

Answer: 

This message is usually caused by the directory containing cmd.exe not being found in your PATH environment variable. The usual directory to ensure is there is C:\Windows\System32. If it's missing, simply add it and PerlApp will work as expected.

Making expiring ("time bombed") executables with PerlApp.

Question: 

Can I put a time limit on my executeable which I create with PerlApp?

Answer: 

Yes. This sample program will run normally when you invoke it as `perl expire.pl`, but will refuse to run after the expiration date when it has been compiled with PerlApp.

You could hard-code the expiration data in your program, or you can supply it when you build the executable and retrieve it inside your application from a bound file:

BEGIN {
    return unless defined $PerlApp::VERSION;
    my $expire = PerlApp::get_bound_file("expire") or return;
    my($y,$m,$d) = (localtime)[5,4,3];
    my $today = sprintf("%04d-%02d-%02d", $y+1900,$m+1,$d);
    return if $today le $expire;
    print "expired\n";
    exit;
}
print "ok\n";

For example:

c:\tmp> date /t
Wed 02/14/2007

c:\tmp> perlapp -f --nologo --bind expire[data=2007-02-13] expire.pl

c:\tmp> expire
expired

c:\tmp> perlapp -f --nologo --bind expire[data=2007-02-14] expire.pl

c:\tmp> expire
ok

Programs using Perl source filters can't be wrapped with PerlApp

Question: 

I wrote a script that uses the Switch Perl module. It works great unwrapped, but when I wrap it with PerlApp it doesn't work.

Answer: 

This happens because the Switch module is implemented as a Perl source filter. Currently, code that uses source filters cannot be processed by PerlApp. There is no easy work-around for this that I am aware of -- the only option at this point seems to be to convert the code using Switch to use if...elsif...else clauses or one of the other alternatives from the perlsyn manual page.

Using PerlApp with Unicode source files including a BOM

Question: 

My Perl program works great, until I compile it with PerlApp. When I run the executable, I get the error message "Unrecognized character \xEF at foo.pl line 1."

Answer: 

Fortunately, this one has an easy, though easy-to-miss solution.

The file is saved in Unicode, and there is a Byte-Order Mark (BOM) present. A BOM helps a text editor figure out what byte order the file is saved in, but it can cause problems with PerlApp and other tools.

The solution is to save the file (or a copy of the file) without a BOM, and use that copy of the file when running PerlApp.

Using Komodo you can turn off BOMs for the current file by going to Edit | Current File Settings and deselecting "Use signature (BOM)". Other editors will do it different ways, but it's almost always possible -- check the manual or help system for your editor.

PerlApp with Perl 5.8 generates huge executables

Question: 

When I use PerlApp with Perl 5.8 the resulting executable is several times larger than when I used Perl 5.6. How do I make it smaller?

Answer: 

More than a few people are surprised when they upgrade to PDK 6.0.x and ActivePerl 5.8. In addition to being more solid than ActivePerl 5.6 with PDK 5, the freestanding executables are sometimes three or four times larger.

There is one word that is responsible for much of this apparent bloat: Unicode.

When PerlApp puts together an executable in freestanding mode, it has to be sure to include all required modules and their contingent bits and pieces. Because PerlApp can't tell if a conditionally required module will be needed, it includes it to be on the safe side. Often, this is how the Unicode modules (which aren't all that big) and the translation tables (which are that big) get involved.

The easiest way to cure this problem is to trim out the Unicode modules and related files using the PerlApp graphical user interface, or --trim arguments on the command line. Whichever way you choose, you should be aware that some modules generate and use Unicode internally. If your application begins to fail after removing the Unicode modules and/or translation tables, you will need to play with it a bit to figure out which are needed and which aren't for your given application.

The best way to get the initial settings correct is to use the PerlApp graphical interface. There you can see which modules and extra files will be included, and have the opportunity to trim them out. When you have everything set up correctly, the Output tab of the graphical interface will show you the command line you need to use to reproduce the build with those settings.

This should bring the size down substantially. If it does the trick for you, let me know and I will give some rough numbers that I hear from people as examples in a future version of this entry.

Including POD in PerlApp executables

Question: 

How can I include POD in scripts and modules compiled by PerlApp?

Answer: 

When PerlApp compiles your code, it strips out all pod from script or module files. If you need to use pod2text, you can work around this by:

  • including the pod data in a separate .pod file
  • including this .pod file in your build using the --bind option.

Here's how you create perl scripts that will work both as a script and an executable (working with bound files):

  # this is the file we want to access in our code
  my $file = "/path/to/this.file";

  # test if we are running as a script or executable
  $file = PerlApp::extract_bound_file($file) if defined $PerlApp::VERSION;

You would then build the PerlApp executable using the --bind option:

  perlapp myscript.pl --bind this.file[file=/path/to/this.file]

See also:

Perl Docs

Code obfuscation

Question: 

Will people be able to decompile the executables I've made with PerlApp?

Answer: 

PerlApp does provide some level of code obfuscation. Decompiling executables is not trivial, but it is possible.

Critical copyrighted data and algorithms should not be included in Perl code within a PerlApp. If you are concerned about keeping important parts of your code secret, you may want to consider some workarounds such as:

  • using strong encryption for critical data
  • implementing critical algorithms as XS modules that can be used by your Perl code.

Suppress console windows when using backticks

Question: 

How do I stop console windows from popping up when i call commands in backticks?

Answer: 

Using perlapp's --gui option should hide normal perl command line output, but system commands called within backticks may still open command line windows. To suppress this, try adding the following block to your script:

BEGIN {
    Win32::SetChildShowWindow(0) if defined &Win32::SetChildShowWindow;
}

This should work using ActivePerl version 632 or later.