How do I use a vendor Apache with a self-compiled Perl and mod_perl? - perl

I want to use Apple's or RedHat's built-in Apache but I want to use Perl 5.10 and mod_perl. What's the least intrusive way to accomplish this? I want the advantage of free security patching for the vendor's Apache, dav, php, etc., but I care a lot about which version of Perl I use and what's in my #INC path. I don't mind compiling my own mod_perl.

Build your version of Perl 5.10 following any special instructions from the mod_perl documentation. Tell Perl configurator to install in some non-standard place, like /usr/local/perl/5.10.0
Use the instructions to build a shared library (or dynamic, or .so) mod_perl against your distribution's Apache, but make sure you run the Makefile.PL using your version of perl:
/usr/local/perl/5.10.0/bin/perl Makefile.PL APXS=/usr/bin/apxs
Install and configure mod_perl like normal.
It may be helpful, after step one, to change your path so you don't accidentially get confused about which version of Perl you're using:
export PATH=/usr/local/perl/5.10.0/bin:$PATH

You'll want to look into mod_so

I've done this before. It wasn't pretty, but it worked, especially since vendor perl's are usually 2-3 years old.
I started with making my own perl RPM that installed perl into a different location, like /opt/. This was pretty straight forward. I mostly started with this because I didn't want the system utilities that used perl to break when I upgraded/installed new modules. I had to modify all my scripts to specify #!/opt/bin/perl at the top and sometimes I even played with the path to make sure my perl came first.
Next, I grabbed a mod_perl source RPM and modified it to use my /opt/bin/perl instead of /usr/bin/perl. I don't have access to the changes I made, since it was at a different gig. It took me a bit of playing around to get it.
It did work, but I'm not an RPM wizard, so dependency checking didn't work out so well. For example, I could uninstall my custom RPM and break everything. It wasn't a big deal for me, so I moved on.
I was also mixing RPM's with CPAN installs of modules (did I mention we built our own custom CPAN mirror with our own code?). This was a bit fragile too. Again, I didn't have the resources (ie, time) to figure out how to bend cpan2rpm to use my perl and not cause RPM conflicts.
If I had it all to do again, I would make a custom 5.10 perl RPM and just replace the system perl. Then I would use cpan2rpm to create the RPM packages I needed for my software and compile my own mod_perl RPM.

Related

How to Redistribute Non-core Modules in Perl?

I am relatively new to Perl and I need some help with redistributing the non-core modules. Here's the whole story.
There are two non-core modules that were used in the Perl script: XML::Simple and SOAP::Lite. The version that I'm using (currently on Windows) is Strawberry Perl, so these two modules are already included. However, we don't know if the end users (Unix/Linux system) have these two modules as they might only have the standard version and so have only the core modules. My goal is to make the end users do as little configurations/installs as possible.
First, I tried to see if there's any core modules that's similar to XML::Simple and SOAP::Lite. Unfortunately, I didn't find any (Please correct me if I'm wrong).
So I guess now the only option is to redistribute the two modules. I checked and that these two modules allow redistribution. My problem right now is how to do it. I tried googling with keywords "perl redistribute" but didn't find anything useful. My guess is that we use the exporter tool to achieve this. but these two modules are rather complicated modules and they have several nested folders/pm files (and a whole bunch of other files like MAKE, pod, ini files) so I'm not sure what I should do. The examples I found using exporter are rather simple: They only have 1 pm file and 1 pl file and they are placed into one folder.
Also, I'm open to any other better ways to deal with the problem. The goal is just to make sure all end users can use my script with the least configuration/install efforts as we don't want them to run into a whole bunch of compatibility issues.
Any help would be appreciated. Thanks! =D
I want to elaborate a little bit on #ikegami said.
SOAP::Lite has a large number of CPAN dependencies, so the people installing your module are going to need CPAN access to get it to build, whether you provide it for them, or list it as a dependency. Otherwise, you'll need to provide your entire dependency tree, at which point, you end up using perlbrew, maybe carton, possibly local::lib, and then you might decide you need the next higher level and produce RPMs and DEBs.
Probably better to just provide your script, packaged as a CPAN module, list your dependencies within, and let the chips fall where they may.
Just state a dependency on the modules in your Makefile.PL or Build.PL, then give them the following installation instruction:
cpanm script.tar.gz
One of the best things about Perl is The CPAN, the Comprehensive Perl Archive Network. It's a mirroring service that since about the time Perl 5 originally came out has allowed people to share useful add-on modules, like XML::Simple or SOAP::Lite through a standard, common tool, the cpan client that comes with Perl. Almost all Perl distributions (such as Strawberry Perl and most Perl distributions that come with linux) have a CPAN client configured and included with them. This client lets people download and install modules from CPAN simply by knowing the name of the module.
Almost all module distributions on CPAN follow the exact same layout. They usually have a Makefile.PL file (if it uses ExtUtils::MakeMaker to generate the install script), Build.PL file (if it uses Module::Build to generate the install script), or both. These Perl scripts, once run, create a 'Makefile' or a 'Build' file that can let you install the module and verify that all prerequisites are met.
If you've never made a Perl distribution before, you can download any distribution you want from CPAN and take a look at how things are laid out. The folders and file locations are pretty intuitive once you've seen one. They are usually laid out with the install script and supporting files (like a readme) in the root directory, with the custom modules (modules you make) in the lib directory, and with unit tests in the t directory.
I'd recommend looking at the Build.PL based ones if you're a novice; these are pure Perl based install scripts. If you decide to make a Module.PL based distribution, it's really easy to specify that your module distribution needs XML::Simple and SOAP::Lite. First, create a basic Module::Build based install script. This looks something like:
use Module::Build;
my $build = Module::Build->new(
module_name => 'Foo::Bar',
license => 'perl',
requires => {
'perl' => '5.6.1',
'Some::Module' => '1.23',
'Other::Module' => '>= 1.2, != 1.5, < 2.0',
},
);
$build->create_build_script;
(This is taken right from the Module::Build::Authoring docs).
Then, specify the libraries you need and minimum versions of them. Zero (0) is an acceptable version if you don't care, but that means "anything" is good. I'd recommend specifying at least the version of the libraries installed on the machines you're testing with.
(Neat short cut: you can find out the version of any library that has a $VERSION package variable defined by doing:
perl -MSome::Lib -E "say Some::Lib->VERSION()"
.)
To install the module, the steps look something like this:
cd folder\where\my\lib\is
perl Build.PL
Build
Build test
Build install
This will create the install tool, prepare the folder for testing (usually just copying stuff to a build library area for simple modules), run all .t scripts in the t folder (the "tests", which usually use Test::More for unit testing of the module prior to install), and then finally, install your module to your PC's Perl site libraries.
The Build script, as part of the 'setting things up' phase, will look at your prerequisites, and warn you if you don't have them yet.
Then, as pointed out in ikegami's answer, if you use the cpanm client to install your library, the cpan client will automatically go out, download, test, and install your dependencies for you! Alternatively, Build.PL based installers also have the 'installdeps' option, which will do the same thing. Then any and all dependencies (and potentially recursive dependencies) are automatically downloaded, tested, and installed, even if they change in the future.

How compatible is ActivePerl with CPAN modules?

I've done some research and it seems like ActivePerl had issues with earlier releases of it's product with certain CPAN modules not installing properly. However, I'm running the 5.14.x version and I've not had any problems.
According to some quotes I've seen:
ActivePerl is 100% compatible with the reference distribution of Perl.
Code tested with ActivePerl will run on any Perl installation that has the appropriate extensions installed.
I assume that the first statement refers to the standard modules you get with the Perl installation and for the second, I'm not sure what they are saying?
In any event, is there any way to find out how compatible ActivePerl is with the current CPAN modules or is that something that isn't known? I just don't want to spend time with it, only to have to switch to something like Strawberry Perl next month to avoid CPAN module build failures for the more common modules.
If ActivePerl is compatible with say 80% or higher with the CPAN modules I would feel more comfortable about using it, but I couldn't find any information on this.
I doubt a generic statistic will be that useful. In general I would expect all "pure perl" modules should work more or less out of the box. Keep in mind however that certain perl modules really are interfaces to lower level linux/unix style shared libraries (dlls in Windows terms), where availability is less certain. In my experience (having written a few perl applications being hosted on Windows, against my advice) most things will work, and/or are fairly easy to work around, and both ActiveState and Strawberryperl seem to have decent support for most common modules.
The first statement doesn't refer to modules at all. It says that ActivePerl is not based on Perl, it is Perl. As such, anything that will run on Perl will also run on ActivePerl.
This also means that all modules on CPAN are compatible with ActivePerl since ActivePerl is Perl.
Whether a module is compatible with Windows is an entirely different question, and it can only be answered on a module-by-module basis.
The second statement points out that if you had a script or module that runs on a pristine ActivePerl, it might not necessarily run on a pristine Perl because ActiveState includes modules in its distribution that aren't core modules (e.g. LWP). But all you'd need to do to make the script or module run on the other distribution is to install those modules.
You can check on the availability of PPM modules at http://code.activestate.com/ppm/. For example, one module that doesn't work well through PPM is PAR::Packer.

How do I use perlbrew to manage perl installations aimed at web applications?

I have been using perlbrew to manage multiple versions of perl on a Linux Fedora notebook. I have used it with great benefit to run command-line scripts mostly using App::cmd.
I now want to move to running web applications written using CGI::Application using different perls installed in my $HOME. I am familiar with running Perl web applications in $HOMEs using Apache's user_dir or creating Virtual Hosts but I am unable to come up with a clean way of integrating this and the perlbrew managed perls. Specifically I need help in understanding and finding answers to these questions:
How do install mod_perl under perlbrew?
Assuming this is done, how do I configure my VirtualHost so that it picks up the correct perl that is current?
If this is not possible, (which I doubt) can I at least use local installations to run vanilla CGI?
Thank you for your attention.
I don't think this is a good use for perlbrew, which moves around symlinks under its own directory. The trick is switching the mod_perl module around. Remember, mod_perl is going to be binary-incompatible between major versions of perl, and that you will have to compile it against apache for each version of perl (and apache) you want to use.
perlbrew really does two big things for you:
Installs perl, which is trivially easy to do on your own.
Switches around symlinks so perl is whatever version you want.
If you give up on that last one, perlbrew isn't really doing that much for you. I don't think the symlink feature is particularly valuable.
I think perlbrew is fine for what it is, but when you start doing things outside of its limited scope, it's time to not use it. It's supposed to be a tool to save you some time and headache, so if it's not accomplishing that goal, it's not the right tool for your situation.
In this situation, where I'm supporting a single, big web application, I give it its own perl installation that I don't let anything else use.
For your other questions:
markdown placeholder
You shouldn't have to configure any VirtualHost stuff. If you are using mod_perl, perl is already in there and you don't get to choose a perl. If you're using CGI stuff, you specify the perl on the shebang line. You will have to ensure apache picks up the right library directories, but I think perlbrew handles that. You might have to use SetEnv or something similar in your httpd.conf.
For vanilla CGI, just point to the right (symlink) path for whatever the default perlbrew version is. The CGI program will just use whatever perl that path points to.
See brian d foy's answer for why not to expect to use perlbrew to switch between versions of mod_perl. I also expect that you will need to run multiple Apache servers, if you need multiple different Perl versions under mod_perl.
However, using perlbrew as an easy way to build Perl is IMHO a valid thing to do, and there are few instructions available for how to run mod_perl under perlbrew.
First ensure perl is built with shared library support, by passing the -Duseshrplib flag (otherwise on 64-bit systems you will get a confusing build failure about -fPIC):
perlbrew install perl-5.16.3 -Duseshrplib
Install the development Apache libraries for your system. On Debian, this differs depending on the Apache MPM that you are using. For the prefork MPM:
sudo apt-get install apache2-prefork-dev
Or for the worker MPM:
sudo apt-get install apache2-threaded-dev
Then you need some options to build and install mod_perl2 into the right place. Note that this means cpanm will fail to build it, but you could use it to get hold of the source:
cpanm mod_perl2 # fails
cd ~/.cpanm/latest-build/mod_perl-2.0.8/ # adjust mod_perl version
Adjust the version of Perl below accordingly. (The MP_APXS option is to give the right path for Debian-based systems, which you might not need.)
perl Makefile.PL MP_APXS=/usr/bin/apxs2 \
MP_AP_DESTDIR=$HOME/perl5/perlbrew/perls/perl-5.16.3/
make
make install
Finally, change the LoadModule line in your Apache configuration file (adjusting paths accordingly):
LoadModule perl_module <your homedir>/perl5/perlbrew/perls/<your perl>/usr/lib/apache2/modules/mod_perl.so
Your mod_perl installation will now be running the version of Perl that you want. Install all your required CPAN modules and get going.

How do I install Devel::Cover on ActivePerl 5.8.7?

cpan fails with this weird error as follows
Error: Unable to locate installed Perl libraries or Perl source code.
It is recommended that you install perl in a standard location before
building extensions. Some precompiled versions of perl do not contain
these header files, so you cannot build extensions. In such a case,
please build and install your perl from a fresh perl distribution. It
usually solves this kind of problem.
(You get this message, because MakeMaker could not find "D:\fbl_esc_bcd_tb\tools\perl\lib\CORE\perl.h")
Running make test
Make had some problems, maybe interrupted? Won't test
Running make install
Make had some problems, maybe interrupted? Won't install
Problem is I can't install new active perl versions in this environment and the tool I want to coverage on does not run outside this environment.
Short answer: The ActiveState PPM repository has a precompiled version of Devel::Cover you should be able to install.
Long answer: That's not a normal message from MakeMaker so I'm willing to guess its an ActiveState addition, but its probably true. The problem is exactly what the error message says; your distribution is missing some important files, specifically the C header files for Perl, so it cannot compile C code necessary for modules like Devel::Cover. This is often the result of an overzealous sysadmin or packager looking to save a few dozen K of disk space. You could probably take the header files from the 5.8.7 source, copy them into the CORE directory and it will probably work. It won't make anything worse.
I agree with Evan that, assuming this is a Windows machine, you should switch to Strawberry Perl which plays much better with the rest of the Perl community than ActivePerl.
Otherwise, ActiveState is a commercial company and they have paid Perl support. Give them a ring.
Active Perl does not use CPAN. If you want to use CPAN use Strawberry Perl. Active Perl uses binary distribution through its ppm system. There are a few third party repos for it if the official one doesn't have Devel::Cover -- though the official probably has Devel::Cover.
Most people these days are moving to Strawberry and away from AS. In my opinion, it is far more stable and CPAN-friendly, and surely less proprietary. Also, expect to be able to get stable versions of most everything - AS has been known to lag years in many occasions in the official repos. strawberry also comes with its own compiler and build environment so you can even get ::XS versions working with ease.

How do I install deps for CPAN module without installing it?

This is a follow-up to my previous question about developing Perl applications. Let’s say I develop an application as a CPAN module using Module::Install. Now I upload the code to the production server, say using a git push, and I would like to install the application dependencies listed in Makefile.PL. If I simply run cpan ., the thing tries to install the application like a regular Perl module, ie. starts to copy the modules and documentation to standard Perl directories all over the system.
Is this the way it’s supposed to be? Do you install the application into the standard Perl directories? I am used to having my Perl applications in one directory with separate lib. Otherwise it seems I’d have to manage a lot of other things, like installing the resources somewhere on path etc. If I just want to install the deps declared in Makefile.PL and run the application tests to make sure everything works, what should I do?
(Is this documented somewhere? I mean, is there something like best practice for deploying and updating non-trivial Perl applications? Or is everybody doing this his own way?)
I might be misunderstanding, but I think what you're looking for is
perl Makefile.PL
make installdeps
If you are using Module::Install, you're really using ExtUtils::MakeMaker behind the scenes. You can use all of the MakeMaker features and the targets it provides. Although the documentation doesn't show every feature, there are some valuable things to be found in the generated Makefile.
However, MakeMaker is old news and most everyone has asked Santa Claus for it to disappear. If you want better control, including creating your own targets and process, Module::Build is orders of magnitude easier to work with as well as cross-platform (even if that just means not using a different make, gmake, or whatever on the same OS on different boxes). If you deviate from the normal, consumer-grade installation process, you're life will be easier without MakeMaker.
Some people appreciate the brevity of the Module::Install build file, but once constructed, you don't spend a lot of time messing with your build file so it's not that much of a real benefit. When the little benefit you get locks you into MakeMaker, it's not a win at all.
A 2014 update: Module::Build has now fallen out of favor and needs a maintainer. It never quite got to the point where people could use it to build and distribute XS modules. It was deprecated in Perl v5.19 although you can still get it from CPAN.
You could look at Module::ScanDeps to generate a list of dependent modules for installing. Or Par::Packer for packaging up the whole thing as an "app".