Perlbrew
perlbrew is a manager for sudo-free, user-level perl installations.
Contents
Hope you're patient
Some of these steps take a very long time and, unless you're lucky, more than one attempt.
Installation
Directly
cd ~/tmp
wget --no-check-certificate https://raw.github.com/gugod/App-perlbrew/master/perlbrew
perl perlbrew self-install
The install will suggest that you source something from your shell startup, which may vary depending on your current shell. Follow the instructions given and restart your shell.
# Two possibilities
echo 'source ~/perl5/perlbrew/etc/bashrc' >> ~/.bash_profile
echo 'source ~/perl5/perlbrew/etc/bashrc' >> ~/.bashrc
At this point, you should continue to Accessories below, but the commands failed for me because of a certificate issue. This issue can be worked around by patching perlbrew to skip SSL cert checks in wget and curl modes (and not have fetch installed).
perl -i -p -E 's/(--silent --location)/-k $1/g; s/(--quiet -O)/--no-check-certificate $1/g' ~/perl5/perlbrew/bin/perlbrew
CPAN
Note: I couldn't get this working on dreamhost; there were tests that failed.
The CPAN install is more involved, but it is also not minified, which should make any necessary debugging easier.
Install using the CPAN for the system's main perl, not one of the perlbrew perls.
perlbrew off # If perlbrew is already installed, disable it
cpan App::perlbrew
Accessories
Install patchperl and cpanm.
perlbrew install-patchperl
perlbrew install-cpanm
Add a new perl install
Do this in a screen
session. It is a long-running process that you won't want interrupted by connectivity problems.
perlbrew install -D useshrplib -D usesitecustomize --as $your_install_name stable
- The
--as
switch is optional. Omitting it causes the version to be used instead of a name when managing. -D useshrplib
enables compiling perl in terms of a shared library, libperl.so. Optional, but don't omit it without a good reason.- Other
-D
,-U
,-A
defines are passed the same way. --thread
,--multi
can also be passed here.
- Other
-D usesitecustomize
enables having this perl automatically run a pre-script,$Config{siteperl}/sitecustomize.pl
, before nearly anything else. See -f in perlrun.--sitecustomize filename
does this and will also install the given file as sitecustomize.pl.
- The
stable
specifier may be replaced with any version number orblead
.- It can also be replaced with the fully qualified path or URL of a .tar.gz (or .tar.bz2, etc.) archive of a Perl distribution. If the archive is in the current directory, use e.g.
"`pwd`"/perl-x.x.x.tar.gz
rather than./perl-x.x.x.tar.gz
; otherwise, it won't be recognized. - It can also be replaced with the path to a git checkout of the perl code.
- It can also be replaced with the fully qualified path or URL of a .tar.gz (or .tar.bz2, etc.) archive of a Perl distribution. If the archive is in the current directory, use e.g.
- Other options are available.
This is a full perl install process and will take a substantial about of time. You will be given a tail -f
command to follow the log if desired.
I believe it is supposed to work to install the same version twice as long as the names are different. However, there can be only one build directory per version, so don't try to perform the actual installs simultaneously; wait for one to finish before starting the next.
Making the install INSTALL_BASE-friendly (or: extra @INC paths)
When using the INSTALL_BASE parameter on perl module installation (in particular, for modules installed outside cpan such as the Image::Magick example), the installer wants to install stuff in, among other paths,
$INSTALL_BASE/lib/perl5 $INSTALL_BASE/lib/perl5/architecture
Unfortunately, these aren't in the default @INC because the simplified install dirs scheme is used (see INSTALL, Installation Directories, scan for "slightly simplified").
Symlink to a directory already in @INC
If the perl has already been compiled, it should work to use a symlink from the current version number to perl5
before trying to install anything:
cd ~/perl5/perlbrew/perls/installname/lib
ln -s site_perl/5.*.* perl5
# or ln -s 5.*.* perl5
This approach seems sane and simple enough that it's probably the one I'm going to use.
Add to @INC using site customization
If the perl was compiled with usesitecustomize
, @INC manipulations can be made directly to lib/site_perl/sitecustomize.pl.
The potential utility of something like this warrants always compiling with this option.
Add to @INC when compiling
If the perl hasn't been compiled yet, you might consider a compile-time mechanism like -Dotherlibdirs
to add paths to @INC.
Remove an install
perlbrew uninstall $your_install_name
Simple.
Using on Cygwin
Tricky, and so far I haven't succeeded. Points to note:
Version
5.18.2
PATH
Before attempting to build, ensure PATH contains no spaces or parentheses in order to prevent a shell syntax problem. On Cygwin, this appears to generally mean cutting out all components containing "cygdrive".
cd to build dir
On the first failure, cd into the path perlbrew says to use for installing without tests.
Fix for nostdio.h hack
The only actual build issue is given as a syntax issue at nostdio.h. nostdio.h is a set of hacks designed to prevent subsequent includes of stdio.h by making all usages thereof errors.
One of the hacks used around line 25 causes some choking:
#define FILE struct _FILE
It is mentioned elsewhere that defining PERLIO_NOT_STDIO
to 0 in cygwin.h near the beginning temporarily disables the hack in one problematic place.
#define PERLIO_NOT_STDIO 0
Continue build
Do make
here. The build should succeed.
Do make test
if you like. Some test problems are apparently unavoidable.
Fixes for build failures
cwd.t linktest
When building 5.18.2, I got this failure:
# Failed test at t/cwd.t line 209.
# '/home/username/perl5/perlbrew/build/perl-5.18.2/dist/Cwd/t/linktest'
# doesn't match '(?^i:\/home\/username\/perl5\/perlbrew\/build\/perl\-5\.18\.2\/dist\/Cwd\/t\/_ptrslt_\/_path_\/_to_\/_a_\/_dir_$)'
A corresponding error reported by someone else said that this manual hack on Cwd.pm got the issue out of the way without forcing the install. Here's my version:
Unpack the perl archive into a temp dir, make the correction, repack it, and install it.
tar xjvf ~/perl5/perlbrew/dists/perl-5.18.2.tar.bz2
vim perl-5.18.2/dist/Cwd/Cwd.pm # and make the edit
tar czvf perl-5.18.2.tar.gz
perlbrew install --as $somename "`pwd`"/perl-5.18.2.tar.gz
The correction is thus (the ADD line):
# Line 579:
unless (opendir(PARENT, $dotdots))
{
# probably a permissions issue. Try the native command.
require File::Spec;
$start = readlink($start) if -l $start; # ADD this line to resolve a symlink
return File::Spec->rel2abs( $start, _backtick_pwd() );
}
This fix seems to have worked.
Image::Magick
One process that is claimed to work for installing Image::Magick is given on perltricks.com.
The given process has a new IM library installed under ~/local. I've changed it to ~/opt/ImageMagick-VERSION-NAME to make it possible to install a different instance per perl install. I've also specified a font path.
IM=ImageMagick-6.8.9-0
IM_DOWNLOADS="http://www.imagemagick.org/download"
OPT="$HOME/opt"
FONT_PATH="$HOME/.fonts"
PB_NAME="perlbrew install name"
PB_DIR="$PERLBREW_ROOT/perls/$PB_NAME"
PB_PERL="$PB_DIR/bin/perl"
PB_CORE="`echo "$PB_DIR"/lib/5.*.*/*/CORE`"
PREFIX="$OPT/$IM-$PB_NAME"
WITHOUT_THREADS=`"$PB_PERL" -MConfig -E '$Config{useithreads} or say "--without-threads"'`
ENABLE_SHARED=`"$PB_PERL" -MConfig -E '$Config{useshrplib} eq "true" and say "--enable-shared"'`
unset PERL5LIB
echo Current PERL5LIB: "$PERL5LIB"
CONFIGURE="LDFLAGS=-L'$PB_CORE' \
./configure $WITHOUT_THREADS $ENABLE_SHARED \
--prefix '$PREFIX' \
--with-perl='$PB_PERL' \
--with-perl-options=INSTALL_BASE='$PB_DIR' \
--with-fontpath='$FONT_PATH' \
--with-rsvg"
echo Our configure command looks like:
echo "$CONFIGURE"
read -p "Press enter if this looks right." &&
wget "$IM_DOWNLOADS/$IM.tar.xz" &&
tar xJvf "$IM.tar.xz" &&
cd "$IM" &&
eval "$CONFIGURE" &&
read -p "Press enter to make and install." &&
make install
If retrying any step after the configure without rerunning the script, at least make sure PERL5LIB is unset. Otherwise, the install will attempt to bring in perl stuff from the system perl, and dumb errors like undefined symbol: Perl_Istack_sp_ptr
will ruin your day.
To verify the install, the article suggests running the perl and requesting a way-too-high version of the module Image::Magick::Q16 (at least, as of this version if IM, that's where the version information actually is).
$ ~/perl5/perlbrew/perls/installname/bin/perl -MImage::Magick::Q16\ 999 Image::Magick::Q16 version 999 required--this is only version 6.89. BEGIN failed--compilation aborted.
If the error is about the version and not about the module seeming installed, you're good.
LWP::Protocol::https
No special treatment needed, but see #Net::SSLeay if you need to use a non-system OpenSSL build.
Net::SSLeay
The shared hosting provider may have omitted the OpenSSL dev headers from the system, requiring you to build your own OpenSSL. When this happens, Net::SSLeay won't install properly unless you specify the path as OPENSSL_PREFIX
.
Note that this refers to the same dir as the PREFIX
from the OpenSSL install. (For example, the file $OPENSSL_PREFIX/include/openssl/x509.h
should exist.)
# I installed OpenSSL to its own subdir of ~/opt
OPENSSL_PREFIX=/home/someuser/opt/openssl-1.0.1k cpanm Net::SSLeay
(This problem isn't specific to perlbrew, but the system perl usually already has a working Net::SSLeay.)