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
- The spec of static install: Leont/cpan-static
- Menlo pull request: miyagawa/cpanminus/pull/467
- cpm pull request: skaji/cpm/pull/68
x_static_install
at grep.cpan.me
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.
@brian d foy
> I'd like to support this in cpan(1)
It's awesome, I'd love to see it!
> I didn't see a definition for "not complicated" that I'd have to support.
Yeah, it is true that we may not say that the spec defines static installable CPAN distributions clearly.
For the time being, I think you can refer to a static builder in Menlo (and github PR). If you have any problems or concerns, let's discuss them in IRC or github issue/PR with toolchain members (especially leont and miyagawa), and improve the spec itself.
I compared the elapsed time for installation of Plack in
https://gist.github.com/skaji/24de4a819ca4a84b2018f5ee996ac52a
Then
* Non-static-install took 28sec
* Static-install took 9sec
That is, static-install is 3x faster. Wow!
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!
Hi Ken, thanks for your comment.
> Does this relate to the existing `dynamic_config` flag that I added to `Module::Build` (around 15 years ago!)?
CPAN::Meta::History::Meta_1_4 says:
dynamic_config:
A boolean flag indicating whether a Build.PL or Makefile.PL (or similar) must be executed when building this distribution, or whether it can be built, tested and installed solely from consulting its metadata file.
On the other hand, current CPAN::Meta::Spec says:
dynamic_config:
A boolean flag indicating whether a Build.PL or Makefile.PL (or similar) must be executed to determine prerequisites.
So it seems that the meaning of dynamic_config has changed, perhaps according to actual uses.
You can refer to miyagawa/cpanminus/pull/467 for why a current static-install implementation in Menlo does not treat dynamic_config as static-install.
Again, I don't think the spec of static-install is fixed, and let's improve the spec and implementation together.
ether pointed out in IRC that Dist::Zilla::Plugin::StaticInstall checked more criteria for the static install. You can use it by: