Make your CPAN module static installable

CPAN modules are normally distributed with Makefile.PL or Build.PL, so that people can install them by

> perl Makefile.PL
> make
> make test
> make install

This makes CPAN modules installable without any CPAN clients help unlike other programing language ecosystem (such as ruby(gem), node(npm)).

On the other hand, today, people mostly use CPAN clients (such as CPAN.pm, cpanm) to install CPAN modules. And it seems that when CPAN modules are not "complicated", CPAN clients easily expect how to build/test/install them even without executing Makefile.PL or Build.PL.

Now we have the concept Static Install. That is, if CPAN modules are not "complicated" and set x_static_install 1 in their META.json, then we may install them statically.

cpanm-menlo (cpanm 2.0) and cpm support the static install. So if a CPAN module set x_static_install 1 in its META.json, then cpanm-menlo and cpm use their bundled builder to build/test/install the CPAN module. There is no execution of perl Makefile.PL or make.

Why do you make your CPAN module static installable?

Fast

Because CPAN clients do not need to execute external programs during installation, people can install your module fast.

Example: Win32::ShellQuote (which set x_static_install 1 in META.json)

> wget http://www.cpan.org/authors/id/H/HA/HAARG/Win32-ShellQuote-0.003001.tar.gz
> tar xzf Win32-ShellQuote-0.003001

# with x_static_install 1
> cpm install -v .
29899 DONE fetch     (0.054sec) file:///Win32-ShellQuote-0.003001
29899 DONE configure (0.012sec) file:///Win32-ShellQuote-0.003001
29899 DONE install   (0.020sec) file:///Win32-ShellQuote-0.003001
1 distribution installed.

# without x_static_install 1
> vim META.json # remove x_static_install 1
> cpm install -v .
29937 DONE fetch     (0.047sec) file:///Win32-ShellQuote-0.003001
29937 DONE configure (0.200sec) file:///Win32-ShellQuote-0.003001
29937 DONE install   (0.433sec) file:///Win32-ShellQuote-0.003001
1 distribution installed.

This shows:

  • With x_static_install: configure 0.012sec, install 0.020sec
  • Without x_static_install: configure 0.200sec, install 0.433sec

Simple

People can easily expect the result (eg: which files will be installed, and where).

Safe

There is no place to execute arbitrary code during installation.

The spec of static install

The official spec is here (cpan-static).

Especially at the time of writing, you should note that to make your CPAN module static installable, not only set x_static_install 1 in META.json, but also:

  • Module files must be in lib/ directory
  • Script files must be in script/ directory if any (NOT bin/)
  • No xs file, no PL file (code generation file)
  • Prerequisites must be declared in META.json statically

How to set x_static_install in META.json

If you CPAN author use ExtUtils::MakeMaker or Module::Build manually, then set x_static_install 1 using META_MERGE or meta_merge attributes respectively, so that META.json with x_static_install 1 will be generated.

If you use Dist::Zilla as an authoring tool, then it seems that the easiest way to set x_static_install 1 is to use Dist::Zilla::Plugin::ModuleBuildTiny:

; dist.ini
[ModuleBuildTiny]
static = yes

Especially, if you use Dist::Milla (a Dist::Zilla profile, which defaults to use ModuleBuildTiny as an installer), then:

; dist.ini
[@Milla]
ModuleBuildTiny.static = yes

If you use Minilla v3.0.8+, then:

# minil.toml
[Metadata]
x_static_install = 1

Conclusion

If you set x_static_install 1 in META.json, then some cpan clients (such as cpanm-menlo, cpm) will install your module statically, which is faster and simpler than traditional ways.

Although this static install feature is highly experimental, I must say it is very interesting, and I've already set x_static_install 1 to almost all my modules.

If you are interested too, set x_static_install 1 to your modules, and let's see what happens!

See also

7 Comments

HI! Sounds like interesting idea. Thanks for sharing. Sometimes time required for installation of CPAN modules stuff is critical, so this will be definitely useful feature. Keep me in loop (:

I'd like to support this in cpan(1), but I didn't see a definition for "not complicated" that I'd have to support.

Hi there,

Does this relate to the existing `dynamic_config` flag that I added to `Module::Build` (around 15 years ago!)?

http://search.cpan.org/~leont/Module-Build-0.4220/lib/Module/Build/API.pod

I don't quite understand the relationship between `x_static_install` and `dynamic_config` - for instance, the cpan-static spec only mentions `dynamic_config`, and your post above only mentions `x_static_install`.

If it's the same mechanism, it's great to see this getting some support on the build-tools side!

Leave a comment

About Shoichi Kaji

user-pic I blog about Perl.