I'm working on a CPAN distribution that can work on Win32 and *nix. However, in order for it to work on Win32, it requires another CPAN distribution (module) that can only be installed on Win32.
The problem with this is that, by declaring that module as a dependency, it fails to install on *nix machines. But it will not be really used/required on *nix machines, only when running on Win32.
My distribution uses ExtUtils::MakeMaker
and configures dependencies in the auto-generated hash %WriteMakefileArgs
.
I've tried editing Makefile.PL
to add or remove dependencies based on the OS running it. However, this doesn't really work for the generation of META.json
and META.yml
, which are generated based on the OS where I eventually execute make dist
. If I run it on Windows, then the Win32-only dependencies are added to those files and break the *nix install. If I run it on *nix, then the dependencies are not added and it may break the install on Win32 when the time to test the distribution comes.
Is there a way to define different dependencies for a specific OS, in a way that applications like CPAN
or CPANminus
can successfully work on each OS when installing the distribution?
Don't worry; you are probably already doing everything right.
Yes, the
META.json
will only reflect the dependencies which Makefile.PL detects on your own machine, so say you're building the distribution on Linux and uploading it to CPAN, theMETA.json
on CPAN won't reflect the Windows dependencies.But that's okay, because when people install the distribution, their CPAN client won't use that
META.json
file to install dependencies. It will re-run Makefile.PL on the end user's system, which will generate a file calledMYMETA.json
, which will include the Windows depenencies if they're running it on Windows, and use the dependencies fromMYMETA.json
instead ofMETA.json
.What follows are details for pedantic people, which you probably don't need to worry about:
META.json
includes a section calledconfigure_requires
which lists not the distribution's requirements but the requirements of Makefile.PL itself; sometimes Makefile.PL will do some complex stuff and have its own dependencies. Because these need to be installed before Makefile.PL is run, CPAN clients get the list fromMETA.json
instead ofMYMETA.json
;MYMETA.json
doesn't exist yet."dynamic_config": 0
in META.json which tells the CPAN client that Makefile.PL isn't doing anything "clever", so it can skip running Makefile.PL, use META.json as a definitive list of dependencies, and guess where to install any included modules and scripts. Not all CPAN clients support this, so many will run Makefile.PL anyway; so you still need to include Makefile.PL. It can just make installation a slight bit faster for those clients which support it.