Perlbrew

From HalfgeekKB
Jump to navigation Jump to search

perlbrew is a manager for sudo-free, user-level perl installations.

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.
  • -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 or blead.
    • 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.
  • 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.)