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/htmlnn";
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
- auto
- install.pm
- Some
- perl5
- man
- man3
- […..]
- 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/htmlnn";
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
- 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
=
- 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):
- 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
=
- 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
2
Answers
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 havePERL5LIB
showing correctly in the output of$ENV{PERL5LIB}
all across your site.The example code:
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 thePERl5LIB
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:The CGI script isn’t launched by a shell.
First, you shouldn’t be using
PERL5LIB
. Why install a customperl
usingperlbrew
and then try to cause it to use modules installed by anotherperl
? This is nothing but bad. UnsetPERL5LIB
.And with
PERL5LIB
unset, you shouldn’t be usingPERL_MB_OPT
andPERL_MM_OPT
either. You need to let the modules get installed whereperl
will find them.So start by cleaning out the mess. Make sure
PERL5LIB
,PERL_MB_OPT
andPERL_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 thatperl
.So what left is ensuring that we’re using the correct
perl
. You use/usr/bin/env
to locateperl
. Does it makes sense for Apache’s PATH to control whichperl
your application uses? Probably not.What I would do is create an alias in perlbrew for your project.
Then use the following shebang line:
That will allow you use to control which build of
perl
your project uses usingThis works using symlinks, not PATH manipulation, so it works from anywhere, not just shells using
perlbrew
.