Karen Etheridge 🐾 🌋


Dist::Zilla::Plugin::DynamicPrereqs - Specify dynamic (user-side) prerequisites for your distribution


version 0.015


In your dist.ini:

    -condition = has_module('Role::Tiny')
    -condition = !parse_args()->{PUREPERL_ONLY}
    -condition = can_xs()
    -raw = $WriteMakefileArgs{PREREQ_PM}{'Role::Tiny'} = $FallbackPrereqs{'Role::Tiny'} = '1.003000'


    -delimiter = |
    -raw = |$WriteMakefileArgs{TEST_REQUIRES}{'Devel::Cover'} = $FallbackPrereqs{'Devel::Cover'} = '0'
    -raw = |    if $ENV{EXTENDED_TESTING} or is_smoker();
    -include_sub = is_smoker


    -raw_from_file = Makefile.args      # code snippet in this file


This is a Dist::Zilla plugin that inserts code into your Makefile.PL to indicate dynamic (installer-side) prerequisites.

Code is inserted immediately after the declarations for %WriteMakefileArgs and %FallbackPrereqs, before they are conditionally modified (when an older ExtUtils::MakeMaker is installed). This gives you an opportunity to add to the WriteMakefile arguments: PREREQ_PM, BUILD_REQUIRES, and TEST_REQUIRES, and therefore modify the prerequisites in the user's MYMETA.yml and MYMETA.json based on conditions found on the user's system.

The dynamic_config field in metadata is already set for you.

You could potentially use this plugin for performing other modifications in Makefile.PL other than user-side prerequisite modifications, but I can't think of a situation where this makes sense. Contact me if you have any ideas!

Only Makefile.PL modification is supported at this time. This author considers the use of Module::Build to be questionable in all circumstances, and Module::Build::Tiny does not (yet?) support dynamic configuration.



The code to be inserted; must be valid and complete perl statements. You can reference and modify the already-declared %WriteMakefileArgs and %FallbackPrereqs variables, as inserted into Makefile.PL by Dist::Zilla::Plugin::MakeMaker and subclasses (e.g. Dist::Zilla::Plugin::MakeMaker::Awesome since Dist::Zilla 5.001.

This option can be used more than once; lines are added in the order in which they are provided.

This option is pretty low-level; I anticipate its use to be deprecated when better options are added (see below). In particular, the user should not have to be aware of existing code in Makefile.PL nor the exact code required to add prerequisites of various types.

If you use external libraries in the code you are inserting, you must add these modules to configure_requires prereqs in metadata (e.g. via [Prereqs / ConfigureRequires] in your dist.ini).


(Available since version 0.007)

A string, usually a single character, which is stripped from the beginning of all -raw lines. This is because the INI file format strips all leading whitespace from option values, so including this character at the front allows you to use leading whitespace in an option string, so you can indent blocks of code properly.


(Available since version 0.010)

A filename that contains the code to be inserted; must be valid and complete perl statements, as with -raw above. This file must be part of the build, but it is pruned from the built distribution.


(Available since version 0.014)

A perl expression to be included in the condition statement in the Makefile.PL. Multiple -conditions can be provided, in which case they are ANDed together to form the final condition statement. (You must appropriately parenthesize each of your conditions to ensure correct order of operations.) Any use of recognized subroutines will cause their definitions to be included automatically (see "AVAILABLE SUBROUTINE DEFINITIONS", below).

When combined with -raw lines, the condition is placed first in a if statement, and the -raw lines are contained as the body of the block. For example:

    -condition = $] > '5.020'
    -raw = $WriteMakefileArgs{PREREQ_PM}{'Role::Tiny'} = $FallbackPrereqs{'Role::Tiny'} = '1.003000'

results in the Makefile.PL snippet:

    if ($] > '5.020') {
    $WriteMakefileArgs{PREREQ_PM}{'Role::Tiny'} = $FallbackPrereqs{'Role::Tiny'} = '1.003000'


(Available since version 0.010; some subs have been added later, as noted)

The name of a subroutine that you intend to call from the code inserted via -raw or -raw_from_file. Its definition will be included in Makefile.PL, as well as any helper subs it calls; necessary prerequisite modules will be added to configure requires metadata. This option can be used more than once. See "AVAILABLE SUBROUTINE DEFINITIONS" for the complete list of sub names that can be requested.


Available subs are:

  • prompt_default_yes($message) - takes a string (appending "[Y/n]" to it), returns a boolean; see "prompt" in ExtUtils::MakeMaker

  • prompt_default_no($message) - takes a string (appending "[y/N]" to it), returns a boolean; see "prompt" in ExtUtils::MakeMaker

  • parse_args() - returns the hashref of options that were passed as arguments to perl Makefile.PL

  • can_xs() - Secondary compile testing via ExtUtils::CBuilder

  • can_cc() - can we locate a (the) C compiler

  • can_run() - check if we can run some command

  • can_use($module, $version (optional)) - checks if a module (optionally, at a specified version) can be loaded. (If you don't want to load the module, you should use has_module, see below.)

  • has_module($module, $version_or_range (optional)) - checks if a module (optionally, at a specified version or matching a version range) is available in %INC. Does not load the module, so is safe to use with modules that have side effects when loaded. When passed a second argument, returns true or false; otherwise, returns undef or the module's $VERSION. (Current API available since version 0.015.)

  • is_smoker() - is the installation on a smoker machine?

  • is_interactive() - is the installation in an interactive terminal?

  • is_trial() - is the release a -TRIAL or _XXX-versioned release?

  • is_os($os, ...) - true if the OS is any of those listed

  • isnt_os($os, ...) - true if the OS is none of those listed

  • maybe_command - actually a monkeypatch to MM->maybe_command (please keep using the fully-qualified form) to work in Cygwin


The implementations for some subroutines (in particular, can_xs, can_cc and can_run are still incomplete, incompatible with some architectures and cannot yet be considered a suitable generic solution. Until we are more confident in their implementations, a warning will be printed upon use, and their use is not advised without prior consultation with the author.


This plugin is still undergoing active development, and the interfaces will change and grow as I work through the proper way to do various things. As I make changes, I will be using metacpan's reverse dependencies list and http://grep.cpan.me to find and fix any upstream users, but I obviously cannot do this for DarkPAN users. Regardless, please contact me (see below) and I will keep you directly advised of interface changes.

Future options may include:

  • -phase the phase in which subsequently-specified module/version pairs will be added

  • -runtime a module and version that is added to runtime prereqs should the -condition be satisfied

  • -test a module and version that is added to test prereqs should the -condition be satisfied

  • -build a module and version that is added to build prereqs should the -condition be satisfied


Bugs may be submitted through the RT bug tracker (or bug-Dist-Zilla-Plugin-DynamicPrereqs@rt.cpan.org). I am also usually active on irc, as 'ether' at irc.perl.org.



Karen Etheridge <ether@cpan.org>


This software is copyright (c) 2014 by Karen Etheridge.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.