P0w3rK!d has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I am currently running Perl on 11 different platforms. I need help determining the best practice for dynamically switching libraries when one runs a different version of Perl on different platforms.

My requirements are:


When I moved the code to aix, I sorted out a few library issues and went back to check my changes on solaris. Solaris blew up and stated:
perl $FOO/foo.pl -bla bla bla IO object version 1.20 does not match bootstrap parameter 1.15 at /usr +/local/lib /perl5/5.6.1//sun4-solaris/DynaLoader.pm line 225. Compilation failed in require at /.../perl/lib/Custom_mods/logfile. pm line 49. BEGIN failed--compilation aborted at /.../perl/lib/Custom_mods/logf ile.pm line 49. Compilation failed in require at /abc/123/foo.pl line 9 3. BEGIN failed--compilation aborted at /abc/123/foo.pl li ne 93.

I think the problem here is that logfile.pm is looking for the Perl 5.6.1 version of Handle.pm, which is 1.21. The aix system is running Perl 5.005_03 and I am pointing to the accompanying version of handle.pm that is 1.1505. Because of the dependencies the Perl 5.005_03 flavored system is barfing now that I am trying to run it in the 5.6.1 environment.
Here are the versions of the IO modules that I am running:
Here are the Perl 5.005_03 versions of the IO modules that I am running:
Module		Version
File.pm		1.06021
Handle.pm	1.1505
Pipe		1.0902
Seekable	1.06
Select		1.10
Socket		1.1603

I have both flavors of the IO modules. The question is, how do I dynamically switch between them? I need to get everything running under 5.005_03, but if I can just switch it for solaris and windows I am golden (at least for the short term). What is the best practice to do this w/ or w/o the use of a BEGIN statement?
My Perl env on solaris is as follows:
PERL_HOME=/usr/local/bin
PERL=/usr/local/bin/perl
PERL5LIB=/usr/local/lib/perl5/5.6.1/:/foo/custom/perl/lib
and on aix:
PERL=/bin/perl
PERL5LIB=/usr/opt/perl5/lib/5.00503:/foo/custom/perl/lib
PERL_HOME=/bin

Thanks in advance for your help :)

-P0w3rK!d

P.S. I have no idea why I am seeing this:

/usr/local/lib/perl5/5.6.1//sun4-solaris/DynaLoader.pm

There appear to be no libraries on the solaris box I am using other than for Perl 5.6.1. There is a Perl executable of version 5.00404. This probably is not related, but I want to make sure.

Edit re IO mod's at author's req. - dvergin 2003-04-15

Replies are listed 'Best First'.
Re: How to handle Cross-platform Perl, modules, and versioning
by Abigail-II (Bishop) on Apr 15, 2003 at 20:49 UTC
    I'm not sure what the question is that you are asking. I understand that on different platforms, you have different versions of Perl. But I don't see the connection with the different directories. Assuming the various versions of Perl weren't configured by monkeys typing random characters, Perl knows where it can find its standard libraries/modules, and where the default site_perl directory is. If for some reason you have installed modules outside of the configured directories, you should put those directories in PERL5LIB; you'd have a separate PERL5LIB for each system.

    There's no need to have any directory dependency in your program.

    But I guess I don't fully understand your problem. Could you show some code that's failing, and indicate where it's failing?

    Abigail

      Abigail,

      >>Assuming the various versions of Perl weren't configured by monkeys typing random characters, Unfortunately, that's the way it's been for all of my clients. :)

      Also, I need to have a central repository for the custom libraries. It's not a good idea to take on the maintenance of updating code on 11 platforms if you do not have to.

      My system was initially setup for a hybrid environment of 5.005_03 and 5.6.1. I have to reference some custom libraries that were written for 5.005_03. Furthermore, I have to backup to make sure my system fully supports 5.005_03 on all 11 platforms.

      Note: The system is centrally located, so any changes on the UNIX/Linux side of the house will affect all of those platforms.

      After making changes on aix due to referencing higher versions IO 5.6.1 library problems, my system started working correctly on Perl 5.005_03. Solaris is still running Perl 5.6.1. That is all it has installed. Other than the old Perl executable I previously mentioned.

      So,when I tried running the same code on Solaris, it barfed because of the Perl 5.6.1 system is expecting Perl 5.6.1 versions of IO to be in PERL5LIB. Perl is in many different locations on the various UNIX/Linux platforms, but in the same place for the 5 Windows + Netware platforms.

      One question is can I have Perl switch on the libraries on the fly with a BEGIN statement? Something like:

      use Config; $PLATFORM = $Config{'osname'}; if (($PLATFORM =~ /^MSWin32/i) || ($PLATFORM =~ /^solaris/i)) { # use Perl 5.6.1 libraries BEGIN { @PERL_SHARE = ( "/foo/custom/perl/lib/Custom_mods5.6.1", ); unshift(@INC, @PERL_SHARE); }; } else { # use Perl 5.005_03 libraries BEGIN { @PERL_SHARE = ( "/foo/custom/perl/lib/Custom_mods5.005_03", ); unshift(@INC, @PERL_SHARE); }; }

      Does this make more sense? The question is, what would the best practice be??

      -P0w3rK!d

        That won't work as-is because both BEGIN{} blocks will be executed before the if statement is even compiled.

        If performance or memory is a consideration, unless you are using %Config for other things as well, you would be better off using $^O to test for the OS. It contain sthe same info as $Config{'osname'} but without the overhead of loading Config.pm.

        Also, why are you putting a single scalar into an array and then unshifting the array?

        This ought to come pretty close to what you are trying to do I think. (NB:untested)

        BEGIN{ # UPDATE: Corrected typo pointed out my [Abigail-II] below. unshift @INC, $^O =~ m[^(?:MSWin32|solaris)$]i ? '/foo/custom/perl/lib/Custom_mods5.6.1' : '/foo/custom/perl/lib/Custom_mods5.005_03'; }

        Though that is probably better coded as

        (Also partially untested)

        BEGIN{ use lib $^O =~ m[^(?:MSWin32|solaris)$]i ? '/foo/custom/perl/lib/Custom_mods5.6.1' : '/foo/custom/perl/lib/Custom_mods5.005_'; }

        Examine what is said, not who speaks.
        1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
        2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
        3) Any sufficiently advanced technology is indistinguishable from magic.
        Arthur C. Clarke.
        Also, I need to have a central repository for the custom libraries.

        Sure, but only custom libraries should be there. There should not, for example, be copies of core modules in there. That would create headaches.

        I have to reference some custom libraries that were written for 5.005_03

        If the custom libraries will also run under more recent versions, I don't see the problem. If they won't, then of course they have to be fixed so that they will.

        So,when I tried running the same code on Solaris, it barfed because of the Perl 5.6.1 system is expecting Perl 5.6.1 versions of IO to be in PERL5LIB

        Yes, that's what it should expect. If that system has 5.6.1, then its PERL5LIB should be the one for 5.6.1 also. That's basic consistency. If you are changing PERL5LIB to point to a central directory, then all the systems using that directory need to have the same version of Perl. Otherwise, if they have different versions of Perl, they must also have different versions of PERL5LIB.

        what would the best practice be?

        The best practice would be to write your code so that it doesn't matter which version of Perl it runs under, simply by not relying on version-specific hacks.

        I still don't understand your problem with modules; for any given module you are trying to use, there are three possibilities: it will run fine under either version of Perl, it won't run at all under some versions, or a different version of it is needed depending on the Perl version. In the first (ideal) case, there should be no problem. In the second case, it should be obvious that you can't use that module. In the third case, you must install the right version of the module on each system for the version of Perl that is there.

        In no event should any of your code ever be looking for specific versions of a module. Write your code generally, without version-specific hacks, so that any (supported) version of the module will just work.

        (If the module changed its API between versions, you should either not use that module (my first inclination) or if you absolutely must use it write a wrapper module so that you don't have to use it directly; install the correct version of the wrapper module on each system for the version of the wrapped module that is there. All versions of the wrapper module should present the same API to the rest of your code.)

        Some of my assumptions may be way off base; I had a hard time following your description of your problem, but as best I understand it, it _sounds_ like the custom modules aren't really your problem, but some core modules that you (or the custom modules) use. It sounds from some parts of your explanation like some installations are getting versions of the core modules that are wrong for the version of Perl and/or for eachother. This implies that someone at your site has messed with the core modules in an inappropriate way. It's hard to be more specific without knowing more details about your setup, except to say that each installation of Perl should have its own installation of the core modules, and any custom modules that are to be shared across multiple versions of Perl must be able to work correctly with whichever versions of Perl (and thus the core modules) they happen to get.


        for(unpack("C*",'GGGG?GGGG?O__\?WccW?{GCw?Wcc{?Wcc~?Wcc{?~cc' .'W?')){$j=$_-63;++$a;for$p(0..7){$h[$p][$a]=$j%2;$j/=2}}for$ p(0..7){for$a(1..45){$_=($h[$p-1][$a])?'#':' ';print}print$/}
Re: How to handle Cross-platform Perl, modules, and versioning
by chromatic (Archbishop) on Apr 15, 2003 at 20:37 UTC

    How are you using them now that a simple use IO::Handle;, for example, does not work across platforms?

      Do you mean IO as a whole?

      This code:

      use IO::handle; use FileHandle;
      is embedded in the functions of logfile.pm, which is a custom library that I have no control over. I am trying to reference all the custom libraries in my code:
      BEGIN { @PERL_SHARE = ( "/foo/custom/perl/lib/Custom_mods", ); unshift(@INC, @PERL_SHARE); };

      logfile.pm is in the Custom_mods directory.
      -P0w3rK!d
      Also I have not checked my changes back into ClearCase yet. I'm trying to get everything synchronized with the Perl libaries first. Hence, the other non-UNIX platforms that are running my production system have not been modified.
      -P0w3rK!d
      I solved one problem. For some reason, Perl 5.6.1 on solaris has 2 versions of IO. Therefore, my PERL5LIB needs to look like this:
      PERL5LIB=/usr/local/lib/perl5/5.6.1/:/usr/local/lib/perl5/5.6.1/sun4-s +olaris:/foo/custom/perl/lib

      The version requirement was being caught because of a problem with the "newer" solaris IO::Handle being the only module to reference. And guess what... there is nothing in that directory but Socket. IO::Handle lives in the /sun4-solaris sub-directory.

      Once this fix was made, logfile.pm was able to find the correct version of IO::Handle.

      -P0w3rK!d

Re: How to handle Cross-platform Perl, modules, and versioning
by crenz (Priest) on Apr 15, 2003 at 21:32 UTC

    I'm not sure whether I fully understand your problem. I am guessing wildly that part of your problem is that you are sharing installed modules between different platforms via NFS/SMB/...?

    I am guessing that because your problems seem to be based not on features not available in a certain version, but rather your installation being a mess.

    To achieve portability on that number of platforms, I'd go the following steps:

    • On each platform, do a clean install of perl and the additional modules you need. That should make sure that core modules like e.g. IO::Handle work.
    • Depending on your code, it is probably just a few of your own modules that behave differently on different perl versions. I would prefer to do the version checking inside those modules, for better abstraction.
    • Make a bundle of your own application to facilitate deployment. Then, do a clean install on each platform.

    Update: You could try to use PAR for easier application deployment.

      There are no issues on Netware, Solaris, or any of the Windows platforms. I was able to get them installed and working cleanly. The problem is that my client does not have additional UNIX boxes so I can modify or test out my stuff. The way Perl is installed on those systems is considered "qualified" by them. In all of those cases, unfortunately, that's the way they'll stay until they are fixed.

      As for your best practice comments, I already practice what you said. Also, the libraries are shared via NFS.

      Thanks :)

      -P0w3rK!d

Re: How to handle Cross-platform Perl, modules, and versioning
by PodMaster (Abbot) on Apr 16, 2003 at 09:03 UTC
    There is a new prama on CPAN called only, and it might be of use to you. only - Load specific module versions; Install many


    MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
    I run a Win32 PPM repository for perl 5.6x+5.8x. I take requests.
    ** The Third rule of perl club is a statement of fact: pod is sexy.