rschupp / PAR-Packer

(perl) Generate stand-alone executables, perl scripts and PAR files https://metacpan.org/pod/PAR::Packer
Other
48 stars 13 forks source link

PAR-Packer lost a line of string when packing Unicode::GCString #87

Closed saxyx closed 5 months ago

saxyx commented 5 months ago

If I have a perl file named aa.pl:

use strict;
use warnings;
use Unicode::GCString;
use utf8;

my $stringToBeMeasured = "你好,世界";
my $gcstring = Unicode::GCString->new($stringToBeMeasured);
my $columns = $gcstring->columns();

print $columns;

When I run pp -T -M Unicode::GCString --output aa.exe aa.pl to generate aa.exe, and then execute aa in the cmd, I encounter the following error message: Can't locate object method "new" via package "Unicode::GCString" at script/aa.pl line 7.

The first 10 lines of GCString.pm extracted from aa.exe are as follows:

#-*-perl-*-

package Unicode::GCString;
require 5.008;

=cut

### Pragmas:

The first 10 lines of GCString.pm from the local library are:

#-*-perl-*-

package Unicode::GCString;
require 5.008;

=encoding utf-8

=cut

### Pragmas:

Therefore, it seems that pp loses the line =encoding utf-8 when packaging Unicode::GCString.

Info:

rschupp commented 5 months ago

PAR::Filter::PodStrip stumbles over

=encoding utf-8

=cut

and removes just the =encoding while leaving =cut. Hence perl interprets everything below =cut as POD, i.e. no perl code. As a quick workaround set the environment variable PAR_VERBATIM=1 while packing to disable use of PodStrip.

rschupp commented 5 months ago

BTW: pp -T -M Unicode::GCString --output aa.exe aa.pl

saxyx commented 5 months ago

Thank you very much for your help and advice. I use -T because I don't want it to decompress and take up space every time I use the aa.exe. I learned the skill from https://stackoverflow.com/questions/34351026/how-to-reduce-par-folder-size-in-tmp.

rschupp commented 5 months ago

I learned the skill from https://stackoverflow.com/questions/34351026/how-to-reduce-par-folder-size-in-tmp.

That's typical stackoverflow nonsense. Don't use -T.

Here's why: create a file named Foo.pm with contents

package Foo;
sub greeting { print "hello\n" };
1;

then run

$ pp -o hello.exe -T WTF -I . -E 'use Foo; Foo::greeting();'
$ .\hello.exe
hello

so faras expected. Now change "hello" to "good bye" in Foo.pm and pack again

$ pp -o hello.exe -T WTF -I . -E 'use Foo; Foo::greeting();'
$ .\hello.exe
hello

Oops! The second incarnation of hello.exe reused the cache area of the first and didn't extract the new version of Foo.pm. If you're concerned about the stuff that accumulates in your cache area, simply blow the cache area away.

saxyx commented 5 months ago

Thanks again for your patient advice.

According to the documentation at https://metacpan.org/pod/pp:

-T, --tempcache Set the program unique part of the cache directory name that is used if the program is run without -C. If not set, a hash of the executable is used.

When the program is run, its contents are extracted to a temporary directory. On Unix systems, this is commonly /tmp/par-USER/cache-XXXXXXX. USER is replaced by the name of the user running the program, but "spelled" in hex. XXXXXXX is either a hash of the executable or the value passed to the -T or --tempcache switch.

The reason why

The second incarnation of hello.exe reused the cache area of the first and didn't extract the new version of Foo.pm.

is that you specified the value passed to the -T switch. It wouldn't be a problem if you didn't specify a specific value.

rschupp commented 5 months ago

It wouldn't be a problem if you didn't specify a specific value.

That's because -T without an argument is simply ignored. And it doesn't help "I don't want it to decompress and take up space every time I use the aa.exe" either: if you don't regenerate an executable, decompression happens on the first run, after that the cache area is reused.

saxyx commented 5 months ago

Thank you very much. I misunderstood earlier, now I understand what you mean.