Skip to content


Fully statically linked Perl – Single executable with all modules, modules fully statically linked also (bundle Crypt::OpenSSL::AES)

Recently I had to figure out how to distribute a single Perl that includes Crypt::OpenSSL::AES module that works across multiple Linux distributions and architectures. There are several problems:

  • Perl has dependencies on shared libraries that may not exist on all systems. This is not by itself a huge problem because you can build a single 32 Bit Perl that work on major distributions
  • Crypt::OpenSSL::AES is a thin wrapper for libcrypto and libssl. This means that when you install the module, it is compiled as a shared library. This is a significant problem because OpenSSL is not backward compatible, so you need all of your target machine to have the same version of libcrypto and libssl and built for the same architecture and using same or better version of libc (and other shared libraries). To see the dependencies, use ldd

Statically linking the shared library built during installation of Crypt::OpenSSL::AES against libcrypto does solve the 2nd part of the problem but not the first. It also means that you are still bounded by the libc version requirements.

After much research, I have found a way to build a fully static (alternatively static perl with dependency only on libc). The method uses App-Staticperl (http://search.cpan.org/~mlehmann/App-Staticperl-1.43/bin/staticperl). Reader should familiarize themselves with the documentation in the link first.


Installation:

  1. Download and Build OpenSSL, the build require no special configuration parameters. If you need to build OpenSSL in a local directory refer to OpenSSL’s INSTALL file for the configuration flags
  2. Patch App-Staticperl. The standard download does not work out of the box due to a script error.
    • Untar App-Staticperl
    • Copy the staticperl.sh into the untarred directory
  3. Build perl from source using staticperl by running ‘./staticperl.sh install’, this installs by default Perl 5.12.4 to ~/.staticperl
  4. Copy ./mkbundle to ~/.staticperl/bin/SP-mkbundle. This step is required to work around a script error in staticperl.sh that prevents it from generating the mkbundle script
  5. Run ./staticperl.sh mkperl, if there are any missing module errors then install the corresponding module from CPAN using ~/.staticperl/bin/perl
  6. Build and install CBC::Crypt:
    • Untar Crypt-CBC
    • CD into the new directory and issue:
    • ~/.staticperl/bin/perl Makefile.PL
      make
      make install
  7. Build and install Crypt::OpenSSL::AES. This require modification to Makefile.PL to statically link in the OpenSSL library built during step 1
    • Untar Crypt::OpenSSL::AES
    • CD into the new directory and modify the Makefile.PL
    • Comment out LIBS
      Add path to the build openssl's include dir to INC
      Add MYEXTLIB => 'POINT TO libcrypto.a FILE' # this gets directly added to the linker
    • Issue commands:
    • ~/.staticperl/bin/perl Makefile.PL
      make
      make install
  8. Build staticperl, CD into App-Staticperl and issue
  9. ./staticperl.sh mkperl --incglob '*' --static
  10. A new executable ‘perl’ should be generated in cwd, test this perl by running it against test.pl
  11. ./perl ../test.pl
    53616c7465645f5f477a787c68a095cb9ba06fb7768140a623a2670aa1c3a4f553d3e64dc16fc5707c6c9a6eac5dcf32
    1234567890123456
    41f813eca9ddd189f7ff3280ada72c8a
    1234567890123456
  12. If the above match then the new single executable perl has been generated successfully

Posted in Linux, Perl. Tagged with , , , .