EXTUTILS::MM_ANY(3perl)

๐Ÿ’– ExtUtils::MM_Any โ€” Platform-agnostic MM methods ๐Ÿ’–

okay so bestie, you've stumbled into ExtUtils::MM_Any(3perl) and honestly? iconic of you. this whole page is the cross-platform glue of MakeMaker and she does NOT get enough credit. let's get into it ๐Ÿซถ


๐Ÿ“› NAME ๐Ÿ“›

ExtUtils::MM_Any โ€” Platform-agnostic MM methods. that's it. that's the name. short, powerful, main character energy โœจ


๐ŸŽ€ SYNOPSIS ๐ŸŽ€

like, read the room first bestie:

  FOR INTERNAL USE ONLY!

  package ExtUtils::MM_SomeOS;

  # Temporarily, you have to subclass both.  Put MM_Any first.
  require ExtUtils::MM_Any;
  require ExtUtils::MM_Unix;
  @ISA = qw(ExtUtils::MM_Any ExtUtils::Unix);
FOR INTERNAL USE ONLY! like actually. this is not for you unless you're writing an MM subclass, no cap ๐Ÿ’€

๐ŸŒธ DESCRIPTION ๐ŸŒธ

FOR INTERNAL USE ONLY! (saying it twice because it's THAT serious ๐Ÿ’…)

ExtUtils::MM_Any is the superclass of the whole ExtUtils::MM_* family. She holds methods that are either inherently cross-platform, or written in a way that works cross-platform. queen behaviour, honestly ๐Ÿ‘‘

so the move is: you subclass off of ExtUtils::MM_Any and ExtUtils::MM_Unix. yes, both. this is a temporary solution. like, is it pretty? no. does it work? yes. moving on ๐Ÿฆ‹

THIS MAY BE TEMPORARY! screaming this from the rooftops, don't build your whole life on it ๐Ÿ˜ญ

๐Ÿ› ๏ธ METHODS ๐Ÿ› ๏ธ

any method that's marked Abstract has to be implemented by the subclasses, no exceptions, that's the assignment bestie ๐Ÿ’ช

๐ŸŒˆ Cross-platform helper methods

these are the little helpers that make writing cross-platform code not a total nightmare โœจ

๐Ÿ” os_flavor โ€” Abstract

    my @os_flavor = $mm->os_flavor;

@os_flavor is the style of operating system we're on, and it usually lines up with whichever MM_*.pm file is in play.

the first element of @os_flavor is the major family (like Unix, Windows, VMS, OS/2, etcโ€ฆ) and everything after that is sub-families. so like, family name first, then the whole friend group ๐ŸŽ€

some examples so you can see the vibe:

    Cygwin98       ('Unix',  'Cygwin', 'Cygwin9x')
    Windows        ('Win32')
    Win98          ('Win32', 'Win9x')
    Linux          ('Unix',  'Linux')
    MacOS X        ('Unix',  'Darwin', 'MacOS', 'MacOS X')
    OS/2           ('OS/2')

this is how you write code for specific styles of OS. and for how to actually use it, see os_flavor_is(). iykyk ๐Ÿ’…

๐Ÿ” os_flavor_is

    my $is_this_flavor = $mm->os_flavor_is($this_flavor);
    my $is_this_flavor = $mm->os_flavor_is(@one_of_these_flavors);

checks if the current OS is one of the flavors you passed in. so basically "are we on one of these or nah?" ๐Ÿงš

it's useful for stuff like this:

    if( $mm->os_flavor_is('Unix') ) {
        $out = `foo 2>&1`;
    }
    else {
        $out = `foo`;
    }

๐Ÿ” can_load_xs

    my $can_load_xs = $self->can_load_xs;

returns true if we can actually load XS. and this matters because miniperl โ€” the thing used to build XS modules in the core โ€” cannot load XS. so yeah, this check is doing a lot of heavy lifting ๐Ÿ˜ค

๐Ÿ” can_run

  use ExtUtils::MM;
  my $runnable = MM->can_run($Config{make});

in scalar context: gives you the full path to the binary you asked for if it was found, or undef if it wasn't. ๐Ÿคท

in list context: gives you a list of full paths to all the instances of that binary found in PATH, or an empty list if it wasn't found at all.

she's copied from IPC::Cmd, but modified into a method (and the $INSTANCES capability got removed, rest in peace ๐Ÿ•Š๏ธ).

๐Ÿ” can_redirect_error

  $useredirect = MM->can_redirect_error;

true if you're on an OS where the qx operator (or backticks) can redirect STDERR onto STDOUT. โœจ

๐Ÿ” is_make_type

    my $is_dmake = $self->is_make_type('dmake');

returns true if $self->make is the type you named. the possibilities are:

  gmake    GNU make
  dmake
  nmake
  bsdmake  BSD pmake-derived

๐Ÿ” can_dep_space

    my $can_dep_space = $self->can_dep_space;

returns true if make can handle dependencies that contain a space (probably by quoting them). currently known to be true for GNU make, and false for BSD pmake derivatives. so like, don't expect spaces to just work everywhere bestie ๐Ÿ™ˆ

๐Ÿ” quote_dep

  $text = $mm->quote_dep($text);

this method protects Makefile single-value constants (mostly filenames) so that make still treats them as single values โ€” even when they rudely contain spaces. if the make program being used can't pull that off and your text needs it, it throws an exception. no silent failure here, periodt ๐Ÿšจ

๐Ÿ” split_command

    my @cmds = $MM->split_command($cmd, @args);

most OSes have a maximum command length they can execute in one go. and large modules can easily blow past that limit like it's nothing. so you gotta chop long commands into a bunch of shorter ones. ๐Ÿ˜ฎ๐Ÿ’จ

split_command returns a series of @cmds, each one processing part of the args. together, they process all the arguments. and no individual line in @cmds will be longer than $self->max_exec_len, being careful to account for macro expansion. thoughtful queen โœจ

$cmd should include any switches and repeated initial arguments. if it has newlines, those should already be escaped.

if no @args are given, no @cmds come back. simple math ๐Ÿ’…

pairs of arguments will always be preserved inside a single command โ€” that's a heuristic for things like pm_to_blib and pod2man, which work on pairs of arguments. which makes stuff like this totally safe:

    $self->split_command($cmd, %pod2man);

๐Ÿ” make_type

returns a suitable string describing the type of makefile being written. that's it, that's the whole job ๐ŸŽ€

๐Ÿ” stashmeta

    my @recipelines = $MM->stashmeta($text, $file);

generates a set of @recipelines that'll result in the literal $text landing in the literal $file once the recipe runs. call it once, with all the text you want in $file. heads up: make macros will not be expanded, so the locations get fixed at configure-time, not at build-time. plan accordingly ๐Ÿ•ฐ๏ธ

๐Ÿ” echo

    my @commands = $MM->echo($text);
    my @commands = $MM->echo($text, $file);
    my @commands = $MM->echo($text, $file, \%opts);

generates a set of @commands that print $text to a $file. ๐Ÿ“ข

  • if $file isn't given, output goes to STDOUT.
  • if $opts{append} is true, the $file gets appended to instead of overwritten. default is to overwrite.
  • if $opts{allow_variables} is true, make variables of the form $(...) won't be escaped. other $ will be. default is to escape all $.

example of it in the wild:

    my $make = join '', map "\t$_\n", $MM->echo($text, $file);

๐Ÿ” wraplist

  my $args = $mm->wraplist(@list);

takes an array of items and turns it into a nicely formatted list of arguments. in most cases it's just something like:

  FOO \
  BAR \
  BAZ

clean, readable, we love a formatting queen ๐ŸŒธ

๐Ÿ” maketext_filter

    my $filter_make_text = $mm->maketext_filter($make_text);

the text of the Makefile gets run through this method before it hits disk. it gives systems a chance to make portability fixes to the Makefile. by default? it does absolutely nothing. ๐Ÿ’ค

this method is protected and not meant to be called outside of MakeMaker, so don't go poking at it ๐Ÿ™…

๐Ÿ” cd โ€” Abstract

  my $subdir_cmd = $MM->cd($subdir, @cmds);

this generates a make fragment that runs the @cmds in the given $dir. it's the rough equivalent of this, except cross-platform:

  cd $subdir && $cmd

right now $dir can only go down one level. "foo" is fine. "foo/bar"? not fine. "../foo"? right out. ๐Ÿšซ

the resulting $subdir_cmd has no leading tab and no trailing newline โ€” which makes it way easier to embed in a make string. for example:

      my $make = sprintf <<'CODE', $subdir_cmd;
  foo :
      $(ECHO) what
      %s
      $(ECHO) mouche
  CODE

๐Ÿ” oneliner โ€” Abstract

  my $oneliner = $MM->oneliner($perl_code);
  my $oneliner = $MM->oneliner($perl_code, \@switches);

this generates a perl one-liner that's safe for whatever platform you're on, based on the given $perl_code and @switches (a -e is assumed), suitable for use in a make target. it handles the proper shell quoting and escapes for you. ๐Ÿงšโœจ

$(PERLRUN) will be used as perl.

any newlines in $perl_code get escaped. leading and trailing newlines get stripped. which makes this idiom so much easier:

    my $code = $MM->oneliner(<<'CODE', [...switches...]);
some code here
another line here
CODE

usage might look something like:

    # an echo emulation
    $oneliner = $MM->oneliner('print "Foo\n"');
    $make = '$oneliner > somefile';

dollar signs inside $perl_code get protected from make using the quote_literal method โ€” unless they're recognised as being a make variable, $(varname), in which case they get left for make to expand. and remember to quote make macros or it might get used as a bareword! like:

    # Assign the value of the $(VERSION_FROM) make macro to $vf.
    $oneliner = $MM->oneliner('$vf = "$(VERSION_FROM)"');

ngl she's currently very simple, and may get expanded sometime in the future to include more flexible code and switches. we'll see ๐Ÿ‘€

๐Ÿ” quote_literal โ€” Abstract

    my $safe_text = $MM->quote_literal($text);
    my $safe_text = $MM->quote_literal($text, \%options);

this quotes $text so the shell interprets it literally. ๐Ÿ”’

for example, on Unix this would escape any single-quotes in $text and wrap the whole thing in single-quotes.

  • if $options{allow_variables} is true, it leaves '$(FOO)' make variables untouched.
  • if false, they get escaped like any other $.
  • defaults to true.

๐Ÿ” escape_dollarsigns

    my $escaped_text = $MM->escape_dollarsigns($text);

escapes stray $ so they don't get interpreted as make variables. it lets $(...) by. ๐Ÿ’ธ

๐Ÿ” escape_all_dollarsigns

    my $escaped_text = $MM->escape_all_dollarsigns($text);

escapes all $ so they don't get interpreted as make variables. all of them. every last one. ๐Ÿ˜ค

๐Ÿ” escape_newlines โ€” Abstract

    my $escaped_text = $MM->escape_newlines($text);

shell escapes newlines in $text. โŽ

๐Ÿ” max_exec_len โ€” Abstract

    my $max_exec_len = $MM->max_exec_len;

calculates the maximum command size the OS can exec. effectively, it's the max size of a shell command line. ๐Ÿ“

๐Ÿ” make

    my $make = $MM->make;

returns the make variant we're generating the Makefile for. it tries to do some normalization on the info coming from %Config or from the user. tidying up, as a treat ๐ŸŽ€


๐ŸŽฏ Targets

these are the methods that produce make targets. les get it ๐Ÿ”ฅ

๐ŸŽฏ all_target

generate the default target all. that's the whole thing bestie ๐Ÿ’…

๐ŸŽฏ blibdirs_target

    my $make_frag = $mm->blibdirs_target;

creates the blibdirs target, which creates all the directories we use inside blib/. ๐Ÿ“

the blibdirs.ts target is deprecated. depend on blibdirs instead.

๐ŸŽฏ clean (o)

defines the clean target. (the (o) means it lives over in another doc, go peek there ๐Ÿ‘€)

๐ŸŽฏ clean_subdirs_target

  my $make_frag = $MM->clean_subdirs_target;

returns the clean_subdirs target. the clean target uses this to call clean on any subdirectories that contain Makefiles. ๐Ÿงน

๐ŸŽฏ dir_target

    my $make_frag = $mm->dir_target(@directories);

generates targets to create the specified directories and set their permission to PERM_DIR.

here's the tea: depending on a directory to just ensure it exists doesn't work great, because the modified time changes way too often. so dir_target() creates a .exists file inside the created directory instead โ€” and that's what you should depend on. ๐Ÿซถ

for portability, you should use the $(DIRFILESEP) macro rather than a / to separate the directory from the file:

    yourdirectory$(DIRFILESEP).exists

๐ŸŽฏ distdir

defines the scratch directory target that holds the distribution before tar-ing (or shar-ing) it. ๐Ÿ“ฆ

๐ŸŽฏ dist_test

defines a target that produces the distribution in the scratch directory, and runs 'perl Makefile.PL; make ;make test' inside that subdirectory. ๐Ÿงช

๐ŸŽฏ xs_dlsyms_arg

(more on this one coming up next ๐Ÿ’–)

Returns the command-line arg(s) you hand over to the linker for the file that lists dlsyms to export ๐ŸŒธ. By default she just gives you back an empty string โ€” but like, things such as AIX can override it, iykyk.

xs_dlsyms_ext ๐Ÿ’…

Returns the file extension for the output file of the xs_make_dlsyms method โ€” and yes, any "." character is included in that, bestie, don't worry.

xs_dlsyms_extra โœจ

Returns whatever extra text needs to be prepended to the $extra argument of xs_make_dlsyms.

xs_dlsyms_iterator ๐Ÿฆ‹

Iterates over the necessary shared objects, calling the xs_make_dlsyms method for each one with the appropriate arguments. Very for-each core of her.

xs_make_dlsyms

$self->xs_make_dlsyms(
    \%attribs, # hashref from %attribs in caller
    "$self->{BASEEXT}.def", # output file for Makefile target
    'Makefile.PL', # dependency
    $self->{NAME}, # shared object's "name"
    $self->{DLBASE}, # last ::-separated part of name
    $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {}, # various params
    $attribs{FUNCLIST} || $self->{FUNCLIST} || [],
    $attribs{IMPORTS} || $self->{IMPORTS} || {},
    $attribs{DL_VARS} || $self->{DL_VARS} || [],
    # optional extra param that will be added as param to Mksymlists
);

Utility method that returns a Makefile snippet to call Mksymlists. She ate that.

dynamic (o)

Defines the dynamic target. Periodt.

makemakerdflt_target

my $make_frag = $mm->makemakerdflt_target

Returns a make fragment with the makemakerdeflt_target specified. This target is the first target in the Makefile, it's the default target, and it just points off to 'all' โ€” purely in case some make variant gets confused or something gets snuck in before the real 'all' target. Safety-net energy ๐Ÿซถ.

manifypods_target

my $manifypods_target = $self->manifypods_target;

Generates the manifypods target. This one generates man pages from all the POD files in MAN1PODS and MAN3PODS.

metafile_target

my $target = $mm->metafile_target;

Generate the metafile target.

Writes the file META.yml (YAML encoded meta-data) and META.json (JSON encoded meta-data) about the module in the distdir. The format follows Module::Build's as closely as possible. Copying her older sister's homework but making it fashion ๐Ÿ’–.

metafile_data

my $metadata_hashref = $mm->metafile_data(\%meta_add, \%meta_merge);

Returns the data which MakeMaker turns into the META.yml file and the META.json file. It is always in version 2.0 of the format, no exceptions.

Values of %meta_add will overwrite any existing metadata in those keys. %meta_merge will be merged with them.

metafile_file

my $meta_yml = $mm->metafile_file(@metadata_pairs);

Turns the @metadata_pairs into YAML.

Heads up bestie ๐Ÿ’€ โ€” this method does NOT implement a complete YAML dumper. It's being limited to dump a hash with values which are strings, undef's or nested hashes and arrays of strings. No quoting/escaping is done. So don't come at her with your chaotic data, she's not ready.

distmeta_target

my $make_frag = $mm->distmeta_target;

Generates the distmeta target to add META.yml and META.json to the MANIFEST in the distdir.

mymeta

my $mymeta = $mm->mymeta;

Generate MYMETA information as a hash โ€” either from an existing CPAN Meta file (META.json or META.yml) or from internal data. Either way, she delivers ๐ŸŽ€.

write_mymeta

$self->write_mymeta( $mymeta );

Write MYMETA information to MYMETA.json and MYMETA.yml. Simple, clean, iconic.

realclean (o)

Defines the realclean target.

realclean_subdirs_target

my $make_frag = $MM->realclean_subdirs_target;

Returns the realclean_subdirs target. The realclean target uses it to call realclean on any subdirectories which contain Makefiles. Recursive queen ๐Ÿ‘‘.

signature_target

my $target = $mm->signature_target;

Generate the signature target.

Writes the file SIGNATURE with cpansign -s.

distsignature_target

my $make_frag = $mm->distsignature_target;

Generates the distsignature target to add SIGNATURE to the MANIFEST in the distdir.

special_targets

my $make_frag = $mm->special_targets

Returns a make fragment containing any targets which have special meaning to make. For example, .SUFFIXES and .PHONY. The VIPs only ๐ŸŒˆ.


โœจ Init methods โœจ

Methods which help initialize the MakeMaker object and macros. Glow-up time, bestie.

init_ABSTRACT

$mm->init_ABSTRACT

init_INST

$mm->init_INST;

Called by init_main. Sets up all the INST_* variables โ€” except the ones related to XS code. Those get handled over in init_xs.

init_INSTALL

$mm->init_INSTALL;

Called by init_main. Sets up all the INSTALL_* variables (except INSTALLDIRS) and *PREFIX.

init_INSTALL_from_PREFIX

$mm->init_INSTALL_from_PREFIX;

init_from_INSTALL_BASE

$mm->init_from_INSTALL_BASE

init_VERSION (Abstract)

$mm->init_VERSION

Initialize macros representing versions of MakeMaker and other tools.

  • MAKEMAKER: path to the MakeMaker module.
  • MM_VERSION: ExtUtils::MakeMaker Version
  • MM_REVISION: ExtUtils::MakeMaker version control revision (for backwards compat)
  • VERSION: version of your module
  • VERSION_MACRO: which macro represents the version (usually 'VERSION')
  • VERSION_SYM: like version but safe for use as an RCS revision number
  • DEFINE_VERSION: -D line to set the module version when compiling
  • XS_VERSION: version in your .xs file. Defaults to $(VERSION)
  • XS_VERSION_MACRO: which macro represents the XS version.
  • XS_DEFINE_VERSION: -D line to set the xs version when compiling.

Called by init_main.

init_tools

$MM->init_tools();

Initializes the simple macro definitions used by tools_other() and places them in the $MM object. These use conservative cross platform versions and should be overridden with platform specific versions for performance. (Do it for the speed, bestie โ€” she's asking nicely ๐Ÿ’….)

Defines at least these macros:

  • NOOP โ€” Do nothing
  • NOECHO โ€” Tell make not to display the command itself
  • SHELL โ€” Program used to run shell commands
  • ECHO โ€” Print text adding a newline on the end
  • RM_F โ€” Remove a file
  • RM_RF โ€” Remove a directory
  • TOUCH โ€” Update a file's timestamp
  • TEST_F โ€” Test for a file's existence
  • TEST_S โ€” Test the size of a file
  • CP โ€” Copy a file
  • CP_NONEMPTY โ€” Copy a file if it is not empty
  • MV โ€” Move a file
  • CHMOD โ€” Change permissions on a file
  • FALSE โ€” Exit with non-zero
  • TRUE โ€” Exit with zero
  • UMASK_NULL โ€” Nullify umask
  • DEV_NULL โ€” Suppress all command output

init_others

$MM->init_others();

Initializes the macro definitions having to do with compiling and linking used by tools_other() and places them in the $MM object.

If there is no description, its the same as the parameter to WriteMakefile() documented in ExtUtils::MakeMaker.

tools_other

my $make_frag = $MM->tools_other;

Returns a make fragment containing definitions for the macros init_others() initializes.

init_DIRFILESEP (Abstract)

$MM->init_DIRFILESEP;
my $dirfilesep = $MM->{DIRFILESEP};

Initializes the DIRFILESEP macro, which is the separator between the directory and filename in a filepath. ie. / on Unix, \ on Win32 and nothing on VMS.

For example:

# instead of $(INST_ARCHAUTODIR)/extralibs.ld
$(INST_ARCHAUTODIR)$(DIRFILESEP)extralibs.ld

Something of a hack but it prevents a lot of code duplication between MM_* variants. We love a messy shortcut that works ๐Ÿซถ.

Do NOT use this as a separator between directories. Some operating systems use different separators between subdirectories as between directories and filenames (for example: VOLUME:[dir1.dir2]file on VMS). Read it again bestie, this one's important.

init_linker (Abstract)

$mm->init_linker;

Initialize macros which have to do with linking.

  • PERL_ARCHIVE: path to libperl.a equivalent to be linked to dynamic extensions.
  • PERL_ARCHIVE_AFTER: path to a library which should be put on the linker command line after the external libraries to be linked to dynamic extensions. This may be needed if the linker is one-pass, and Perl includes some overrides for C RTL functions, such as malloc().
  • EXPORT_LIST: name of a file that is passed to linker to define symbols to be exported.

Some OSes do not need these, in which case leave it blank.

init_platform

$mm->init_platform

Initialize any macros which are for platform specific use only.

A typical one is the version number of your OS specific module. (ie. MM_Unix_VERSION or MM_VMS_VERSION).

init_MAKE

$mm->init_MAKE

Initialize MAKE from either a MAKE environment variable or $Config{make}.


๐Ÿ› ๏ธ Tools ๐Ÿ› ๏ธ

A grab bag of methods to generate specific macros and commands. Chaotic, but in a cute way.

manifypods

Defines targets and routines to translate the pods into manpages and put them into the INST_* directories.

POD2MAN_macro

my $pod2man_macro = $self->POD2MAN_macro

Returns a definition for the POD2MAN macro. This is a program which emulates the pod2man utility. You can add more switches to the command by simply appending them on the macro. Cute, right? โœจ

Typical usage:

$(POD2MAN) --section=3 --perm_rw=$(PERM_RW) podfile1 man_page1 ...

test_via_harness

my $command = $mm->test_via_harness($perl, $tests);

Returns a $command line which runs the given set of $tests with Test::Harness and the given $perl.

Used on the t/*.t files.

test_via_script

my $command = $mm->test_via_script($perl, $script);

Returns a $command line which just runs a single test without Test::Harness. No checks are done on the results, they're just printed. No notes, just vibes ๐Ÿฆ‹.

Used for test.pl, since they don't always follow Test::Harness formatting.

tool_autosplit

Defines a simple perl call that runs autosplit. May be deprecated by pm_to_blib soon. RIP bestie, possibly ๐Ÿ’€.

arch_check

my $arch_ok = $mm->arch_check(
    $INC{"Config.pm"},
    File::Spec->catfile($Config{archlibexp}, "Config.pm")
);

A sanity check that what Perl thinks the architecture is and what Config thinks the architecture is are the same. If they're not it will return false and show a diagnostic message. ๐Ÿšฉ

When building Perl it will always return true, as nothing is installed yet.

The interface is a bit odd because this is the result of a quick refactoring. Don't rely on it. Fr.


๐Ÿฆ‹ File::Spec wrappers ๐Ÿฆ‹

ExtUtils::MM_Any is a subclass of File::Spec. The methods noted here override File::Spec.

catfile

File::Spec <= 0.83 has a bug where the file part of catfile is not canonicalized. This override fixes that bug. In her bug-squashing era ๐Ÿ˜Œ๐Ÿ’….


๐ŸŽฒ Misc ๐ŸŽฒ

Methods I can't really figure out where they should go yet. Respect the honesty, honestly.

find_tests

my $test = $mm->find_tests;

Returns a string suitable for feeding to the shell to return all tests in t/*.t.

find_tests_recursive

my $tests = $mm->find_tests_recursive;

Returns a string suitable for feeding to the shell to return all tests in t/ but recursively. Equivalent to

my $tests = $mm->find_tests_recursive_in('t');

๐Ÿ” find_tests_recursive_in ๐Ÿ”

my $tests = $mm->find_tests_recursive_in($dir);

okay so bestie hands it a $dir and gets back a string you can literally feed to the shell ๐Ÿ’… and that string will make the shell return, like, all the tests in $dir โ€” recursively. every last one. she did the walking so you don't have to ๐Ÿซถ


๐Ÿงผ extra_clean_files ๐Ÿงผ

my @files_to_clean = $MM->extra_clean_files;

gives you back a list of OS-specific files that get yeeted during the clean target โ€” and these are on top of the usual set, not instead of it. so it's the regular cleanup plus the platform-specific extras. no cap ๐Ÿงš


๐Ÿ“‹ installvars ๐Ÿ“‹

my @installvars = $mm->installvars;

it's a list of every single INSTALL* variable but with the INSTALL prefix chopped off โœ‚๏ธ super handy when you're looping over them or building related variable sets. it's giving convenience ๐Ÿ’–


๐Ÿšซ libscan ๐Ÿšซ

my $wanted = $self->libscan($path);

you give her the path to a file or a dir, and:

  • if we don't want this thing in the library โ†’ she returns an empty string (the vibe check failed, sorry babe ๐Ÿ™ˆ)
  • otherwise โ†’ she returns the $path back to you, unchanged, untouched, exactly as you gave it โœจ

and what is this actually for? mainly two little jobs: excluding version control administrative directories from installation, and excluding the base-level README.pod from installation. that's it, that's the whole gig ๐Ÿ‘‘


๐Ÿงฑ platform_constants ๐Ÿงฑ

my $make_frag = $mm->platform_constants

returns a make fragment that defines all the macros initialized over in init_platform() โ€” because instead of tossing them into constants(), we keep them here. same macros, different real estate ๐Ÿ 


โœจ post_constants (o) โœจ

returns an empty string by default, fr. it exists so that overrides from within Makefile.PL can do their thing after all the constants have been defined. it's the after-party ๐ŸŽ€


๐ŸŒธ post_initialize (o) ๐ŸŒธ

also an empty string by default, naturally. used in Makefile.PLs to add some chunk of text to the Makefile after the object is initialized. it's the "okay now I'm awake, here's a thought" hook ๐Ÿ’ญ


๐ŸŒ™ postamble (o) ๐ŸŒ™

yep, empty string. can be used in Makefile.PLs to write some text to the Makefile right at the very end. the last word. the mic drop ๐ŸŽค


๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Michael G Schwern <schwern@pobox.com> and the denizens of makemaker@perl.org, with code from ExtUtils::MM_Unix and ExtUtils::MM_Win32. legends, all of them, no notes ๐Ÿ’œ


and that's the whole page bestie!! this was ExtUtils::MM_Any(3perl) from perl v5.44.0, dated 2026-10-17 โ€” go forth and Makefile your little heart out ๐ŸŒˆโญ periodt ๐Ÿ’…

๐Ÿ“ฆ where this page comes from
  • arch rolling: perl 5.44.0-1 ยท Artistic-1.0-Perl AND GPL-1.0-or-later
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms