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

Hi PerlMonks,

I wrote some modules of which some of them are platform dependent.

This is so far my manifest of it:

bin/sysscan Changes lib/System/Scanner.pm lib/System/Scanner/AIX.pm lib/System/Scanner/Linux.pm lib/System/Scanner/Linux/RHEL.pm lib/System/Scanner/Linux/SUSE.pm Makefile.PL MANIFEST README t/System-Scanner.t

The basis of this consists of the sysscan binary plus the Scanner.pm module. The rest is platform dependant. What I need is to create at least three, maybe five different modules out of it.

This is because the next step is to make rpm packages out of it for different platforms.

I tried to figure out how to do this with ExtUtils::MakeMaker and searched for a solution, but it really fried my brain.

I learned that somehow the CONFIGURE attribute of the hash provided to WriteMakefile could be a solution, in that I could place a coderef in it that alters the hashref itself, but I after lots of google-loops and dark circles around my eyes I gave up.

I only can guess what it really does and how it works and I thought that before I jump at it doing lots of trial and error, I should take back a step and ask someone ...

Is there some way in Makefile.PL or options to accomplish this?

Replies are listed 'Best First'.
Re: Makefile.PL: Howto make OS dependent modules
by Anonymous Monk on Jan 07, 2015 at 19:59 UTC
    Your manifest looks like it's only got pure Perl stuff in it, no XS, right? I'm not quite sure I understand the reason for needing to make several modules out of it - why not just one distribution with everything in it, and let the code decide which of the modules to load (and test during installation)? The only downside I see is having a few extra unused files lying around on your disk (and perhaps the minor runtime overhead of choosing which module to load, but it sounds like you need to do that anyway)... Don't know much about rpms, is there some reason that wouldn't work?

      Yes, youīre right, thereīs only Perl stuff in it.

      And as you assumed, the base module as well as the binary do test the OS and decide what they need (and complain if they donīt find it).

      The reasons why wanted to be able to split it up are rational reasons like to make the rpms smaller and fit to the underlying OS, and that this also could be some kind of template for bigger projects.

      On the other hand maybe there are some irrational reasons like: It looks like a wonderful, ordering, esthetic thing to me to do it that way. I know there must be some way to do it and it really iches me that I donīt know how...

Re: Makefile.PL: Howto make OS dependent modules
by Anonymous Monk on Jan 07, 2015 at 22:24 UTC
    See Devel::AssertOS, and consider that File::Spec and many other frontend modules with platform specific backend implementations don't load all the backends ... just the one that works

      Thank you for you hint with Devel::AssertOS.

      I looked into it, but Iīm afraid it does not quite serve my purpose.

      As I understand it dies when the underlying OS is not the intended one, but I covered that aspect already.

      What I need is, that by saying something like:
      perl Makefile.PL # Maybe some option here? os=all|Linux|AIX|RHEL|Suse make # To get everything or things covered with option # And if option is not possible: make Linux # To get Base plus all Linux stuff make RHEL # To get Base plus Linux.pm plus RHEL.pm make Suse # To get Base plus Linux.pm plus Suse.pm make AIX # To get Base plus AIX.pm make test # To test all related tests make install # To install only selected modules

      That way only the selected modules get installed out of my manifest.

      As I see it, I must teach somehow Makefile.PL either to select the appropriate things I need when I call it (with options) or to make Makefile.Pl make additional targets (like AIX, Linux ...).

      I saw the CONFIGURE attribute in the documentation of ExtUtils::MakeMaker which looked very promising to accomplish this:

      CONFIGURE CODE reference. The subroutine should return a hash reference. The hash may contain further attributes, e.g. {LIBS => ...}, that have to be determined by some evaluation method.

      I also found a small article in CPAN how to create own make targets:

      sub MY::postamble { return <<'MAKE_FRAG'; $(MYEXTLIB): sdbm/Makefile cd sdbm && $(MAKE) all MAKE_FRAG }

      But all that I find extremely vague and unintuitive...

      A good example could help :-)

        I looked into it, but Iīm afraid it does not quite serve my purpose.

        Look up :) AssertOS is in the CheckOS distribution ... Devel::CheckOS - check what OS we're running on ... this mean it doesn't die

        So then

        package System::Scaller; use Module::Load qw/ load /; use Devel::CheckOS qw/ os_is /; my @targets = ( [qw/ AIX System::Scanner::AIX /], [qw/ RHEL System::Scanner::Linux::RHEL /], [qw/ SUSE System::Scanner::Linux::SUSE /], ); for my $targ ( @targets ){ my( $name, $module ) = @_; if( os_is( $name ) ){ load $module; @System::Scaller::ISA = $module; last; } } 1;

        You install everything, you only load the module thats appropriate for the platform

        Hacking Makefiles and only packing certain files is PITA, avoid it