我试图用我的 Perl 代码制作一个可执行文件,然后我意识到perl
编译器没有这样的选项。经过一番搜索,我找到perlcc
了 ,它是 Perl 编译器的前端,可以完成这项工作(生成二进制文件)。
为什么 Perl 有单独的编译器和前端?例如,gcc
对于 C/C++ 而言,它本身就是一个完整的工具。这就是它的方式,还是有一些好的原因?
这个答案是很久以前写的,不反映当前状态。我宁愿删除这个答案,但我不能,因为它被接受了。请参阅Reini 的答案。
人们将 Perl 程序编译为二进制文件并不常见。很多人都想这样做,但这不是它的工作方式。你想达到什么目的?可能有另一种方法可以做你想做的事。
Perl 程序实际上分两个阶段执行:编译时和运行时。它也是一种动态语言,因此您无法在编译阶段结束时告诉您需要编译的所有内容,并且在编译阶段您可能必须运行一些代码。
Perl 在这方面更像 Java 或 Ruby 而不是 C。当您运行 Perl 程序时,perl
解释器会加载所有源代码并将其编译成抽象语法树。它是在运行时perl
执行(或解释)的字节码。这与 Java、Ruby 和 Python 所做的事情相同。
Perl 的一个缺点是它没有像其他语言那样保存编译结果的好方法。这意味着您最终每次都编译源代码。有一些方法可以使用pperl
特定领域的工具,例如 mod_perl 或 fastcgi。
里面有一些模糊位,带有BEGIN
块,eval
等等,但这主要是它的工作方式。perlmod中有更多细节。
如果我们从现在所知道的一切重新开始,这个设计缺陷就不会存在,事实上,在 Perl 6 中它不存在。:)
我确定您指的是在perlcc
5.8.9 之前 perl 随附的 B::C 套件。从那以后,我接手了自 1997 年以来没有得到增强的 perl 编译器的开发,并修复了大部分剩余的错误。
为什么 perl 有单独的编译器和前端?
首先(对于其他人):perl 是 perl 的唯一官方前端,即解释器。
perlcc
是编译器的前端B::C
,B::Bytecode
(-B)和B::CC
(-O),C链接器部分cc_harness
也在。
没有人真的想弄乱后端的各种选项。使用perlcc
起来要容易得多。就像gcc
作为所有后端和中间步骤的驱动程序一样。gcc 对于所有中间步骤也有不同的可执行文件:
cc1, cc1plus, collect, as, ld
你想自己打电话cc1
吗?我从来没有见过这个。
这是否充分回答了您的问题?
顺便说一句,基本上之前所有的答案都是完全错误的,没有人直接回答 Lazer 的问题。
@briandfoy:perlcc不是一个死工具,它正在稳步发展,并用于生产代码。启动时间大大加快。您可以发布单个可执行文件。90% 的正常 perl 工作。您也可以使用 .pmc(就像 python 一样),但只有大型网站才能这样做。我建议使用 CPAN 的版本。
perlcc 基本上在 CHECK 时创建一个转储,然后执行转储。因此,perl 打包程序(PAR、perl2exe、perlapp)存在语义差异,它们创建转储并在 BEGIN 之前执行它们。请参阅 CPAN 上 B::C 中的 perlcompile.pod。
@mkb:perlcc 支持并没有减弱。p5p 只是没有足够的能力来修复剩余的错误。所以我做了。见http://search.cpan.org/dist/BC/。
@Chas:当然 perl5 会编译成某种“字节码”,即 optree。B::Bytecode 编译器可以用来转储它,而 ByteLoader 用来运行它。还有转储到 XML 的 MAD。还有 -u 转储为二进制表示。哪个可以用于undump
exe。只需要一个简单的类似链接器的步骤,我还没有时间。
@Novikov:Perl 编译为字节码,然后运行它。就像大多数脚本语言一样。Perl 具有 perlcc,因此您可以将其编译为本机可执行文件。
@zigdon:您将其与 perl2exe 和 PAR 之类的打包程序混为一谈。
也许是因为FAQ 中perl 编译器的输入仍然错误,所以我们遇到了麻烦。
更正:这是一个单独的前端。perl
并不是真正的字节码编译器。“编译” Perl 的最终形式是一组抽象语法树,然后由解释器使用。Perlcc 支持衰落了,因为该语言变化得足够快,以至于它从未跟上。它解决的问题大多可以通过其他方式解决,不需要不断维护单独的源代码树。
因为 Perl 5 不能编译成字节码。另一方面,Perl 6 可以编译成在 Parrot 虚拟机上运行的字节码。
Perl 程序不像 C 程序那样编译,它们在运行时被解析。perlcc 所做的只是尝试将 perl 可执行文件和您的程序所需的任何库捆绑到一个二进制文件中。在运行时,脚本仍将被解释,而不是从二进制数据运行。
Perl 是一种解释型语言,而 C/C++ 不是。