How to install local tar file dependencies together with dependencies from CPAN? - perl

Let's assume there is a distribution "Example" that is packed in example-1.0.tar.gz which contains a Makefile.PL that points to all dependencies. After extracting, "Example" could be easily installed (including all its dependencies) by calling cpanm . if all its dependencies were available on CPAN.
How do I install a simialar file (let's call it example-2.0.tar.gz) if I am given a folder "deps" containing most of the distribution's dependencies
dependency-1.tar.gz
dependency-2.tar.gz
...
dependency-N.tar.gz
where N is a huge number?
Further assumptions are:
dependency-*tar.gz files have to be preferred over the available CPAN modules
some dependencies are not available on CPAN but only in this "deps" folder
the folder "deps" is incomplete and further dependencies have to be installed from CPAN.
Is there a simple way to install example-2.0.tar.gz?
I would like to know if there is some command line like cpanm --use-local-deps=~/deps example-2.0.tar.gz which does not need further workarounds.

You could use this tool http://search.cpan.org/~bingos/CPANPLUS-0.9152/bin/cpan2dist . It lets you specify filters to define what modules are loaded locally and what is fetched from CPAN. It's part of the CPANPLUS module, which should cone with newer versions of Perl I think.

Related

Installing Cairo, Helm on Windows

How do I install Helm (https://hackage.haskell.org/package/helm) on Windows 7 (64-bit)?
(Update: I had posted a lot of error messages here, but I've moved them to my answer to not clutter up the question.)
Installation for Windows 64-bit:
I'm including error messages, for if you follow all the steps up to that point and then just try to install directly. This is a conglomeration of a bunch of ad-hoc steps from following many different posts. Any simplification would be appreciated!
Note: Do all work in directories without spaces. I'm doing all work in C:/PF; modify this to your directory.
Download MSYS2-x86_64 from https://msys2.github.io/ and install it. Cabal install cairo (or helm) will give something like:
Configuring cairo-0.13.1.0...
setup.exe: Missing dependencies on foreign libraries:
Missing C libraries: z, cairo, z, gobject-2.0, ffi, pixman-1, fontconfig,
expat, freetype, iconv, expat, freetype, z, bz2, harfbuzz, glib-2.0, intl,
ws2_32, ole32, winmm, shlwapi, intl, png16, z
Download C libraries. In MINGW64 (NOT MSYS2 - I had trouble with MSYS2 at random stages in the process), use the package manager:
pacman -Ss cairo
to search for the Cairo package. You'll find "mingw64/mingw-w64-x86_64-cairo", so install that:
pacman -S mingw64/mingw-w64-x86_64-cairo
*.pc files should have been added to C:\PF\msys64\mingw64\lib\pkgconfig and C:\PF\msys64\usr\lib\pkgconfig. (pkg-config needs to be able to find these files. It looks in PKG_CONFIG_PATH, which by default should have the lib/pkgconfig folder above. Moving the file here is easiest. See Can't install sdl2 via cabal) If you get
The pkg-config package ... version ... cannot be found
errors then check your *.pc files.
Repeat with other required libraries, like atk
pacman -S mingw64/mingw-w64-x86_64-atk
(I don't know the complete list, but error messages later on will let you know what to get.)
Get the development files for these libraries (as suggested by How to install cairo on Windows). Most of them are bundled up at http://ftp.gnome.org/pub/gnome/binaries/win64/gtk+/2.22/. Unzip.
Copy files (.a, .dll.a) in lib to C:\PF\msys64\mingw64\lib. Copy the pkgconfig folder, which contains the .pc files.
Copy files in include to C:\PF\msys64\mingw64\include.
Add C:\PF\gtk+-2.22.1\bin to the path.
(2) and (3) might be redundant. I don't know - I did them both.
At this point you can probably do "cabal install cairo". (Warning: if your end goal is something else, you may not want to "cabal install" intermediate packages, see https://wiki.haskell.org/Cabal/Survival#Issue_.232_--_Not_installing_all_the_packages_in_one_go.)
See (4) for the syntax in specifying extra-include-dirs and extra-lib-dirs (but if you copied the files above this shouldn't be necessary),
Any time you get
Missing (or bad) header file
check to see you copied the *.h files to mingw64\include and/or add the include folder to the PATH. Use cabal install -v3 to get verbose error messages if the problem persists.
If you get something like
cairo-0.13.1.0: include-dirs: /mingw64/include/freetype2 is a relative path
which makes no sense (as there is nothing for it to be relative to). You can
make paths relative to the package database itself by using ${pkgroot}. (use
--force to override)
try --ghc-pkg-options="--force" (as mentioned at https://github.com/gtk2hs/gtk2hs/issues/139).
Get SDL. Otherwise you'll get
configure: error: *** SDL not found! Get SDL from www.libsdl.org.
If you already installed it, check it's in the path. If problem remains,
please send a mail to the address that appears in ./configure --version
indicating your platform, the version of configure script and the problem.
Failed to install SDL-0.6.5.1
Follow the instructions in (2) to get sdl/sdl2 libraries. (See instructions here Installing SDL on Windows for Haskell (GHC).)
The new version helm-0.7.1 requires sdl2, but there are other dependency issues with helm-0.7.1 as of writing. Download SDL from http://sourceforge.net/projects/msys2/files/REPOS/MINGW/x86_64/ (direct download link to newest version as of writing http://sourceforge.net/projects/msys2/files/REPOS/MINGW/x86_64/mingw-w64-x86_64-SDL-1.2.15-7-any.pkg.tar.xz.sig/download), unzip. "cabal install sdl" gives
* Missing (or bad) header file: SDL/SDL.h
* Missing C library: SDL
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.
so we specify where the dirs are (change the name depending on where you extracted sdl to)
cabal install sdl --extra-include-dirs=C:/PF/sdl\include --extra-lib-dirs=C:/sdl/lib
If you got SDL2 (http://libsdl.org/download-2.0.php) (for a newer version of Helm): there is a fatal bug that hasn't been fixed in the release version. (If you don't fix it, cabal install -v3 things which depends on it will give error
winapifamily.h: No such file or directory
("winapifamily.h: No such file or directory" when compiling SDL in Code::Blocks) Download https://hg.libsdl.org/SDL/raw-file/e217ed463f25/include/SDL_platform.h, replace the file in the include folder and in C:/PF/msys64/mingw64/include/SDL2.
Download gtk2hs from http://code.haskell.org/gtk2hs and run
the following
cd gtk2hs/tools
cabal install
cd ../glib
cabal install
cd ../gio
cabal install
cd ../pango
cabal install --ghc-pkg-options="--force"
(Maybe you have already installed glib and gio from before? I did this step because normal install of Pango caused an error for me (https://github.com/gtk2hs/gtk2hs/issues/110)
pango-0.13.1.0: include-dirs: /mingw64/include/freetype2 is a relative path
which makes no sense (as there is nothing for it to be relative to). You can
make paths relative to the package database itself by using ${pkgroot}. (use
--force to override)
Once the Helm developers get things updated you should be able to do "cabal install helm" but right now there seem to be dependency issues. For me, cabal automatically tries to install helm-0.4 (probably because 0.4 didn't give upper bounds on dependencies, while newer versions do. You could try "cabal unpack"ing and deleting the upper bounds...). Then
cabal unpack helm-0.4
Installing gives an error because "pure" got moved to Prelude. Open helm-0.4\src\FRP\Helm\Automaton.hs and change line 17:
import Prelude hiding (id, (.), pure)
Now
cabal install
Try to compile and run a program using Helm
(This is 0.4 - look on the website for a newer sample if you tried a newer Helm)
import FRP.Helm
import qualified FRP.Helm.Window as Window
render :: (Int, Int) -> Element
render (w, h) = collage w h [filled red $ rect (fromIntegral w) (fromIntegral h)]
main :: IO ()
main = run $ fmap (fmap render) Window.dimensions
If you get an error about a missing .dll (sdl.dll), find it in a bin/ folder and add the folder to your PATH (or copy it to somewhere on your path).

CPAN installing modules into perl5 instead of site_perl

I'm trying to do a temporary install of some cpan modules into a custom folder (/tmp/perl). So I have amending the build install base with...
o conf mbuildpl_arg "--install_base /tmp/perl"
o conf makepl_arg "INSTALL_BASE=/tmp/perl"
Which works fine, the modules get installed into that directory now. I also set PERL5LIB with
PERL5LIB=/tmp/perl/lib/5.14.2/:/tmp/perl/lib/site_perl/:/opt/perl/lib/5.14.2/:/opt/perl/lib/site_perl/:
Note, this is all just temporary, on a virtual server which will be destroyed.
I note that, previously it would install modules into buildpath/lib/5.14.2 or buildpath/lib/site_perl
However now, its installing modules into buildpath/lib/perl5
My understanding was that core perl modules ended up in buildpath/lib/5.14.2 and non-core modules ended up in buildpath/lib/site_perl.
As this is installing into buildpath/lib/perl5, what decides to install into the perl5 directory as opposed to 5.14.2 or site_perl ?
Unless you override ExtUtils::MakeMaker and Module::Build through environment variables (i.e. values in PERL_MM_OPT and PERL_MB_OPT) or command line arguments (e.g. values in cpan's mbuildpl_arg and makepl_arg), locations hardcoded into Perl when it was built will be used. The following command will show you those locations (for .pm and associated files):
perl -V:'install(privlib|archlib|vendorlib|vendorarch|sitelib|sitearch)'
installprivlib contains the "pure Perl" modules that came with Perl.
installarchlib is the same for modules with arch- or build-dependent components.
installvendorlib contains the "pure Perl" modules installed by your distro.
installvendorarch is the same for modules with arch- or build-dependent components.
installsitelib contains the "pure Perl" modules installed by you.
installsitearch is the same for modules with arch- or build-dependent components.
Example runs:
$ perl -V:'install(privlib|archlib|vendorlib|vendorarch|sitelib|sitearch)'
installprivlib='/usr/share/perl/5.14';
installarchlib='/usr/lib/perl/5.14';
installvendorlib='/usr/share/perl5';
installvendorarch='/usr/lib/perl5';
installsitelib='/usr/local/share/perl/5.14.2';
installsitearch='/usr/local/lib/perl/5.14.2';
$ perl -V:'install(privlib|archlib|vendorlib|vendorarch|sitelib|sitearch)'
installprivlib='/home/ikegami/usr/perlbrew/perls/5.20.1t/lib/5.20.1';
installarchlib='/home/ikegami/usr/perlbrew/perls/5.20.1t/lib/5.20.1/x86_64-linux-thread-multi';
installvendorlib='';
installvendorarch='';
installsitelib='/home/ikegami/usr/perlbrew/perls/5.20.1t/lib/site_perl/5.20.1';
installsitearch='/home/ikegami/usr/perlbrew/perls/5.20.1t/lib/site_perl/5.20.1/x86_64-linux-thread-multi';
>perl -V:"install(privlib|archlib|vendorlib|vendorarch|sitelib|sitearch)"
installprivlib='C:\progs\sp5280-x64\perl\lib';
installarchlib='C:\progs\sp5280-x64\perl\lib';
installvendorlib='C:\progs\sp5280-x64\perl\vendor\lib';
installvendorarch='C:\progs\sp5280-x64\perl\vendor\lib';
installsitelib='C:\progs\sp5280-x64\perl\site\lib';
installsitearch='C:\progs\sp5280-x64\perl\site\lib';
There is no answer posted here. I have the same problem. cpan and cpanm installs are going into (using X to shorten paths):
/X/lib/perl5
but that path is not in #INC:
perl -V
#INC:
/X/lib/perl5/5.22.0/x86_64-linux-thread-multi
/X/lib/perl5/5.22.0
/X/lib/perl5/site_perl/5.22.0/x86_64-linux-thread-multi
/X/lib/perl5/site_perl/5.22.0
/X/lib/perl5/site_perl/5.22.0/x86_64-linux-thread-multi
/X/lib/perl5/site_perl/5.22.0
/X/lib/perl5/site_perl
/X/lib/perl5/site_perl/5.22.0/x86_64-linux-thread-multi
/X/lib/perl5/site_perl/5.22.0
/X/lib/perl5/5.22.0/x86_64-linux-thread-multi
/X/lib/perl5/5.22.0
PERL_MM_OPT and PERL_MB_OPT have the following values, which do not appear to be incorrect:
PERL_MB_OPT="--install_base /X"
PERL_MM_OPT="INSTALL_BASE=/X"
I have Perl installed within a conda environment. I suspect the problem is that CPAN and CPANM are making improper assumptions about the subdirectory structure underneath the paths contained in PERL_MB_OPT and PERL_MM_OPT.

Defining required packages and versions for a perl project

I am familiar with using package.json with node.js, Gemfile for Ruby, Podfile for Objective-C, et al.
What is the equivalent file for Perl and what is the syntax used?
I've installed a couple packages using cpanm and would like to save the package names and version in a single file that can be executed by team members.
For simple use cases, writing a cpanfile is a good choice. A sample file might look like
requires 'Marpa::R2', '2.078';
requires 'String::Escape', '2010.002';
requires 'Moo', '1.003001';
requires 'Eval::Closure', '0.11';
on test => sub {
requires 'Test::More', '0.98';
};
That is, it's actually a Perl script, not a data format. The dependencies can then be installed like
$ cd /path/to/your/module
$ cpanm --installdeps .
This does not install your module! But it makes sure that all dependencies are satisfied, so we can do:
use lib '/path/to/your-module/lib'; # add the location as a module search root
use Your::Module; # works! yay
This is usually sufficient e.g. for a git repository which you want others to tinker with.
If you want to create a tarball that can be distributed and installed easily, I'd recommend Dist::Zilla (although it's geared towards CPAN releases). Instead of a cpanfile we use a dist.ini:
name = Your-Module
version = 1.2.3
author = Your Self <you#example.com>
license = GPL_3
copyright_holder = Your Self
[#Basic]
[Prereqs]
Marpa::R2 = 2.078
String::Escape = 2010.002
Moo = 1.003001
Eval::Closure = 0.11
[Prereqs / TestRequires]
Test::More = 0.98
Then:
$ dzil test # sanity checks, and runs your tests
$ dzil build # creates a tarball
Dist::Zilla takes care of creating a Makefile.PL and other infrastructure that is needed to install the module.
You can then distribute that tarball, and install it like cpanm Your-Module-1.2.3.tar.gz. Dependencies are resolved, your packages are copied to a permanent location, and you can now use Your::Module in any script without having to specify the location.
Note that you should adhere to the standard directory layout for Perl modules:
./
lib/
Your/
Module.pm # package Your::Module
Module/
Helper.pm # package Your::Module::Helper
t/ # tests to verify the module works on the target syste,
foo.t
bar.t
xt/ # optional: Author tests that are not run on installation
baz.t
bin/ # optional: scripts that will later end up in the target system's $PATH
command-line-tool
Makefile.PL usually (along with a few other files; Perl has had packages for longer then any of the other languages you mention and suffers from a bit of inelegance here).
Module Starter is a sensible way to start writing a package. It has a getting started guide.

Building perl module gives metafile error

I'm working on installing a perl module (not using CPAN) on a Linux machine. When I run the command:
perl Build.PL
I get the following error:
ERROR: Missing required field 'dist_abstract' for metafile
Could not get valid metadata. Error is: Invalid metadata structure.
Errors: Missing mandatory field, 'abstract' (abstract) [Validation: 1.4],
value is an undefined string (abstract) [Validation: 1.4]
at /usr/local/share/perl5/Module/Build/Base.pm line 4559
Could not create MYMETA files
I've tried Googling bits and pieces of this error but haven't found any solutions. Just looking for a clue as to what might be causing this error.
Here's a link to a zip file containing the files required to install it:
https://oncourse.iu.edu/access/content/user/brilewis/Filemanager_Public_Files/DataDownloader.zip
First at all please make sure you have package Module::Build installed.
You need ungzip few gzipped files in this package. I don't realize why author gzipped them:
gzip -d *.gz
I really don't know why author archived each install file. It looks like some mistake to me.
Than you can install all dependencies (this module requires some):
./Build installdeps
And then finally install module itself:
./Build
./Build test
./Build install
However I must warn you that this module packaged in a bit strange way and there's no guarantee it works.
The NAME section of the module does not have a - in it, e.g.,
=head1 NAME
Foo::Bar implements a Foo framework.
will fail, but if you make it
=head1 NAME
Foo::Bar - implements a Foo framework.
then it will work.
Do you have root access on your machine? Can you use the cpan utility to build and install your module. Using cpan is fairly straight forward:
$ cpan
After that, it will do a lot of configuration, simply take the default values. When it finishes, it'll come to a cpan> prompt. All you have to do there is type this:
cpan> install Module::Name
Where Module::Name is the module you're trying to install. Check the CPAN archive to get the name of your module.
If there are any dependencies, CPAN will ask if you want to download and install those. Say Yes, and CPAN will install the dependencies, then your module.
Using cpan is the best way to install third party modules you find in the CPAN archive. It takes care of all the dependencies, testing, and building for you.
Try installing through CPAN, and then see if you still have your issues.

How can I safely compile a Perl 5.12 module for Perl 5.8.9?

I want to install File::Fetch, which is a core module in Perl 5.12, in my Perl 5.8.9. In general, I want to compile and install future-dated modules in my back-dated Perl because I cannot upgrade my Perl.
So I downloaded the module and also its dependencies. It's quite painful following the dependency tree but I'm more concerned about the fact that some of them are core modules. If I install these, my Perl 5.8.9 core will have patches from 5.12.
My question is how I can know whether I can safely install the future-dated modules, especially the core modules. Is there a tutorial for this purpose of testing backwardcompatability in Perl?
EDIT:
My module is dual lifed, but I cannot compile it using cpan. It said my FTPsite.yaml has a bad element. However, I followed the dependencies in the modules' META files, and I could compiled the module. Is this one of the odd bits with cpan? Thank you.
I cannot recreate the issue after I installed all those dependencies manually. But here is the error:
cpan[5]> install File::Fetch
Running install for module 'File::Fetch'
Running make for B/BI/BINGOS/File-Fetch-0.24.tar.gz
CPAN: Digest::SHA loaded ok (v5.48)
CPAN: Time::HiRes loaded ok (v1.9715)
CPAN: YAML loaded ok (v0.72)
Alert: While trying to 'parse' YAML file
'/Users/martin/.cpan/FTPstats.yml'
with 'YAML' the following error was encountered:
YAML Error: Invalid element in map
Code: YAML_LOAD_ERR_BAD_MAP_ELEMENT
Line: 3
Document: 1
at /opt/local/lib/perl5/site_perl/5.8.9/YAML.pm line 36
If the module is available separately (i.e. "dual-lifed"), as both a standalone distribution and inside core Perl, then the standalone version is safe to install on an earlier Perl, assuming its Makefile allows it. That is, if you can do cpan <Module> and it builds and tests without errors, then you are good.
The only problem is if a module is not dual-lifed, which I opined about in this question -- which is where you are likely S.O.L.
If a perl core module is also available separately, that means that it is intended to work on older perls (unless it explicitly requires some version of perl), and if it doesn't, that's a bug.
That said, 5.10 was released almost three years ago, and you are going to start seeing more and more problems using newer modules with older versions of perl.
cpan or cpanplus will handle dependencies for you.