http://qs1969.pair.com?node_id=11147070

syphilis has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I have an "architectured" perl installation where, in addition to perl/site/lib, I also have:
perl/site/lib/MSWin32-x64-multi-thread perl/site/lib/MSWin32-x64-multi-thread-ld perl/site/lib/MSWin32-x64-multi-thread-quadmath perl/site/lib/MSWin32-x86-multi-thread perl/site/lib/MSWin32-x86-multi-thread-64int perl/site/lib/MSWin32-x86-multi-thread-64int-ld perl/site/lib/MSWin32-x86-multi-thread-64int-quadmath perl/site/lib/MSWin32-x86-multi-thread-ld perl/site/lib/MSWin32-x86-multi-thread-quadmath
Pure-perl modules will, by default, be installed into perl/site/lib.
Other modules (ie perl extensions) will be installed into the appropriate location listed above, according to the perl architecture for which they have been built.

I have a perl extension called (say) Module::B, and it has been built and installed into each of those architecture-specific locations.
There also exists a pure-perl Module::A, which requires Module::B but has not yet been installed anywhere into that perl.

Using (say) the MSWin32-x64-multi-thread build of perl, I then install Module::A in the usual way (cpan -i Module::A).
Module::A gets installed into perl/site/lib because it is a pure-perl module.
At that point, Module::A becomes immediately available to all 9 architectures, even though it has not been tested against 8 of them.

This is an unsatisfactory state of affairs, IMO.
I envisage that Module::A should really be installed into the relevant architecture-specific location.
How do I tell ExtUtils::MakeMaker to do that ?
Or is there some better way of handling this ?
How do module authors generally deal with this issue ?

Cheers,
Rob

Replies are listed 'Best First'.
Re: How to tell EU::MM to install a pure-perl module into an architecture-specific location
by tobyink (Canon) on Sep 23, 2022 at 06:08 UTC

    You should be able to set the INST_LIB parameter when calling WriteMakefile() to determine which directory the modules will install into. Config.pm will provide $Config::Config{sitearchexp}.

    Note: I haven't actually tested this.

      Thanks for the pointer tobyink.
      I get the impression that this section of the EU::MM documentation is telling me what I need to know, but I can't make any sense of the table that it includes:
      make install make alone puts all relevant files into directories that are named + by the macros INST_LIB, INST_ARCHLIB, INST_SCRIPT, INST_MAN1DIR and INST_MAN3DIR. All these default to something below ./blib if you a +re *not* building below the perl source directory. If you *are* build +ing below the perl source, INST_LIB and INST_ARCHLIB default to ../../ +lib, and INST_SCRIPT is not defined. The *install* target of the generated Makefile copies the files fo +und below each of the INST_* directories to their INSTALL* counterpart +s. Which counterparts are chosen depends on the setting of INSTALLDIR +S according to the following table: INSTALLDIRS set to perl site vendor PERLPREFIX SITEPREFIX VENDORPREFIX INST_ARCHLIB INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDOR +ARCH INST_LIB INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDOR +LIB INST_BIN INSTALLBIN INSTALLSITEBIN INSTALLVENDOR +BIN INST_SCRIPT INSTALLSCRIPT INSTALLSITESCRIPT INSTALLVENDOR +SCRIPT INST_MAN1DIR INSTALLMAN1DIR INSTALLSITEMAN1DIR INSTALLVENDOR +MAN1DIR INST_MAN3DIR INSTALLMAN3DIR INSTALLSITEMAN3DIR INSTALLVENDOR +MAN3DIR The INSTALL... macros in turn default to their %Config ($Config{installprivlib}, $Config{installarchlib}, etc.) counterpa +rts. You can check the values of these variables on your system with perl '-V:install.*'
      If I can just get 'make install' to install into INSTALLSITEARCH (which is mentioned in the table), then that will be fine.
      But neither INSTALLDIRS => 'perl', nor INSTALLDIRS => 'site', nor INSTALLDIRS => 'vendor', will do that, and everything else I try turns out to be either ineffective or just plain rubbish.

      Can anyone tell from that (supposed) "table" just what argument I need to give to WriteMakefile() ?

      Cheers,
      Rob

        This looks to have some effect at least. It may be what you are after.

        #!/usr/bin/perl use strict; use warnings; use ExtUtils::MakeMaker; use Config; my %MF = ( macro => { INSTALLSITELIB => $Config{installsitearch} } ); WriteMakefile (%MF); exit;

        🦛

Re: How to tell EU::MM to install a pure-perl module into an architecture-specific location
by NERDVANA (Deacon) on Sep 24, 2022 at 07:29 UTC
    At that point, Module::A becomes immediately available to all 9 architectures, even though it has not been tested against 8 of them. This is an unsatisfactory state of affairs, IMO.

    Even more unsatisfactory, Module::A would be available on all 9 architectures possibly lacking many of its XS dependencies, and completely fail to work until someone ran cpanm under each other architecture to get the dependencies installed.

    How do module authors generally deal with this issue ?

    I don't think any module authors ever deal with it. This general usage pattern can't be fixed by a single module author; it would require all pure-perl modules with XS dependencies to always be installed in the architecture-specific location. I've never used this usage pattern either; every perl of a different arch that I've used has always had a complete standalone lib directory. (using perlbrew or plenv) I would guess the only time the multi-arch directories are actually intended to be used are when you have perl libs shared on NFS or a binary package repo or something like that. In that case, an administrator or distro maintainer would ensure the state of each arch before releasing the changes to the user base.

    Since you have to install your module 9 times anyway, you might consider automating it with something like Carton. Carton records the version of every module dependency installed, and would re-install all the dependent modules as you re-run it under each arch.

      I don't think any module authors ever deal with it.

      I think you're right about that.
      And, wrt my own modules, I'm now happy to utilize the solution that hippo provided.

      But there's the question of what to do about other people's modules on CPAN.
      For example, there's the pure-perl module Math::AnyNum that depends upon a number of perl extensions.
      Should I suggest to the Math::AnyNum author that he also apply hippo's fix to his module ?
      Or should I just deal with it myself ? - either by patching the Math::AnyNum Makefile.PL, or by doctoring the make install command as suggested by hv ?
      I tend to think that it's probably up to me to deal with it privately, but I might mention the issue to the Math::AnyNum author to ensure that he's at least aware of the issue.

      Cheers,
      Rob
        I tend to think that it's probably up to me to deal with it privately

        I agree. Any pure-perl module, regardless of whether it depends on impure modules at any depth, should go in the architecture-independent lib path by default. How else would you deal with the case where the deep dependencies change either to or from XS? Or vary depending on other factors?

        Your particular use case is far enough from the mainstream that it is IMHO up to you to set the necessary flags when installing such modules to meet your specific requirements.


        🦛

Re: How to tell EU::MM to install a pure-perl module into an architecture-specific location
by Anonymous Monk on Sep 23, 2022 at 09:55 UTC
      SorryAM, I missed your post while I was investigating and composing my reply to tobyink's.
      Again, I'm still faced with the table that I simply don't understand.

      I probably should just add an XS file (containing a meaningless and pointless XSub) to the Module::A distro, as that act alone would ensure that the module gets installed into INSTALLSITEARCH ;-)))

      Cheers,
      Rob

        The non-arch-specific files (INST_LIB) will be installed to INSTALLSITELIB, but you want them in the arch-specific site directory (INSTALLSITEARCH). So I think the comments so far (plus those docs) suggest that you could parse out the value of INSTALLSITEARCH from perl -V:installsitearch, then override INSTALLSITELIB to that value: perhaps at make time with something like make install INSTALLSITELIB=`find_archlib`.

        It is not clear however why you don't simply put each perl build in a separate hierarchy. That would give you the separation you want in a far cleaner and more obvious manner.

        I think the assumption underlying the existing directory layout is that things can and will be tested in isolation: if Module::B passes its tests and gets installed on each of perl-X and perl-Y, then it should not matter which of them the pure-perl Module::A has been tested against. If it does matter, that suggests either that there are tests missing for Module::B, or that there is code in one module that should be in the other.