mpersico
mpersico

Reputation: 833

How do I handle installing scripts in Perl modules with multiple versions of Perl?

I don't think that this is a duplicate question. This is specifically about scripts that come with Perl modules.

Typically, when installing multiple Perl versions, you can have the perl executable tagged with a version number (perl5.32) so that they can all sit side by side in /whatever/bin. I need to do the same for scripts that come with modules. Example: perltidy. So:

Is there a setting I can throw on the config when I build perl that will automagically [sic] create 'versionated' script names?

Or, is there something I can set when I call perl Makefile.PL or perl Build.PL when I am building the script to make 'versionated' script names?

Yes, there are plenv and perlbrew, but I don't want to use those on the production side, yet there will be a period of time on my production machines when both versions will exist. I will be migrating programs over time; I will not be "big-banging" a cut over to a new version one night.

Upvotes: 2

Views: 593

Answers (2)

brian d foy
brian d foy

Reputation: 132906

I wrote more about this in Make links to per-version tools.

I have about 30 perls installed, and I install each manually:

$ ./Configure -des -Dprefix=/usr/bin/perls/perl-5.x.y
$ make test install

Now there's something like /usr/bin/perls/perl-5.x.y/bin/perl and so on. If I want to install modules or scripts for that, I use that cpan:

$ /usr/bin/perls/perl-5.x.y/bin/cpan ...

When you install through the normal Perl toolchain, the shebang line to point to the perl that installed it (and see the recent Perl.com article Bang Bang for more on that):

#!/usr/local/perls/perl-5.32.0/bin/perl
    eval 'exec /usr/local/perls/perl-5.32.0/bin/perl -S $0 ${1+"$@"}'
    if $running_under_some_shell;
#!/usr/local/bin/perl

That sufficiently compartmentalizes the different programs from each other and each program knows which perl it should run.

Of course, those long paths are too much to type, so I have a program that makes symlinks in ~/bin such that ~/bin/cpan-5.x.y points into that. The same program takes any programs it finds in /usr/bin/perls/perl-5.x.y/bin and makes similar symlinks.

rhich is my own which-like program that takes a regex:

$ rhich 5.32.0 | head -4
/Users/brian/bin/perls/pod_cover5.32.0 → /usr/local/perls/perl-5.32.0/bin/pod_cover
/Users/brian/bin/perls/ppodchecker5.32.0 → /usr/local/perls/perl-5.32.0/bin/ppodchecker
/Users/brian/bin/perls/prove5.32.0 → /usr/local/perls/perl-5.32.0/bin/prove
/Users/brian/bin/perls/plackup5.32.0 → /usr/local/perls/perl-5.32.0/bin/plackup

Along with this, it makes links that use -latest instead of the version so I don't have to remember what I have:

$ rhich latest | head -5
/Users/brian/bin/latest_sha1.pl
/Users/brian/bin/perls/perl-latest → /usr/local/perls/perl-5.32.0/bin/perl
/Users/brian/bin/perls/ptar-latest → /usr/local/perls/perl-5.32.0/bin/ptar
/Users/brian/bin/perls/ttree-latest → /usr/local/perls/perl-5.30.1/bin/ttree
/Users/brian/bin/perls/dprofpp-latest → /usr/local/perls/perl-5.14.4/bin/dprofpp

And somewhere in there, I also just make the bare command name point to whatever is the latest, which is what I want most of the time:

/Users/brian/bin/perls/perl → /Users/brian/bin/perls/perl-latest

perltidy

And, here's all my perltidy installations:

$ rhich perltidy
/Users/brian/bin/perls/perltidy5.30.1 → /usr/local/perls/perl-5.30.1/bin/perltidy
/Users/brian/bin/perls/perltidy5.30.0 → /usr/local/perls/perl-5.30.0/bin/perltidy
/Users/brian/bin/perls/perltidy-latest → /usr/local/perls/perl-5.32.0/bin/perltidy
/Users/brian/bin/perls/perltidy5.28.0 → /usr/local/perls/perl-5.28.0/bin/perltidy
/Users/brian/bin/perls/perltidy5.26.1 → /usr/local/perls/perl-5.26.1/bin/perltidy
/Users/brian/bin/perls/perltidy5.30.2 → /usr/local/perls/perl-5.30.2/bin/perltidy
/Users/brian/bin/perls/perltidy5.32.0 → /usr/local/perls/perl-5.32.0/bin/perltidy
/Users/brian/bin/perls/perltidy → /Users/brian/bin/perls/perltidy-latest

Upvotes: 2

tobyink
tobyink

Reputation: 13664

Update: having re-read your question, I think I mis-read it the first time. I will include my first interpretation at the end, as it may be useful.

So as I understand it, you wish to install /usr/bin/yourapp-1.1 and then later when people upgrade, you wish to install /usr/bin/yourapp-1.2?

Firstly, this seems like a badly thought out idea. If your script relies on Your::Module, then as per normal Perl module installations, Your::Module 1.2 will replace Your::Module 1.1 on the system, so if /usr/bin/yourapp-1.1 gets run, it will be running using Your::Module 1.2. (Unless you fatpack it, I guess.)

But it certainly is possible.

Simple way is to just use File::Copy in Makefile.PL to copy the unversioned script to a new filename containing the version number, before letting MakeMaker do its thing.


Earlier Answer

If your scripts include a shebang like this:

#!perl

Then ExtUtils::MakeMaker will automatically rewrite it to point to the current version of Perl at the time the distribution is being built.

If your scripts include:

#!/usr/bin/env perl

Then it won't be rewritten, and the script will be run against whatever version of perl is found in the $PATH environment variable at runtime, which is probably not what you want.

Upvotes: 0

Related Questions