Search code examples
perlubuntuperlbrewcpanm

Perlbrew libs management


I have installed perlbrew and installed two Perls with it. Now I am trying to separate libraries for modules I install with cpanm.

I want (if possible) to switch to one Perl (within Perlbrew) (for example: 5.22.4) and once I call cpanm install Some::Module the module will be installed in the separate library, related only to this Perl.

Then, in the script, I would like to have like the example below:

#!/usr/bin/env perl

use strict;
use Some::Module;
print "Content-type:text/html\n\n";
print "Works!";

and that's it. No any other use lib 'path'; or so. I tried to use perlbrew lib create perl-5.22.4@somename and then switch to it.

Then call cpanm install Some::Module and I see the result at the location ~/.perlbrew/perl-5.22.4@somename/lib/perl5/Some/Module.pm, but when I call my script from a browser I see Error 500 and the logs say "missing module Some::Module, check @INC etc..."

What I also found that if I move the ~/.perlbrew/perl-5.22.4@somename/lib/perl5/Some/Module.pm to ~/perl5/perlbrew/perls/perl-5.22.4/lib/5.22.4/Some/Module.pm or to /home/arseniigorkin/perl5/perlbrew/perls/perl-5.22.4/lib/site_perl/5.22.4/x86_64-linux/Some/Module.pm then the script works. And Perl 5.22.4 (in our example) has its own library without need to use use lib 'path';

But, how to set up Perlbrew to switch cpanm automatically to this directory?

What I was also trying: cpanm install -l /home/arseniigorkin/perl5/perlbrew/perls/perl-5.22.4/lib/site_perl/5.22.4/x86_64-linux Some::Module to specify the target lib dir, but it creates the next tree under /home/arseniigorkin/perl5/perlbrew/perls/perl-5.22.4/lib/site_perl/5.22.4/x86_64-linux instead:

  • lib
    • perl5
      • Some
        • Module.pm
      • x86_64-linux
        • auto
          • [.....]
        • .meta
          • [.....]
        • perllocal.pod
      • install.pm
  • man
    • man3
      • [.....]

and, sadly, the script throws Error 500.

So, is there a possibility to omit use lib 'path'; in the script, switching between multiple Perl versions in Perlbrew?

This all happens on Ubuntu 22.04.

Update:

When switching to perl-5.22.4@somename and installing Some::Module via cpanm the module appears under the ~/.perlbrew/perl-5.22.4@somename/lib/perl5/Some/Module.pm as mentioned above, but the CGI script fails with Error 500.

However, when I execute the next command: perlbrew list-modules it shows Some::Module as installed under the current Perl (which I am switched to). So, this is a dissonance: Perlbrew "sees" the module under the specific Perl, but the CGI script cannot "see" this module under the same Perl.

Update 2:

here is the output of the perlbrew info:

Current perl:
  Name: perl-5.22.4@somename
  Path: /home/username/perl5/perlbrew/perls/perl-5.22.4/bin/perl
  Config: -de -Dprefix=/home/username/perl5/perlbrew/perls/perl-5.22.4 -Dusesitecustomize -Aeval:scriptdir=/home/username/perl5/perlbrew/perls/perl-5.22.4/bin
  Compiled at: Nov 10 2022 23:26:53

perlbrew:
  version: 0.96
  ENV:
    PERLBREW_ROOT: /home/username/perl5/perlbrew
    PERLBREW_HOME: /home/username/.perlbrew
    PERLBREW_PATH: /home/username/.perlbrew/libs/perl-5.22.4@somename/bin:/home/username/perl5/perlbrew/bin:/home/arseniigorkin/perl5/perlbrew/perls/perl-5.22.4/bin
    PERLBREW_MANPATH: /home/username/.perlbrew/libs/perl-5.22.4@somename/man:/home/username/perl5/perlbrew/perls/perl-5.22.4/man

Update 3:

The dirs permissions for the libs: enter image description here and enter image description here

@terry0its is the name of the library (in the example I called it @somename.

Update 4:

Printing vars:

  • PERL_MB_OPT
  • PERL_MM_OPT
  • PERL5LIB
  • PATH
  • PERL_LOCAL_LIB_ROOT

with the script:

#!/usr/bin/env perl

print "Content-type:text/html\n\n";
print <<HTML;
Vars:<br>
PERL_MB_OPT = @{[$ENV{"PERL_MB_OPT"}]}<br>
PERL_MM_OPT = @{[$ENV{"PERL_MM_OPT"}]}<br>
PERL5LIB = @{[$ENV{"PERL5LIB"}]}<br>
PATH = @{[$ENV{"PATH"}]}<br>
PERL_LOCAL_LIB_ROOT = @{[$ENV{"PERL_LOCAL_LIB_ROOT"}]}<br>
HTML
  1. In the web browser:

Vars:

PERL_MB_OPT =

PERL_MM_OPT =

PERL5LIB =

PATH = /home/username/.perlbrew/libs/perl-5.22.4@terry0its/bin:/home/username/perl5/perlbrew/bin:/home/username/perl5/perlbrew/perls/perl-5.22.4/bin:/root/Komodo IDE/bin:/home/username/anaconda3/condabin:/root/Komodo IDE/bin:/home/username/pycharm/bin:/home/username/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/username/.local/share/JetBrains/Toolbox/scripts

PERL_LOCAL_LIB_ROOT =

  1. With the terminal:

Content-type:text/html

Vars:

PERL_MB_OPT = --install_base /home/username/.perlbrew/libs/perl-5.22.4@terry0its

PERL_MM_OPT = INSTALL_BASE=/home/username/.perlbrew/libs/perl-5.22.4@terry0its

PERL5LIB = /home/username/.perlbrew/libs/perl-5.22.4@terry0its/lib/perl5

PATH = /home/username/.perlbrew/libs/perl-5.22.4@terry0its/bin:/home/username/perl5/perlbrew/bin:/home/username/perl5/perlbrew/perls/perl-5.22.4/bin:/root/Komodo IDE/bin:/home/username/anaconda3/condabin:/root/Komodo IDE/bin:/home/username/pycharm/bin:/home/username/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/username/.local/share/JetBrains/Toolbox/scripts

PERL_LOCAL_LIB_ROOT = /home/username/.perlbrew/libs/perl-5.22.4@terry0its

Update 5:

When I switch to a pure perl-5.22.4 (without external lib, like @terry0its) I see the next output for the same scripts (after the restart of the server):

  1. In the web browser:

Vars:

PERL_MB_OPT =

PERL_MM_OPT =

PERL5LIB =

PATH = /home/username/anaconda3/condabin:/home/username/perl5/perlbrew/bin:/home/username/perl5/perlbrew/perls/perl-5.22.4/bin:/root/Komodo IDE/bin:/home/arseniigorkin/perl5/bin:/home/username/pycharm/bin:/home/username/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/username/.local/share/JetBrains/Toolbox/scripts

PERL_LOCAL_LIB_ROOT =

  1. With the terminal:

Content-type:text/html

Vars:

PERL_MB_OPT --install_base "/home/username/perl5"

PERL_MM_OPT = INSTALL_BASE=/home/username/perl5

PERL5LIB =

PATH = /home/username/anaconda3/condabin:/home/username/perl5/perlbrew/bin:/home/username/perl5/perlbrew/perls/perl-5.22.4/bin:/root/Komodo IDE/bin:/home/username/perl5/bin:/home/username/pycharm/bin:/home/username/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/username/.local/share/JetBrains/Toolbox/scripts

PERL_LOCAL_LIB_ROOT = /home/username/perl5


Solution

  • The issue was related to Apache2 server-specific behavior with ENV variables.

    It strips off some environment variables so they are undefined in your CGI scripts.

    To have them in the CGI script you simply have to add PassEnv PERL5LIB into your host conf file and restart the server. Then, voila - you have PERL5LIB showing correctly in the output of $ENV{PERL5LIB} all across your site.

    The example code:

    <Directory "/home/user/someproject/server/www/public_html/cgi-bin">
        AllowOverride All
        Options None
        Require all granted
        Options +ExecCGI
        PassEnv PERL5LIB
        AddHandler cgi-script .cgi .pl
    </Directory>
    

    So, to use Perlbrew and easily switching between Perls and to have automatically handling all your libs (incl. externally created with perlbrew create lib somename) you have to PASS the PERl5LIB environment to your CGI scripts explicitly in the Apache configuration file for your host.

    Do not forget to check if your mod_env is enabled in the httpd.conf (main Apache configuration file) as LoadModule env_module modules/mod_env.so (it must be uncommented).

    I hope it will help others to handle easily their Perl libraries of perlbrew with Apache2 server.

    Also, the module mod_env allows us to add custom environment variables, that we will be able to use all across the host or a server (it depends on where you put it in - inside the main conf file, your host file, or just into .htaccess for a particular dir(s) or even page(s)).