Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems packing freetype library #67

Closed
sciurius opened this issue Sep 16, 2022 · 12 comments
Closed

Problems packing freetype library #67

sciurius opened this issue Sep 16, 2022 · 12 comments

Comments

@sciurius
Copy link

PAR::Packer 1.056, PAR 1.017, Strawberry 5.30.2, Windows10

I have a program that uses Imager. Imager demand loads backends for writing PNG files and font handling. It works fine when packed but other users reported problems with the font handling.

I've boiled it down to a small test program borrowed from the Imager tutorial (see below). I use the following pp settings:

--addfile=FreeSansBold.ttf
--module=Imager
--module=Imager::Font::FT2
--module=Imager::File::PNG

At least one user reports problems similar to

No font drivers enabled that can support this file, rebuild 
Imager with any of tt (FreeType 1.x), ft2 (FreeType 2.x) to use this 
font file at ...

Inspection shows that the generated
exe does not include 'libfreetype-6__.dll`but I'm not sure that is relevant.

The attached zip contains the sample program, and associated files, plus the generated binary.
prog.zip

@shawnlaffan
Copy link

The call below seems to work.

I ran objdump on all the .xs.dll files under the ...\site\lib\auto\Imager folder to get the set. This is using strawberry perl 5.32.1.1.

set dllpath=c:\perls\5.32.1.1_pdl\c\bin
pp --link %dllpath%\libpng16-16__.dll --link %dllpath%\libharfbuzz-0__.dll --link %dllpath%\zlib1__.dll --link %dllpath%\libbz2-1__.dll --link %dllpath%\libfreetype-6__.dll --link %dllpath%\libgraphite2__.dll --link %dllpath%\libfreetype-6__.dll --link %dllpath%\libt1-5__.dll -x --addfile=FreeSansBold.ttf -M Imager:: --module=Imager prog.pl

@rschupp
Copy link
Owner

rschupp commented Sep 16, 2022

@shawnlaffan thanks, you beat me to the punch

@sciurius Note you probably have to modify the dllpath environment variable in Shawn's recipe to match your configuration.

Just to explain the problem, PAR::Packer correctly packed the following DLLs into your prog.exe (just run unzip -l prog.exe):

   911872  2020-03-17 04:41   lib/auto/CryptX/CryptX.xs.dll
    23040  2020-03-17 03:23   lib/auto/Cwd/Cwd.xs.dll
    23552  2020-03-17 03:24   lib/auto/Fcntl/Fcntl.xs.dll
    30208  2020-03-17 03:24   lib/auto/File/Glob/Glob.xs.dll
    25088  2020-03-17 03:39   lib/auto/IO/IO.xs.dll
    89600  2022-09-14 15:26   lib/auto/Imager/File/PNG/PNG.xs.dll
    74752  2022-09-14 15:25   lib/auto/Imager/Font/FT2/FT2.xs.dll
   555520  2022-09-14 15:26   lib/auto/Imager/Imager.xs.dll
    54272  2020-03-17 03:48   lib/auto/List/Util/Util.xs.dll
    22016  2020-03-17 03:42   lib/auto/Math/BigInt/FastCalc/FastCalc.xs.dll
   251904  2020-03-17 04:20   lib/auto/Math/BigInt/GMP/GMP.xs.dll
   132096  2020-03-17 03:25   lib/auto/POSIX/POSIX.xs.dll
    43008  2020-03-17 03:44   lib/auto/Socket/Socket.xs.dll
    73216  2020-03-17 03:46   lib/auto/Win32/Win32.xs.dll
    76288  2020-03-17 03:26   lib/auto/Win32API/File/File.xs.dll
    26112  2020-03-17 03:26   lib/auto/mro/mro.xs.dll

These are the "glue" DLLs produced when you built and installed, for example, Imager/File/PNG/PNG.xs.dll from Image::File::PNG. This DLL actually links against the "real" PNG shared library, on your system that's libpng16-16__.dll. But PAR::Packer does not inspect PNG.xs.dll to detect this and hence doesn't pack libpng*.dll into the executable. The executable will work fine on the machine you generated it on, because it's installed there, but it won't work on your user's machine (unless they have installed libpng*.dll by chance). You can make this work by adding --link libpng16-16__.dll to your pp command line.
It's actually more complicated since libpng*.dll itself links against the zlib compression library, zlib1__.dll on your system, so you have to add --link zlib1__.dll, too.

I should plug here Shawn's https://github.com/shawnlaffan/perl-pp-autolink tool, that will do the work for you to (recursively) detect dependent shared libraries, locate them on your machine and construct the necessary --link options.

@shawnlaffan
Copy link

pp-autolink had a bug where it was not scanning all the .xs.dll files on windows. It should be fixed in shawnlaffan/perl-pp-autolink@387fd97 which I'll upload to cpan tomorrow, and once I check the related logic for other operating systems (and update the CI).

@sciurius
Copy link
Author

Hi Roderich and Shawn,
Thanks for your comments. Adding the extra dll's did, indeed, fix the problem.

I must admit I'm not familiar with Windows, I use it only occasionally to build releases of some of my software packages. PAR::Packer is a great help.
I've tried pp_autolink (2.04 + patch 387fd97) but it did not find any libraries:

pp_autolink --output=prog.exe --module=Imager --module=Imager:: prog.pl
DLL check iter: 1
No alien system dlls detected

Detected link list:
CMD: pp --output=prog.exe --module=Imager --module=Imager:: prog.pl

Puzzling...

@rschupp
Copy link
Owner

rschupp commented Sep 16, 2022

I must admit I'm not familiar with Windows,

@sciurius Note that the problem is not specific to Windows, i.e. pp not packing dependent libraries. But on Linux for common libraries (e.g. libpng, zlib or libfreetype) you won't notice as they are typically installed on your user's machines (e.g. any graphical desktop would require these).

@sciurius
Copy link
Author

Hmm. Apparently pp_autolink only processes --link and doesn't handle --module.

@shawnlaffan
Copy link

I've tried pp_autolink (2.04 + patch 387fd97) but it did not find any libraries:

It needs the -x flag to work in this case. Otherwise Module::Scandeps does not return the full set of libs.

Hmm. Apparently pp_autolink only processes --link and doesn't handle --module.

That would likely help with the above case. Patches welcome.

@sciurius
Copy link
Author

Speaking of patches, this is something I severely miss at times:

--- lib/pp.pm~  2022-09-17 15:46:12.791363348 +0200
+++ lib/pp.pm   2022-09-17 16:32:15.863380766 +0200
@@ -14,7 +14,7 @@
 use PAR ();
 use Module::ScanDeps ();
 use App::Packer::PAR ();
-use Getopt::ArgvFile default=>1;
+use Getopt::ArgvFile default=>1, resolveEnvVars=>1;
 use Getopt::Long qw(:config no_ignore_case);
 

Rationale: I have options files that contain library links, eg.

--link=C:/Strawberry/perl/site/lib/Alien/wxWidgets/msw_3_0_2_uni_gcc_3_4/lib/wxbase30u_gcc_custom.dll
--link=C:/Strawberry/perl/site/lib/Alien/wxWidgets/msw_3_0_2_uni_gcc_3_4/lib/wxbase30u_net_gcc_custom.dll
--link=C:/Strawberry/perl/site/lib/Alien/wxWidgets/msw_3_0_2_uni_gcc_3_4/lib/wxbase30u_xml_gcc_custom.dll
...etc...

and I would rather have the physical location and version abstracted out, eg.

--link=${WXLIBS}/wxbase${WXLVV}_gcc_custom.dll
--link=${WXLIBS}/wxbase${WXLVV}_net_gcc_custom.dll
--link=${WXLIBS}/wxbase${WXLVV}_xml_gcc_custom.dll
...etc...

This is easier to maintain.

@sciurius
Copy link
Author

BTW, is it normal that I have to disable Windows Defender to run pp?

pp --link c:\strawberry\c\bin/libgraphite2__.dll --link c:\strawberry\c\bin
/libfreetype-6__.dll --link c:\strawberry\c\bin/zlib1__.dll --link c:\strawberry
\c\bin/libpng16-16__.dll --link c:\strawberry\c\bin/libharfbuzz-0__.dll --link c
:\strawberry\c\bin/libbz2-1__.dll -o prog.exe prog.pl
The system cannot execute the specified program.

@rschupp
Copy link
Owner

rschupp commented Sep 17, 2022

BTW, is it normal that I have to disable Windows Defender to run pp?

I've seen several times that some packed executables trigger malware signatures (in your case of pp it's probably the intermediate executable that's run to determine the modules to pack into the FILE section of the final prog.exe) - nothing I can do about it.

@sciurius
Copy link
Author

Hence the question: Is it normal? Apparently it is...

@rschupp
Copy link
Owner

rschupp commented Sep 18, 2022

Speaking of patches, this is something I severely miss at times:
...
use Getopt::ArgvFile default=>1, resolveEnvVars=>1;

Done in 20d5707 - I didn't even know about this parameter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants