Raskas asked me a question about the creation off a binary Perl script.
The goal of this was to run a Perl script on a machine where Perl is not installed.
perlcc should be our friend… but some dependencies were still giving troubles, so I tried to find another solution, here is a summary of my small research :
first, the Perl script’s source (Copyright fred… but in GPL !) :
root@matisse test# cat fred.pl #!/bin/perl printf("hello world\n");
So the first try with perlcc :
root@matisse test# perlcc -o fred1 fred.pl pccPvjBI.c: In function ‘perl_init_aaaa’: pccPvjBI.c:444: warning: this decimal constant is unsigned only in ISO C90 root@matisse test# ls -l fred1 -rwxr-xr-x 1 root root 47855 Nov 29 08:42 fred1 root@matisse test# file fred1 fred1: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped root@matisse test# ldd fred1 linux-gate.so.1 => (0x006aa000) libperl.so => /usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libperl.so (0x00101000) libresolv.so.2 => /lib/libresolv.so.2 (0x00c67000) libnsl.so.1 => /lib/libnsl.so.1 (0x0314b000) libdl.so.2 => /lib/libdl.so.2 (0x00a3e000) libm.so.6 => /lib/libm.so.6 (0x00a44000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x00aef000) libutil.so.1 => /lib/libutil.so.1 (0x0047a000) libpthread.so.0 => /lib/libpthread.so.0 (0x00a15000) libc.so.6 => /lib/libc.so.6 (0x00702000) /lib/ld-linux.so.2 (0x008b5000)
First problem is that libperl.so should be then copied into the destination machine.
Second try then with -static option of perlcc :
root@matisse test# perlcc -static -o fred2 fred.pl pccB0xON.c: In function ‘perl_init_aaaa’: pccB0xON.c:444: warning: this decimal constant is unsigned only in ISO C90 root@matisse test# ls -l fred2 -rwxr-xr-x 1 root root 47855 Nov 29 08:46 fred2 root@matisse test# ldd fred2 linux-gate.so.1 => (0x00cf1000) libperl.so => /usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libperl.so (0x00101000) libresolv.so.2 => /lib/libresolv.so.2 (0x00c67000) libnsl.so.1 => /lib/libnsl.so.1 (0x0314b000) libdl.so.2 => /lib/libdl.so.2 (0x00a3e000) libm.so.6 => /lib/libm.so.6 (0x00a44000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x00aef000) libutil.so.1 => /lib/libutil.so.1 (0x0047a000) libpthread.so.0 => /lib/libpthread.so.0 (0x00a15000) libc.so.6 => /lib/libc.so.6 (0x00702000) /lib/ld-linux.so.2 (0x008b5000)
Same size, same dependencies… nothing changes even if the files differ :
root@matisse test# diff fred2 fred1 Binary files fred2 and fred1 differ
My third try was then with the -B option (Compiles using the bytecode backend) :
root@matisse test# perlcc -B -o fred3 fred.pl root@matisse test# ls -l fred3 -rwxr-xr-x 1 root root 328 Nov 29 08:50 fred3 root@matisse test# ldd fred3 not a dynamic executable
Woohoooo nice…. !!! Don’t be so happy… it requires Perl :
root@matisse test# file fred3 fred3: perl script text executable
Indeed :
root@matisse test# head -n 1 fred3 #! /usr/bin/perl
So, once again it’s not the good solution !
My last try then was using Perl Packager (pp) from PAR, installed via CPAN:
root@matisse test# pp -o fred4 fred.pl root@matisse test# ls -l fred4 -rwxr-xr-x 1 root root 1880375 Nov 29 08:54 fred4 root@matisse test# file fred4 fred4: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped root@matisse test# ldd fred4 linux-gate.so.1 => (0x00ef2000) libresolv.so.2 => /lib/libresolv.so.2 (0x00c67000) libnsl.so.1 => /lib/libnsl.so.1 (0x0314b000) libdl.so.2 => /lib/libdl.so.2 (0x00a3e000) libm.so.6 => /lib/libm.so.6 (0x00a44000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x00aef000) libutil.so.1 => /lib/libutil.so.1 (0x0047a000) libpthread.so.0 => /lib/libpthread.so.0 (0x00a15000) libc.so.6 => /lib/libc.so.6 (0x00702000) /lib/ld-linux.so.2 (0x008b5000) root@matisse test# ./fred4 hello world
Conclusion: in this case pp is the solution to have a binary that could run on a system without Perl.