简体   繁体   中英

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: 在此处输入图像描述 and在此处输入图像描述

@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

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)).

perlbrew does two things:

  • Makes installing Perl a little bit easier.
  • Manipulate the PATH of a shell that loads it.

The CGI script isn't launched by a shell.


First, you shouldn't be using PERL5LIB . Why install a custom perl using perlbrew and then try to cause it to use modules installed by another perl ? This is nothing but bad. Unset PERL5LIB .

And with PERL5LIB unset, you shouldn't be using PERL_MB_OPT and PERL_MM_OPT either. You need to let the modules get installed where perl will find them.

So start by cleaning out the mess. Make sure PERL5LIB , PERL_MB_OPT and PERL_MM_OPT aren't set anywhere. You may to need reinstall the modules if they were installed in a weird place.

Now, using the correct perl will load the modules installed by that perl .


So what left is ensuring that we're using the correct perl . You use /usr/bin/env to locate perl . Does it makes sense for Apache's PATH to control which perl your application uses? Probably not.

What I would do is create an alias in perlbrew for your project.

perlbrew alias create perl-5.22.4@somename myproject

Then use the following shebang line:

#!/home/username/perl5/perlbrew/perls/myproject/bin/perl

That will allow you use to control which build of perl your project uses using

perlbrew alias create -f ... myproject

This works using symlinks, not PATH manipulation, so it works from anywhere, not just shells using perlbrew .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM