--- name: When an install goes wrong --- ```{index} single: CPAN; troubleshooting ``` # When an install goes wrong Symptoms first, since that is what you have when you arrive here. ```{index} single: Can't locate ... in @INC single: architecture directory; install pinning single: INSTALLARCHLIB single: ExtUtils::MakeMaker; architecture directory ``` ## "Can't locate Foo/Bar.pm" after a successful install The install said it worked, and the module is not there. Two causes. **You have not set `PPERL5LIB`.** An install does not put itself on the search path. Check that the tree is where you think it is: ```bash ls ~/.pperl/lib/perl5 export PPERL5LIB="$HOME/.pperl/lib/perl5" ``` **The module went into an architecture directory.** This is the subtle one. `ExtUtils::MakeMaker` sends everything from a distribution that *declares* XS into `lib/perl5//`, even when what it actually installs is pure Perl. pperl searches no architecture directory, so the module lands somewhere pperl will never look. `WWW::Form::UrlEncoded` installed "successfully" this way, and then `Plack::Request->parameters` died with `Can't locate WWW/Form/UrlEncoded.pm`. `pperl --cpan` prevents this: it pins `INSTALLARCHLIB`, `INSTALLSITEARCH` and `INSTALLVENDORARCH` to the plain lib tree for both toolchains, so nothing can be installed into an architecture directory. If you are driving an installer yourself, you need to do the same, or check afterwards: ```bash find ~/.pperl/lib/perl5 -maxdepth 1 -type d ``` Anything other than package directories is a sign the pinning did not happen. ```{index} single: Config::lib_file; troubleshooting ``` ## The installer wants to build a module pperl already has Confirm what pperl thinks it provides, and at which version: ```bash pperl -MConfig -MExtUtils::MakeMaker -e \ 'my $f = Config::lib_file("Storable.pm"); print "$f ", MM->parse_version($f), "\n"' # ./pperl-native/Storable.pm 3.41 ``` If the path starts with `./pperl-native/` the module is built in. If the installer still wants it, compare the versions: the dependency may genuinely be newer than the version pperl carries, in which case no arrangement will satisfy it. An installer that is not pperl's own, run under pperl, looks for modules with file tests and does not see the built-in ones. Use `pperl --cpan`. ```{index} single: dynamic loading not available in this perl ``` ## "dynamic loading not available in this perl" XS. Read [the no-XS rule](no-xs) to work out which shape the distribution is, because shapes 2 and 3 there have a way forward and shapes 4 and 5 do not. The message appearing at *runtime* rather than install time is usually good news: it means the module caught it and is choosing its Perl implementation. ## The install hangs waiting for input It should not - under `--cpan`, `PERL_MM_USE_DEFAULT` and `NONINTERACTIVE_TESTING` are both set, so distributions take their own defaults. If you are driving an installer yourself, set both. ```{index} single: --cpan; -T single: --cpan; skipping tests ``` ## Tests fail but the module is fine `-T` goes straight through to the CPAN client and skips the tests: ```bash pperl --cpan -T Some::Module ``` Worth doing once to find out whether the module or its test suite is the problem. A test suite that itself depends on XS will fail against a perfectly good pure-Perl module. ## Starting over The tree is disposable. Nothing else refers to it: ```bash rm -rf ~/.pperl pperl --cpan Your::Module ``` ## Reporting If a pure-Perl distribution fails to install, or installs and then cannot be loaded, that is a pperl bug and worth filing: Include the distribution name and version, the full `--cpan` output, and `pperl -e 'print "$_\n" for @INC'`.