I just purchased a commercial perl shared object that is really light on its documentation. Specifically it's an ".so" file and I know that it needs to go into whatever directory perl is using to find shared objects.
Normally I encounter ".pm" files and know how to install those with no problem, but this is the first time I have ever used something in perl where I had to install a ".so" file, or copy it to a directory.
Anyone know how I would find this directory? It's at a level of Perl's sausage making which I'm not familiar with (plus I'm a bacon gal anyway. LOL!).
Janie
Update: (for more clarity). The company that sold this has the file named as "hcmodule.so". Their example perl script has a use pragma in it of "use hcmodule" and a call later as..
$retval = hcmodule( ........ <SNIP>..);
If this helps unmurky things a bit.
Perl loads shared objects from directories under its lib directory. In some installations of Perl, that will be the lib directory parallel to the bin directory where the main Perl binary is found. In some systems, it will be located elsewhere. For example, my own build of Perl (5.14.1 on MacOS X) says (part of output from perl -V):
#INC
/Users/jleffler/Perl/v5.14.1-64/lib/perl5/site_perl/5.14.1/darwin-2level
/Users/jleffler/Perl/v5.14.1-64/lib/perl5/site_perl/5.14.1
/Users/jleffler/Perl/v5.14.1-64/lib/perl5/5.14.1/darwin-2level
/Users/jleffler/Perl/v5.14.1-64/lib/perl5/5.14.1
On the other hand, the system Perl (5.12.3) says:
#INC:
/Library/Perl/5.12/darwin-thread-multi-2level
/Library/Perl/5.12
/Network/Library/Perl/5.12/darwin-thread-multi-2level
/Network/Library/Perl/5.12
/Library/Perl/Updates/5.12.3
/System/Library/Perl/5.12/darwin-thread-multi-2level
/System/Library/Perl/5.12
/System/Library/Perl/Extras/5.12/darwin-thread-multi-2level
/System/Library/Perl/Extras/5.12
The shared objects on MacOS X have a .bundle extension (instead of .so), and some of the bundles I have are:
.../lib/perl5/site_perl/5.14.1/darwin-2level/auto/DBD/Informix/Informix.bundle
.../lib/perl5/site_perl/5.14.1/darwin-2level/auto/DBD/SQLite/SQLite.bundle
.../lib/perl5/site_perl/5.14.1/darwin-2level/auto/DBI/DBI.bundle
The corresponding PM files are:
.../lib/perl5/site_perl/5.14.1/darwin-2level/DBD/Informix.pm
.../lib/perl5/site_perl/5.14.1/darwin-2level/DBD/SQLite.pm
.../lib/perl5/site_perl/5.14.1/darwin-2level/DBI.pm
In any case, Perl will expect to look for the .so file in a directory related to the name of the module. There should be install instructions, especially since you paid for it. There will be (at least) a shared object and a .pm file to be installed, in two related related directories.
Have you tried perl -V to see if it has the information you want? Do you have the environment variable LD_LIBRARY_PATH set?
I'm on Linux, and doing perl -V (uppercase V) showed that Perl libraries are in /usr/lib/perl/5.10 and a few other libraries.
Exactly what Perl *.so file did you purchase? I've never heard of someone selling Perl shared libraries.
Related
Perl newbie here with very little time and support to learn Perl but all the expectations from management to use it like a Perl Pro :)
I am using Perl (v5.30.2 by Larry Wall) under Cygwin (windows 10)
My developer issued a new script, that now uses a Perl module I didn't have.
They then sent me the .pm file (which they authored themselves and it is not on any online Perl repo).
I was unable to use CPAN to install that file into my Perl execution environment.
Where should the .pm file be saved at? (please specify the exact folder)
How to tell CPAN to install this file for usage? Ideally, a one-time affair, as I don't want to forget installing this file, if I have to do that every time I need to run the Perl script...
Just in case there may be any security concern from the dear answer-ers: There isn't any security concern here, this is all under an environment that has no connection to the internet.
A Perl module is just a file (or collection of files). You don't have to put them anywhere special, but you need to tell Perl where to find them.
When you call use or require with a bareword, Perl translates that module name, like Some::Module, into Some/Module.pm (or whatever is appropriate for your system. Anyone still using VMS?).
Once it has the filename form of the module, it looks for that subpath in the directories in #INC. It tries the first directory. If it doesn't find it it moves on to the next, and so on down the line. These directories are decided when someone configures and installs Perl. And, before v5.26, it included the current working directory (see v5.26 removes dot from #INC and Doesn't Perl include current directory in #INC by default?
)
But, you can tell Perl where else to look. perlfaq8 has How do I add a directory to my include path (#INC) at runtime?. ikegami also showed FindBin in the comments (How do I add the directory my program lives in to the module/library search path?).
Beyond that, you can tell require to load a path, although you then need to ensure that the program can find that path even if someone runs it from another directory
require './this_file/over/here';
require '/usr/local/lib/this_file/over/here';
I have a Perl app on my development server that I would like to replicate on my local machine (mac osx). I'm not a perl programmer by trade (I'm a PHP/Rails developer), and the developer of this app is no longer around so I can't contact him for help. I've gotten pretty close to getting it to work. I was able to install all the packages using CPAN (at least I think I got them all) but I keep running into the following error:
Can't locate WebCNP/Config.pm in #INC (
#INC contains: /Library/Perl/5.16/darwin-thread-multi-2level
/Library/Perl/5.16
/Network/Library/Perl/5.16/darwin-thread-multi-2level
/Network/Library/Perl/5.16
/Library/Perl/Updates/5.16.2/darwin-thread-multi-2level
/Library/Perl/Updates/5.16.2
/System/Library/Perl/5.16/darwin-thread-multi-2level
/System/Library/Perl/5.16
/System/Library/Perl/Extras/5.16/darwin-thread-multi-2level
/System/Library/Perl/Extras/5.16 .
)
at webcnp_lib.pl line 30.
On the server, the app's file structure looks like this:
/var/www/cgi-bin (empty dir)
/var/www/conf
/var/www/error
/var/www/html (empty dir)
/var/www/icons
/var/www/perl (the config file is located in this directory)
- /WebCNP/Config.pm
/var/www/ssi (all the .pl files for the app are located here, including all the JS and CSS files)
Line 30 of /var/www/ssi/webcnp_lib.pl has the following:
use WebCNP::Config;
Any ideas what I could be doing wrong?
Just so you know I've copied the file structure of the app from my development server to my local machine and created a virtual host so that it points to the app's root directory (/var/www).
Thanks in advanced for any insight!
was able to fix this with a symbolic link
ln -s /path/to/my/app/WebCNP /Library/Perl/5.16/WebCNP
I take this isn't a module from CPAN.
I would be a bit hesitant to use a symbolic link. This will work, but you're basically linking in a file you have under your own control to the master /Library directory on MacOS X. You delete your file, and that link won't be pointing to anything.
You can use use lib to add directories that contain your modules to the #INC directory:
use lib qw(/path/to/my/app);
This will now include this path for module searches.
If you rather install the module itself, why not simply copy it into /Lbrary/Perl/5.16 itself? It's what cpan would have done. At least this way, you're Perl module directory isn't dependent upon a link that can be removed.
/var/www/perl isn't present in #INC, so Perl won't look there. The most common approach to solve this for CGI scripts would be to add the following to your scripts (but not modules):
use FindBin qw( $RealBin );
use lib "$RealBin/../perl";
I was able to fix this with a symbolic link
ln -s /path/to/my/app/WebCNP /Library/Perl/5.16/WebCNP
Not sure if this is the most elegant approach, but seems to work well for this app. Thanks everyone for your replies! This has been very insightful.
Old post, I know, but there is a much more portable way. When you install the modules, you need to do two things.
Add the installation path to PERL5LIB (i.e. PERL5LIB=$PERL5LIB:/My/Module/Path/lib) in your environment configuration (.profile or other files which get read on system initialization)
Add a PREFIX to your perl Makefile.PL call (perl Makefile.PL PREFIX=/My/Module/Path)
It goes without saying that you need to make certain your Makefile.PL is written correctly.
Does Perl look in . (the current directory) for modules?
I can't directly install a module and I think I could copy it into the local directory. Is this true?
perl -V will print out various properties about your Perl installation, including the default #INC. You should notice a . in there: yes, the current working directory is searched for modules by default.
(If not, you can use environment variables PERL5LIB or PERLLIB, or -I on the command line, or add a sitecustomize.pl to perl -V:sitelib.)
In response to Cameron and tchrist's discussion in the comments to ephemient's answer.
You may use this snippet to use modules in the same directory as the script, even if the script is executed while in another directory.
use Cwd 'abs_path';
use File::Basename;
use lib dirname( abs_path $0 );
It should work in all cases and on all OSes. (Source: http://use.perl.org/~Aristotle/journal/33995)
Lately there has been some reason to not rely on . being in #INC more than usual, namely that this default behavior is scheduled to be removed in Perl 5.26. See the development release notes here: https://metacpan.org/pod/release/EXODIST/perl-5.25.7/pod/perldelta.pod#and-INC
It is generally known that this is being done to address vulnerabilities that were noticed in some applications as a result of this behavior. The CVE(s) have not been released publicly (yet).
Perl searches directories in the #INC array when searching for modules.
Please refer to the following Stack Overflow question on how that array is constructed (this would tell you how your current or home directory can be added):
How is Perl's #INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?)
Please refer to the following Stack Overflow question on how Perl finds the actual file for the module:
How does a Perl program know where to find the file containing Perl module it uses?
I think it most likely will by default, as indicated in this post. If your implementation does not do so, the syntax referenced in the initial question on that post will allow you to reference the module you need.
When you unpack the module’s tarball directory, build its Makefile with an optional library argument with the name of whatever personal directory you want the module contents placed in:
$ perl Makefile.PL LIB=~/perllibs
Then make sure you have your ~/perllibs directory included in your $PERL5LIB envariable.
I have a Perl script which uses installed packages. One is a Perl package another one is Perl XS package.
Now I want to call this script but use not installed packages, but packages with the same name by path.
I used perl -I /home/.../lib script.pl but it doesn't work
How can I do it?
For various ways of affecting where your modules are loaded, please review this SO posting:
How is Perl's #INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?)
You can use the lib pragma to prepend directories to the path perl uses to find modules.
So, if there is a module named Foo installed in the default directories and a different version installed in /home/cowens/perl5 you can say
use lib "/home/cowens/perl5";
use Foo;
and perl will find the version in /home/cowens/perl5.
Can you show us a recursive listing of the directory where you're storing the modules you want to use? An ls -R could help us figure out if you have the right paths.
When you use the -I switch, you have to ensure you get the right path in there. If you use a module:
use Some::Module;
Perl actually looks for:
$lib/Some/Module.pm
The $lib is one of the directories in #INC. Another way to say that though, is that if the particular directory is not in #INC, Perl isn't going to look in it. This means that Perl won't automatically look in subdirectories for you
If your module is not at that location, Perl is not going to rummage around in that $lib to look for it. Your XS module is probably not stored like that. It might have a Perl version and archtype in the path, so you might find it in:
$lib/5.10.1/darwin-2level/Some/Module.pm
You need to add those paths yourself if you are using -I.
However, you can load modules on the command line. It's much easier to use lib, which adds the extra directories for you:
perl -Mlib=/path/to/lib ...
I need to run Perl applications I develop on cygwin Windows on HP unix / Solaris hosts. I am not a superuser on the unix machines and I can't touch the default Perl module location nor can I install modules to the default Perl module location. Also the unix installation lacks most basic modules and I can't change that.
For example, I have a Perl application that needs Expect which has native C compiled parts to it. How would I roll out this application to unix with its required dependencies without having to install anything else on that box?
Is there way to build the entire Perl application under Cygwin Windows and then just roll out one executable to unix and run it from my home directory there?
EDIT addition based on answers so far:
Thanks in particular to brian, the local LIB dir solution seems to work in case of native Perl, but in case of Perl module needing C components, cross platform compiling, ie compiling on cygwin to run on Solaris, is not really possible as I feared.
However would having an other linux installation help, i.e. would this be possible easier between different flavors of Unix like package Perl on linux and then deploy to Solaris/HP? And what about something like lcc ?
Also I'd still like to hear little more if somebody has rolled out a native Perl package on Windows that includes all dependencies for a complicated Perl app that can then be moved to unix as just one file? (I do now understand that it won't work in case native C code is included like in in Expect.pm, but what about in case of app only using pure perl modules?)
Basically for many reasons I am trying to minimize time I need to spend being logged into these "production" unix hosts and do as much as possible locally beforehand.
Added a new cross-compile question, since I felt I was maybe veering too far from the original perl question.
EDIT -- Par looks promising for pure Perl, although same deal, it doesn't look to solve the cross platform compile problem for native extensions
In this case, I'd consider delivering a complete application complete with its own Perl. You get to choose any version you like and any modules you like. Compile everything, organize everything into a directory, then tar the result. To deploy, copy the file and untar. Use the advice that others have already noted about library search paths, etc. In essence, your application gets its own stack.
Now, the trick there is the cross compilation. Why are you developing on Cygwin? Is that a target too? Is there a reason you don't have an HP/UX or Solaris development machine? What architecture are you targeting (RISC, SPARC, Intel, etc). If you can't get hardware to run those, get some virtual machines for your targets and develop there.
Aside from that, you can install modules anywhere you have permissions. See perlfaq8:
How do I keep my own module/library directory?
How do I add the directory my program lives in to the module/library search path?
How do I add a directory to my include path (#INC) at runtime?
I haven't tried this particular feature, but perl2exe says it supports cross platform builds.
Compiling a Perl script with all its dependencies on Windows with Cygwin and running it Solaris is just not going to work.
Now the question is: do you have access to a compiler on that Solaris computer? It's not because you do not have root access that you cannot compile and install Perl modules in your home directory by using:
perl Makefile.PL PREFIX=$HOME
If you have CPAN available on your Solaris system you can set the prefix in the CPAN shell this way:
start the shell perl -MCPAN -e shell;
change the prefix with conf makepl_arg PREFIX=/path/to/your/home/directory
For your script to run, you can either start perl with the -I $HOME command-line switch, e.g.:
perl -I $HOME script.pl
Your other option would be to place this at the begining of your script
use lib $ENV{'HOME'};
Set your environment variable PERLLIB to your personnal Perl lib directory or use the -I command line switch to Perl to indicate it.
If you have access to the HP-UX machine you can compile Expect there and install it in your directory. But cross compilation from Windows to HP-UX is probably much more difficult. You would have to build a GCC cross compiler.
If you have a compiler on each of your systems (and some other tools needed by configure like grep), you should not only be able to compile modules, but you should also be able to build your own perl executables.
You'll want local::lib. Once you've done that, the pure Perl modules should work cross platform, but you'll have to identify and reinstall the compiled modules on the foreign platform. Do the initial install on a real unix, cpan on cygwin is slow.
I've run across this several times on my work systems. We have a base install of Perl 5.8 and I don't have the ability to add modules. Here's the solution I use:
Create a folder called 'lib' in your
project root (ex:
~/projects/MyProject/lib)
Any
modules you download from CPAN
should have a Makefile as well as a
directory called "lib". Copy the contents of the lib folder into your newly created lib folder. Some modules may only contain a single .pm file, and no lib structure. Just copy the .pm file.
Your code should do the following: first, use any modules that have been installed normally, then unshift your #INC environment variable to use your local libraries:
# Declare Includes --------------------------------------------------------------------------------
use Getopt::Long;
use vars qw($VERSION);
use DirHandle;
use FileHandle;
# Force perl to use our local 'lib' directory for imported modules, this allows us to
# use modules without having to install them in th emain perl assembly. However, this
#also prevents these modules from being used in other projects.
BEGIN { unshift #INC, "lib"; }
use Error qw(:try);
use SOAP::Transport::HTTP;
#use LWP::Protocol::https;
use XML::Simple;
use XML::Writer;
use XML::Writer::String;
The caveat to this method is that some Perl modules don't use the 'lib' method or have additional dependencies. If you run into problems, examine the Makefile.PL for the module and see what it's doing.