I have a module Term:TermKey, which is in a file TermKey.pm. I don't want to install it into my perl; I want it to be referenced locally so that the script can be moved to other machines without messing about with each perl installation. How do I do this? None of the recommendations I have seen online works. I always get some form of:
Can't locate loadable object for module Term::TermKey in #INC (#INC contains: /home/fritz/multi.kodis/Term /etc/perl /usr/local/lib/perl/5.18.2 /usr/local/share/perl/5.18.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.18 /usr/share/perl/5.18 /usr/local/lib/site_perl .) at test.pl line 6.
Compilation failed in require at test.pl line 6.
BEGIN failed--compilation aborted at test.pl line 6.
To test this. I placed copies of TermKey.pm in all of:
./TermKey.pm
./Term/TermKey.pm
./Term/Term/TermKey.pm
(just as a test)
Yet it doesn't work for any of:
use lib '';
use Term::TermKey;
use lib '.';
use Term::TermKey;
use lib './';
use Term::TermKey;
use lib './Term';
use Term::TermKey;
use lib './Term/';
use Term::TermKey;
use lib '/home/[user]/[project]'
use Term::TermKey;
use lib '/home/[user]/[project]/Term'
use Term::TermKey;
use FindBin;
use lib "$FindBin::RealBin";
use Term::TermKey;
What the heck? This should be easy, what am I missing?
"Can't locate loadable object for module" does not mean that Perl can't find Term/TermKey.pm. It means that it can't find Term/TermKey.so (or whatever shared libraries are called on your platform).
Term::TermKey is not a pure-Perl module. Instead, it includes XS code, which needs to be compiled into C and then into a shared library. Also, that library links to libtermkey, which must also be installed on your system.
This makes it much harder to move the module from system to system. An XS module compiled for Perl 5.18.2 won't work with 5.20.0; it has to be recompiled. You can upgrade minor releases (like from 5.18.0 to 5.18.2) without having to recompile, although going the other direction (from 5.18.2 to 5.18.0) isn't guaranteed to work.
So, you might be able to get this to work if all the machines are running the same version of Perl on the same OS with the same libraries installed. The easiest way (if it works at all) would be to install cpanm and local::lib and do something like:
cpanm --local-lib some-dir Term::TermKey
Then you could copy some-dir to another machine (with the caveats listed above). It isn't necessary to install local::lib on the other machines; you can just
use lib 'some-dir/lib/perl5';
Related
When I run my perl program, i get the error, i have tried googling it, but i could not find a definitive easy to solve answer
C:\Users\mte>C:\Users\mte\Desktop\org11.pl
Can't locate org2.pm in #INC (you may need to install the org2 module) (#INC con
tains: C:/Perl64/site/lib C:/Perl64/lib .) at C:\Users\mte\Desktop\org11.pl line
2.
BEGIN failed--compilation aborted at C:\Users\mte\Desktop\org11.pl line 2.
the beginning of my code looks like this
use warnings;
use org22;
Either your perl path is incorrect/lacking, or the org22 module is not installed. Take a look at this post for more information on constructing an #INC. Make sure that the org22 module is installed (and if it isn't, that's likely the cause of this error.)
Edit:
If your module is not in #INC (the standard perl include path), and assuming that your module (for example) is located at C:\Some\Path\MyModule.pm, then:
use lib 'C:\Some\Path';
use MyModule;
# Rest of your code
You also may consider using a shebang line as the 1st line in your script:
#!/bin/perl
or
#!/usr/bin/env perl
This will help ensure a consistent experience based on which perl interpreter you are using, given updates, installations of other programs, etc.
I would like to deploy my Perl application to several remote servers. My perl application consists of one big program, using non-core modules : Path::Iterator::Rule, XML::Writer, and two home-made modules.
I would like to be able to deploy my application on a remote server whithout having to copy one by one all of the modules my program uses, with all their dependencies.
I had a look at PAR, which could help with what I'd like to do.
I need to create an archive ("modules.par") where I put my homemade modules, and I add Path::Iterator::Rule, XML::Writer modules ? But how can I be sure that all the dependencies of those modules are correctly added in my archive ?
I've understood that I need to do something like this in my main application :
use PAR;
use lib "modules.par";
use Path::Iterator::Rule;
use XML::Writer;
use HomemadeModule1;
use HomemadeModule2;
Sorry for the confusion, I'm really lost with all those module dependencies, ..
Edit :
So I've tried using cpanm -L extlib to create a directory with all my libraries, but I can't use cpanm on my system.
Now I'm trying to use PAR, I've created a file called "sources.par" in which all of my modules are contained, I used the following command :
pp -p myperlprogram.pl
This created the "sources.par", that I should be able to use in my program using this :
use PAR;
use lib "sources.par";
use XML::Writer;
use ..
But I still get the following message :
Can't locate XML/Writer.pm in #INC (#INC contains: sources.par CODE(0x10c0cc) /app/pro
dexpl/gld/LOA /usr/perl5/5.8.4/lib/sun4-solaris-64int /usr/perl5/5.8.4/lib /usr/
perl5/site_perl/5.8.4/sun4-solaris-64int /usr/perl5/site_perl/5.8.4 /usr/perl5/s
ite_perl /usr/perl5/vendor_perl/5.8.4/sun4-solaris-64int /usr/perl5/vendor_perl/
5.8.4 /usr/perl5/vendor_perl . CODE(0x10c1e0)) at /app/prodexpl/gld/LOA/AnalyseF
ichier.pm line 7.
BEGIN failed--compilation aborted at /app/prodexpl/gld/LOA/AnalyseFichier.pm lin
e 7.
Compilation failed in require at /app/prodexpl/gld/LOA/loganalysis.pl line 9.
BEGIN failed--compilation aborted at /app/prodexpl/gld/LOA/loganalysis.pl line 9
.
Any ideas what I could do ? You can see that #INC contains my sources.par file..
Create a package using either Module::Build or Module::Build::Tiny, and then just install the package on these remote machines. That way you can just specify what the dependencies are, and cpanm can install them as well.
I need to create a custom system-wide perl install on a CentOS machine. I don't want to use perlbrew as I want to alter the config variables myself, plus I get the same linkage problems.
Essentially, I cannot figure out how to compile perl so that /usr/lib64/perl5 is not included by the linker or in #INC. That is the old centos version, and it sucks. No matter how I compile though, perl -V yeilds this:
#INC:
/usr/local/lib64/perl5
/usr/lib64/perl5/vendor_perl
/usr/local/perl5/lib/site_perl/5.16.3/x86_64-linux-thread-multi-ld
/usr/local/perl5/lib/site_perl/5.16.3
/usr/local/perl5/lib/5.16.3/x86_64-linux-thread-multi-ld
/usr/local/perl5/lib/5.16.3
And then when I run, I get insane library errors like this: undefined symbol: Perl_Gthr_key_ptr from libraries inside /usr/lib64/perl5.
Note that PERL5LIB has no effect on this, it is compiled in.
Thanks.
In order to remove a directory from #INC, you can use no lib. For example,
no lib "/usr/lib64/perl5/";
would remove the /usr/lib64/perl5/ directory from #INC.
For more, try perldoc lib.
I need to run a perl script to gather system information that will be deployed and executed on different unix servers.
Right now I am writing it and testing it, and I'm receiving this error.
Can't locate XML/DOM.pm in #INC (#INC contains: /usr/local/lib64/perl5
/usr/local/share/perl5 /usr/lib64/perl5/vendor_perl
/usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at
test.pl line 7. BEGIN failed--compilation aborted at test.pl line 7.
So I am simply using XML::DOM which should be part of Perl but it isn't for this version on this particular server which is 5.10.1.
Anyways, is there a way I can create and design my script and package modules into it while keeping the .pl extension, which is the requirement for this script?
If the modules don't require compiled libraries, you can include them by copying the text out of the module into your .pl file. That's a horrible hack but it should work.
Perl modules should contain a package statement that gives them their name. When you get to your main program section you'll need a package main; statement of your own.
You can put the modules in any directory, and then include this directory to be included in the search for modules via the lib pragma. Be aware that a module Foo::Bar has to be in the file MY-ROOT/Foo/Bar.pm and may not be in MY-ROOT/Bar.pm, where MY-ROOT is your module directory.
use lib 'MY-ROOT';
use Foo::Bar;
However, this only works for pure-Perl modules, and doesn't support XS.
In lieu of using the lib pragma as amon suggests, consider installing perlbrew and cpanminus which is designed to work hand-in-hand to add and/or update modules.
perlbrew is designed to be leveraged by specifying #!/usr/bin/env perl as the interpreter line in your Perl scripts while adding a line like source ~/perl5/perlbrew/etc/bashrc to your ${HOME}/.bash_profile to locate the local version of Perl you want.
How can I set where Perl looks for modules in Apache httpd.conf file on OSX?
I've installed several modules via CPAN, which were installed successfully in
/opt/local/lib/perl5/site_perl/5.8.9
I can verify this via perldoc perllocal
If I run perl -V on the command line, I get (among other dirs):
#INC:
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level
/opt/local/lib/perl5/site_perl/5.8.9
When I run a perl script as CGI via Apache, however, I get errors that the modules I'm useing can not be found. The list of dirs being included in #INC do not match my local perl configuration.
[error] [client 127.0.0.1] Can't locate Spreadsheet/ParseExcel.pm in #INC (
#INC contains:
/Library/Perl/Updates/5.8.8
/System/Library/Perl/5.8.8/darwin-thread-multi-2level
/System/Library/Perl/5.8.8
/Library/Perl/5.8.8/darwin-thread-multi-2level
/Library/Perl/5.8.8
/Library/Perl
/Network/Library/Perl/5.8.8/darwin-thread-multi-2level
...
How is #INC getting set when running perl as CGI on OSX - and how do I override it?
The initial value of #INC is hardcoded when perl is built, but it can be modified in a number of ways. The most convenient here are
SetEnv PERL5LIB ...
from within the Apache configuration, or using
use lib qw( ... );
from within the Perl script.
That said, it's not safe to use modules installed using Perl 5.8.9 with Perl 5.8.8 (although the other way around is safe). Even worse, one appears to be a threaded Perl and the other one isn't. Modifying #INC is simply not going to work.
You need to install the module using the same perl as the one you intend to use to run the script, or you must run the script using the same perl as the one used to install the module.