如何分发一个包含多个perlapp可执行文件的应用程序,但只分发一个perl解释器?

5

总结问题

我是否只需对每个perl脚本使用perlapp --dependent,然后在构建过程中确保将perl-static复制到应用程序的bin目录中(并命名为perl)?

背景

我目前正在分发许多perlapp独立可执行文件的应用程序,这意味着它们各自包含一个捆绑的perl运行时副本。

我想仅分发一个perl运行时副本,并使每个可执行文件引用我要分发的唯一perl运行时副本。

例如,假设我的应用程序由10个perl脚本组成。当我对两个演示脚本中的每一个执行perlapp时,我会看到类似于以下内容:

+ ls -l
-rw-r--r--  1 -----  staff   55 Feb  5 21:03 t1.pl
-rw-r--r--  1 -----  staff   62 Feb  5 21:03 t2.pl
+ perlapp --force t1.pl
PerlApp 9.5.1 build 300018
Copyright (C) 1998-2016 ActiveState Software Inc. All rights reserved.
Commercial license for ..................................

Created 't1'
+ perlapp --force t2.pl
PerlApp 9.5.1 build 300018
Copyright (C) 1998-2016 ActiveState Software Inc. All rights reserved.
Commercial license for ..................................

Created 't2'
+ ls -l
-rwxr-xr-x  1 -----  staff  2266356 Feb  5 21:07 t1
-rw-r--r--  1 -----  staff       55 Feb  5 21:03 t1.pl
-rwxr-xr-x  1 -----  staff  2026992 Feb  5 21:07 t2
-rw-r--r--  1 -----  staff       62 Feb  5 21:03 t2.pl

ls -l `which perl`
-rwxr-xr-x  1 root  wheel  1978336 Mar 19  2015 /usr/local/ActivePerl-5.20/bin/perl-static

在上面的输出中,您可以看到两个(我目前有10个)可执行文件中的每一个大约为2Mib,每个perl脚本对应一个。在每个捆绑的可执行文件中,都有一个perl运行时。如果我要分发所有这10个,那么分发大小将超过22MiB。
强制客户下载10次perl运行时实际上是一种懒散和浪费的做法,因为该应用程序只需要一个perl运行时。显然,发布仅为一个文件,但它比必要的更大。虽然整个应用程序只是一个perlapp可执行文件,但perl运行时可以方便地捆绑到可执行文件中。但随着时间的推移,功能(即可执行文件)增加,浪费和懒散性也会增加。
正确的方法是,我非常确定必须使用--dependent perlapp命令行选项。当我测试使用该选项时,我看到捆绑的可执行文件大小大大减小。删除临时文件夹并执行依赖的可执行文件后,它似乎已经捆绑了与之前相同的模块。
以下是我的“如何”问题。
Q1(迄今为止最重要的)
如果我在perlapp命令中添加--dependent选项,那么我应该期望perlapp捆绑所有先前捆绑的模块吗?我认为答案是“是”,但我想让像Graham Stuart这样的人回答。
Q2
是否真的只需要确保静态链接的perl在执行这些依赖可执行文件时在PATH中?
Q3(重新措辞的Q2) perlapp捆绑静态链接版本的perl吗?我认为它是,但再次,我想确保我做了等效的事情。
附言
我尝试在ActiveState的pdk论坛上发布主题,但我认为该接口不接受我的帖子,因为它显示我的帖子未发布,而没有提示如何发布。
如果我使用--dependent选项,那么我会看到这个:
+ perlapp --force --dependent t1.pl
PerlApp 9.5.1 build 300018
Copyright (C) 1998-2016 ActiveState Software Inc. All rights reserved.
Commercial license for ..................................

Created 't1'
+ perlapp --force --dependent t2.pl
PerlApp 9.5.1 build 300018
Copyright (C) 1998-2016 ActiveState Software Inc. All rights reserved.
Commercial license for ..................................

Created 't2'
+ ls -l
-rwxr-xr-x  1 -----  staff  108560 Feb  5 21:07 t1
-rw-r--r--  1 -----  staff      55 Feb  5 21:03 t1.pl
-rwxr-xr-x  1 -----  staff  108608 Feb  5 21:07 t2
-rw-r--r--  1 -----  staff      62 Feb  5 21:03 t2.pl

在上面的输出中,你可以看到文件非常小,不可能包含perl运行时。如果我分发perl-static和以上10个可执行文件,那么分发的大小将约为3MiB,节省了大约19MiB。
当我取消设置PATH时,这些可执行文件会引发错误,因为找不到perl可执行文件。这就是为什么我认为分发只需要在bin目录中与可执行文件一起提供perl运行时。这似乎是一个合理的解决方案,但由于我没有编写perlapp,所以我无法真正知道实情。我必须依靠其他人告诉我“是的,你正在做正确的事情,并且在6个月后进行x操作时不会受到影响”。

@ikegami 不,当我的应用程序被复制到用户的桌面上时,我不会安装perl。我故意让应用程序没有安装程序。构建过程将在构建时将本地构建机器的perl放入分发中。我认为这是正确的假设:(1)perlapp消除了安装perl的需要,(2)perlapp仅捆绑模块和perl rutime,(3)复制perl-static并使用perlapp --dependent与perlapp --freestanding相同。 - Jeff Holt
@ikegami 这取决于您对“安装”一词的定义。您选择的词语让我相信您认为我将像下载perl源代码并执行“make install”一样安装perl。但我不打算这样做。 - Jeff Holt
@ikegami,您最后的评论没有意义,因为我的问题是关于如何分发10个perlapp包装的可执行文件,但通过只分发一个perl来节省空间。我不想为每个可执行文件“安装”一个perl。这是一种可怕的浪费。此外,perlapp包装的可执行文件实际上并没有安装任何东西。是的,它会将一些文件写入/tmp(或/var/tmp),但它并没有安装任何东西。这就是为什么它通常被称为独立的原因。 - Jeff Holt
@ikegami perlapp --freestanding 可以避免安装 Perl 的需要。perlapp --dependent 不会将 Perl 运行时与输出可执行文件捆绑在一起。如果我分发与 perllapp --freestanding 捆绑的相同的 perl-static,则分发的应用程序失败的唯一方式是如果应用程序的可执行文件之前被绕过,使得 PATH 包含某些有问题的 Perl。 - Jeff Holt
重复自己是毫无意义的,就像我重复自己一样。 - ikegami
显示剩余4条评论
1个回答

1

这不完全是你寻找的解决方案,但 Win32::Packer 支持该功能。你可以告诉它组成你的应用程序的一组脚本,并将它们打包为一个单独的 MSI 安装程序,其中包含所有依赖项和所有脚本的 .exe 封装。

目前它仅支持 Strawberry Perl,但增加对 AS Perl 的支持也应该不太困难。


我非常感谢您的回答。在对话中深藏着一个半声明的要求,即不能有安装程序。这是为了解决Windows用户可能缺乏管理员权限的问题。问题中没有提到(因为我认为这不是必要的)的要求是支持Windows、Linux和macOS。 - Jeff Holt
@jeff6times7:实际上,Win32::Packer也可以生成不需要任何安装的“.zip”文件。您只需解压缩存档并执行其中包含的程序即可。 - salva
这很好知道。但我的主要关注点是回答我的Q1和Q3。特别是考虑到(直到现在才揭示的)每个3个平台的构建ant脚本已经捆绑了zip(MSWin32),tar.gz(linux)和app(darwin)中所需的一切。让ant脚本复制一个以上的可执行文件是微不足道的。也就是说,假设这是最好的解决方案。因此,我的最初问题。 - Jeff Holt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接