3

I am trying to make an executable out of my Perl code and then I realized that there is no such option available with the perl compiler. After a bit of searching, I found perlcc, which is a frontend for the Perl compiler and does the job (produces a binary).

Why does Perl have a separate compiler and frontend? Like for example, gcc for C/C++ is a complete tool in itself. Is this just the way it is, or are there some good reasons behind it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lazer
  • 90,700
  • 113
  • 281
  • 364
  • 1
    Perl has various tools that can help you distribute code. However, you have to tell us what you are trying to accomplish so we might recommend the right tool. – brian d foy Sep 01 '10 at 20:25
  • @brian: I am trying to make an executable out of my Perl program before distributing it, so that it would be easier to use for the end users. – Lazer Sep 01 '10 at 20:33
  • 2
    In that case, look at the various questions and answers for ["perl distribute"](http://stackoverflow.com/search?q=perl+distribute) already on Stackoverflow. – brian d foy Sep 01 '10 at 20:53
  • 1
    For binding an executable package, look at PAR::Packer, Cava Packager, perl2exe or ActiveState PerlApp. – daotoad Sep 02 '10 at 02:14
  • Anyone reading this answer should not the date it was asked and the date of the answers and edits. Much has changed in three years. – brian d foy Dec 09 '13 at 04:26

6 Answers6

7

This answer was written a long time ago and doesn't reflect the current state. I'd rather delete this answer, but I can't since it's accepted. See Reini's answer instead.


It's not typical for people to compile Perl programs to a binary. Plenty of people would like to do that, but that's just not the way it works. What are you trying to accomplish? There might be another way to do what you want to do.

A Perl program really executes in two phases: a compile-time and a run-time. It's a dynamic language too, so you can't tell everything you'll need to compile at the end of the compile phase, and during the compile phase you might have to run some code.

Perl is more like Java or Ruby than C in this manner. When you run a Perl program, the perl interpreter loads all the source code and compiles it into a abstract syntax tree. It's that bytecode that perl executes (or interprets) during the runtime. This is the same sort of thing that Java, Ruby, and Python do.

One of Perl's warts is that it doesn't have a good way to save the result of that compilation, like those other languages can. That means you end up compiling the source every time. There are some ways around that with pperl and domain-specific tools such as mod_perl or fastcgi.

There are some fuzzy bits in there with BEGIN blocks, eval, and so on, but that's mostly the way it works. There are more details in perlmod.

This design wart wouldn't be there if we started all over with everything we know now, and indeed, in Perl 6 it isn't there. :)

Community
  • 1
  • 1
brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • Perl doesn't have the "two phases". What is also the main reason why no decent codegen ever materialized: one can't seperate compilation from interpretation. Perl compilation and running are overlapping and and there is no clear seperation: e.g. `BEGIN {}` are ran during syntax check already while `eval ""` or `s///ee` are compiled during run-time. Also many large module feature on-demand compilation where the real code is put past the `__END__` in the `.pm`. IOW Perl can save the results of the compilation - they just not useful since compiler still would be called during run-time. – Dummy00001 Sep 01 '10 at 21:45
  • 2
    Perl basically has two phases. I mentioned the BEGIN and eval as "fuzzy bits". I don't know what you think saves the compilation, but if it's dump, that's the wrong answer too. – brian d foy Sep 01 '10 at 21:48
  • See [B::Concise](http://perldoc.perl.org/B/Concise.html) for example. Perl tree can be represented reliably. It just [makes no sense](http://www.perlmonks.org/index.pl?node_id=45235) since there is no clear separation between compilation and execution, and new stuff could be added to the tree during run-time (`eval "sub {}"`). And yes, that is actively used and deemed important language feature. That means generated executable would still have to contain (or access) the whole of the Perl distro. And that defies the purpose of code generation. – Dummy00001 Sep 01 '10 at 22:22
  • 1
    B::Concise prints a text version of the syntax tree. It doesn't give you something that you can execute. I don't know why you're arguing about eval here. I mentioned that part was fuzzy in my post. I'm not denying that it exists. You can run code during the compile phase, and you can compile code during the run phase, but that doesn't negate that there are two phases. That's how the various blocks like BEGIN, INIT, CHECK, and so on know how to run. – brian d foy Sep 01 '10 at 22:28
  • 1
    @Dum: there are two phases, but each phase can recursively enter the other phase. There was a really good perlmonks article discussing this (and has come up before on previous SO posts) but alas my search-fu is inadequate for the time I currently have to find it. – Ether Sep 01 '10 at 22:34
  • @Ether: well, that [actually four](http://archu.wordpress.com/2006/10/02/perl-interpreted-or-compiled/). But as code generation goes, and why the subject's `perlcc` is useless, is precisely the recurrence. IOW, phases designation at large makes no sense, since in Perl script execution there is no point of time where one can say "from here on it is only interpretation." Compare to Python or Java or C: they have clearly demarcated global phases. Perl doesn't. – Dummy00001 Sep 02 '10 at 00:28
  • 3
    I'm starting to understand your problem. You're reading random stuff on the internet instead of the documentation. It's easy to get confused doing that. – brian d foy Sep 02 '10 at 00:54
  • 2
    @Dummy Python has `eval`. We fully acknowledge that the compilation and runtime phases can call each other, but they are still distinct. I'm not sure what you're arguing. Anyhow, perlcc can handle `eval`. It only cuts out the first-pass compilation step. This is also why it was dropped, there's a small startup benefit but no runtime. Perl ops are already written in C, and a lot of what perlcc does is call ops. B::CC attempts to do optimizations, but it never got far. Its still being worked on as an independent project. http://search.cpan.org/dist/B-C – Schwern Sep 02 '10 at 01:34
  • 2
    @briandfoy I think you should update your answer to no longer say it’s dead. It’s very well maintained, actually. I’m fixing the book similarly. – tchrist Apr 01 '12 at 18:59
  • @briandfoy I think you should update your answer to no longer say it’s dead. It’s used commercially and very well maintained. – rurban Dec 05 '13 at 17:59
  • @rurban: maybe you can update my answer :) I trust what you'd do. – brian d foy Dec 06 '13 at 11:49
7

I'm sure you are referring to the B::C suite with perlcc which came with perl until 5.8.9. Since then I took over the development of the perl compiler which was not enhanced since 1997, and fixed most of the remaining bugs.

Why does perl have separate compiler and frontend?

First of all (for the others): perl is the only official frontend for perl, the interpreter.

perlcc is the frontend for the compilers B::C, B::Bytecode (-B) and B::CC (-O), the C linker part is in cc_harness also.

Nobody really wants to mess with the various options for the backends. Using perlcc is much easier. Like gcc as driver for all the backends and intermediate steps. gcc has for all intermediate steps also different executables: cc1, cc1plus, collect, as, ld

Do you want to call cc1 by your own? I never saw this.

Does this answer your question sufficiently?

BTW, basically all answers before were complelety wrong and nobody answered Lazer's question directly.

@briandfoy: perlcc is not a dead tool, it is in steady development, and it is used in production code. Startup times are dramatically faster. You can ship single executables. 90% of normal perl works. You could also use .pmc (as python does), but only huge sites do that. I recommend to use the version from CPAN.

perlcc basically creates a dump at CHECK time, and executes the dump then. So there are semantical differences to perl packers (PAR, perl2exe, perlapp), which create dumps and execute them before BEGIN. See perlcompile.pod from B::C on CPAN.

@mkb: perlcc support did not languish. p5p was just not capable enough to fix the remaining bugs. So I did. See http://search.cpan.org/dist/B-C/.

@Chas: Of course does perl5 compile down to some sort of "bytecode", the optree. The B::Bytecode compiler can be used to dump this, and the ByteLoader is used to run it. There also MAD which dumps to XML. And there's -u which dumps to a binary representation. Which can be used to undump to an exe. Just a simple linker-like step is necessary, for which I had no time yet.

@Novikov: Perl compiles to bytecode, and then runs this. As most scripting languages do. Perl has perlcc so you compile it to native executables.

@zigdon: You mixed that up with packagers, like perl2exe and PAR.

Maybe we have that mess because of the still wrong entry of the perl compiler in the FAQ.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
rurban
  • 4,025
  • 24
  • 27
1

Correction: It was a separate front-end. perl is not really a compiler to bytecode. The ultimate form of 'compiled' Perl is a set of abstract syntax trees that are then used by an interpreter. Perlcc support languished because the language changed fast enough that it never kept up. The problems it solved are mostly solvable in other ways that don't require constant maintenance of a separate source tree.

Matt K
  • 13,370
  • 2
  • 32
  • 51
  • 5
    What the E2 article totally neglects to mention, and what you seem not to be aware of, is that perlcc is now part of the [`B::C` distribution on CPAN](http://search.cpan.org/dist/B-C/) which is actively maintained. All those negative words "downfall" and "languished" give a false impression. – daxim Sep 01 '10 at 20:19
  • Well, don't also gloss over the docs that say "The code generated in this way is not guaranteed to work. The whole codegen suite (perlcc included) should be considered very experimental. Use for production purposes is strongly discouraged." – brian d foy Sep 01 '10 at 20:26
  • 1
    The test results for B::C don't look promising. – Matt K Sep 01 '10 at 20:32
  • (although I will add that to my E2 article) – Matt K Sep 01 '10 at 20:34
  • > The test results for B::C don't look promising. Sure, but the official compiler tests were much less promising. There was just no testsuite before. – rurban Apr 15 '11 at 13:03
-1

Because Perl 5 doesn't compile down to bytecode. Perl 6, on the other hand, can be compiled down to bytecode that runs on the Parrot virtual machine.

Chas. Owens
  • 64,182
  • 22
  • 135
  • 226
  • Well, Perl 5 doesn't compile down to a result that you can save and reuse in another run. – brian d foy Sep 01 '10 at 20:30
  • Yes, that is better way of saying it. – Chas. Owens Sep 01 '10 at 22:08
  • 1
    Perl5 does compile down to bytecode. Both -u (undump) dumps and B::Bytecode bytecode .plc can be saved and reused for a later run. To dump a running process you can try Devel::CoreDump from CPAN or may need to write a save_image using the code from undump. – rurban Apr 15 '11 at 13:09
-2

Perl programs aren't compiled as C programs are, they are parsed at runtime. All perlcc does is try to bundle up the perl executable and any libraries your program needs into one binary. At runtime, the script will still be interpreted, not run from the binary data.

zigdon
  • 14,573
  • 6
  • 35
  • 54
  • Well, "runtime" meaning when you decide to run it. Perl compiles all the source then runs the bytecode it produces, unlike some things that read a line, run it, read another line, and so on. People tend to get this confused so I find you have to be really, really careful with "interpreted". – brian d foy Sep 01 '10 at 20:20
  • perlcc doesn't make a perl interpreter and I don't think it linked against libperl either, although I may be mistaken on the latter. Maybe you're thinking of PAR files and PAR::Packer? – Matt K Sep 01 '10 at 20:31
-4

Perl is an interpreted language, C/C++ aren't.

Novikov
  • 4,399
  • 3
  • 28
  • 36
  • 3
    "Interpreted" in the sense that Java, Ruby, et al are interpreted, but not in the sense that shell scripts or BASIC is interpreted. It's a loaded term that people tend to take the wrong meaning from. :( – brian d foy Sep 01 '10 at 20:22