make adds an 'exec' line to my scripts - perl

I'm trying to build a perl package (module + scripts).
My Makefile.PL has the following to include my script
EXE_FILES => [
'bin/somescript1',
],
But after installing the script, it adds the following to the beginning of the installed script.
eval 'exec /usr/bin/perl -S $0 ${1+"$#"}'
if 0; # not running under some shell
Why does it do this and can I make it not include that?

When ExtUtils::Makemaker installs your scripts, it modifies to the shebang line to use the path to the perl you used to build the distribution. That way, when you call the script, it uses the same perl that you used to install the dependencies.
Additionally, it adds that exec line. If, for some reason, the system starts your program in the shell instead of perl, the exec switches it to perl.
Leave it alone. This only helps you.
However, if you want to override it, you have to override the parts of Makemaker that install programs. If you want to cut off your arm, you'll have to find out how to do that yourself. It's all in the Makemaker docs.

You should not worry about those lines. It's a way to make your script runnable with both Perl and the shell, making it super-portable.

If you set the shebang line to #!/usr/bin/env perl you can exploit a bug in ExtUtils::MM_Unix and the eval line isn't added on install. This wil break if the installing host does not have a working /usr/bin/env

Related

Replace #INC in Perl from command line

I have a perl script that used to run in a chroot, and now I'd like it to run outside the chroot. That means that I have to somehow point perl to only look for libraries and modules in /where/chroot/used/to/be/usr/lib instead of /usr/lib. I tried adding the new directories inside the script with push #INC, but then the dependencies are still broken, looking in the old dirs.
Is there any way to tell perl when I run the script that I only want it to look in certain dirs for libraries and modules?
Or is there another better way to make sure dependecies still work when the regular dirs (/usr/bin, /usr/lib etc) are replaced by nonstandard ones?
To change the #INC from the command line, use the -I option:
perl -lIadded -e 'print for #INC'
In a program, you need to modify #INC early enough, i.e. during compile time. This can be done with
BEGIN { unshift #INC, '/path/...' }
or by using lib
use lib '/path/...';
You can also set the PERL5LIB environment variable:
export PERL5LIB=/path/...
perl -e 'print for #INC'
you can use lib to put any new directory in your program.
example
use lib "path";
in your case just add this line in the beginning of your program
use lib "/usr/lib/";
hope this will work for you.

Running Perl Script from Command Line?

I have perl express 2.5 loaded on my server. I would like to be able to run my perl scripts using a command line so they can be scheduled rather than manually bringing up the script in Perl Express and clicking on the run command. Is there a way to execute the script from a command line using this version of Perl or do I need to download a newer or more robust version of the Perl Engine.
You need to export the Perl interpreter (usually named perl) to your path. Then you can simply do
perl path/to/script.pl
In UNIX-based systems you are also able to run the scripts directly if you prepend
#!/usr/bin/perl
to the scripts and give them executable permissions (you might need to replace /usr/bin/perl with the path to your Perl interpreter).
According to the documentation:
Perl Express is not tied to a specific Perl port and should work with any build for Windows.
and the system requirements:
Windows 98/Me/2000/XP/2003, Perl Interpreter
So you, presumably, have a separate Perl distribution already installed somewhere. That should have a perl.exe executable that you can use to run your script.
You just need to give perl command and the path of your perl script.
example :
D:\Project\dir>perl <path_of_perl_script .pl>

Cant run some perl scripts from Textmate (Can't locate in #INC error)

I primarily use Textmate for perl hacking on OSX Snow Leopard. It was all fine till some days ago when I installed Macports (I've heard a rumor that macports installs some version of perl in /opt/local). Now, for any new package that I install from CPAN, and try to use if from Textmate, it gives me an error like this when I hit Cmd+R to run it (I had installed HTML::TreeBuilder from CPAN moments before):
Can't locate HTML/TreeBuilder.pm in #INC (#INC contains: /Applications/TextMate.app/Contents/SharedSupport/Bundles/Perl.tmbundle/Support /Library/Perl/Updates/5.10.0/darwin-thread-multi-2level /Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level /System/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0 /Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library/Perl/Extras/5.10.0 .) at /workspace/PerlScripts/test.pl line 2.
However it runs just fine when I run it from command line. If you will notice, textmate is using Perl version 5.10.0. When I run a "Perl -v" from command line, it shows me the version as 5.12.3 (see a copy paste from terminal below)
This is perl 5, version 12, subversion 3 (v5.12.3) built for darwin-multi-2level
The small perl code that I used is this:
#!/usr/bin/env perl <br/>
use HTML::TreeBuilder; <br/>
print $HTML::TreeBuilder::VERSION."\n";<br/>
print "$INC{'HTML/TreeBuilder.pm'}\n";<br>
Then I ran "which perl" from command line and it returned this:
/opt/local/bin/perl
then I ran "print system("which perl");" from Textmate and it returned
/usr/bin/perl
Now I clearly have two versions of perl sitting in my system. 5.10.0 that Textmate is trying to refer to and which cannot see my CPAN installs. And 5.12.3 that looks to be the default version of perl when I run it from command line and the one which my CPAN installs to. I tried to replace this:
#! /usr/bin/perl -w
with this (had read on google that this will force the system default perl to be picked up in textmate):
#!/usr/bin/env perl
No dice yet. Textmate still gives me the same error as I mentioned at the start of the question. So, is there a way to get it to work with Textmate? And is there a way to make textmate point to version 5.12.3?
You need to set the relevant environment variables for OS X. At the moment you probably have them set just for your shell. These will probably be PATH and PERL5LIB.
mkdir ~/.MacOSX
touch ~/.MacOSX/environment.plist
defaults write ~/.MacOSX/environment VARIABLE_NAME VARIABLE_VALUE
You'll need to log out and back in again to activate it.
Make sure that TextMate has your $PATH variables
in Textmate go to Preferences, then the Advanced Tab.
Under Shell Variables, make sure the path to your preferred perl (and cpan) is there something like:
/opt/local/bin:/opt/local/sbin:/usr/local/mysql/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
Your inc path can be gotten from:
perl -e 'print #INC,"\n"'
Or from perl -V.
It is higly probable that you installed HTML::Treebuilder in a version dependent path component, so 5.12 can findit, whereas 5.10 does not.
If this is the case, you may either install the relevant modules with 5.10 OR try some tricks with lib.pm:
use lib qw(/usr/perl/site_perl/5.12);
This kind of things are best left to your package manager though, and I do not advise you do this at home unless you are totally sure of what you are doing, as you might introduce subtle bugs due to version incompatibilities (or it could just blow up, but that's easier) .

How to make an installable Perl program with makefile/autoconf?

I have software written in Perl, now I want to release it and I want it to be an installation package like the other GNU software, which can be installed by typing:
./configure; make; make install
I noticed that in autoconf's package, most of the code is written in Perl and the Perl scripts are generated by running "make". That's exactly what I want to do. How would I go about doing that?
===
Added
Thank you for your nice answer! But what I wrote is not a module, it's actually a set of scripts which will do something in a pipe, the only thing I need to setup is the locations of some program I used in the Perl scripts. Is there any suggestion on this?
The process used by ExtUtils::MakeMaker and Module::Install is very similar.
perl Makefile.PL
make
make test
make install
If you're set on using the specific command chain you posted, you can place the following in file configure:
#!/bin/sh
perl Makefile.PL
If you're not set on using the specific command chain you posted, there's also Module::Build.
perl Build.PL
./Build
./Build test
./Build install
I use Module::Build personally.
In the Makefile.am that's where your perl scripts reside, add the line
dist_bin_SCRIPTS = your_perl_program

How can I modify my cygwin environment to use Strawberry Perl instead of the packaged Perl distribution?

I currently use Strawberry Perl as my primary Perl distribution. However, I have some applications that make Perl calls through cygwin. These generally fail because they are calling the version of Perl that was packaged with cygwin, and only looking in cygwin's lib folders. How can I modify my cygwin environment to call Strawberry Perl (and use the C:/strawberry/perl/lib dirs) instead?
If you remove Perl from cygwin using the setup program it will use Strawberry Perl by default.
If you are unable to remove Perl from cygwin, you can create a symbolic link to the Perl executable from Strawberry.
From a cygwin shell, use the following set of commands:
$ mv /usr/bin/perl /usr/bin/perl-cygwin
$ ln -s /cygdrive/c/strawberry/perl/bin/perl.exe /usr/bin/perl
This is assuming you used the default Strawberry Perl installer. Update your perl.exe location accordingly if you have it installed somewhere else.
Check to make sure the link is working properly by checking the Perl version:
$ perl -v
It should say This is perl, (version) built for MSWin32-x86-multi-thread (or similar) and not built for cygwin-thread-multi-64int.
You can change your PATH to put the Strawberry directories first. Strawberry tries to be nice by putting its directories at the end of the PATH. If you installed from the .zip file, however, it didn't change the PATH at all.
You could move /usr/bin/perl, but that's a bad idea since it breaks when cygwin tries to update what it thinks is its perl. I just had that happen to me this week and used to happen to me on my Mac until I stopped playing with the system setup and installed my own stuff completely separate.
One good thing I can add is that if you get the right perl to come first in the path, it should handle site-specific CPAN modules you may have installed with strawberry perl running in a CMD shell.
"which perl" is your friend.
If you had trouble with this, you could set the PERL5LIB environment variable, but it shouldn't be necessary.
I still pass in DOS-style file paths as parameters into the perl script, i.e. "d:\data\myfile.txt", not "/cygdrive/d/data/myfile.txt". So oddly enough, this mix of path notation works:
bash> /cygdrive/d/scripts/myscript.pl d:\data\myfile.txt
Many of these are good solutions, but I rather take an easy one that I don't have to modify more than once.
All you need to do is add/modify a line in your .bashrc file.
# Prepend strawberry perl to cygwin's path
export PATH=/cygdrive/C/Tools/Perl/perl/bin:$PATH
source .bashrc file from your shell, (or start a new shell) and run your program.
source ~/.bashrc
perl script.pl
This is probably not a preferred solution, but you should be able to modify the #! line:
#!/cygdrive/c/strawberry/perl/bin/perl5.10.0
I always refer to an explicit location and installation of perl, rather than relying on what is in /usr/bin.
I have two scripts that I use to modify the first line of Perl scripts to whichever Perl is first in my path: rightperl hardcodes to the Perl that is first in my $PATH now, envperl will change the line to #!/usr/bin/env perl so the Perl to use is only picked at the time the script is invoked. Works really well under Cygwin (and from a Unix shell in general).
If you don't want to mess around with any paths or do anything permanent there is an easy TEMPORARY hack. Type "where perl" at Cygwin sh prompt. It will list all the Perl.exe it sees in PATH in their order of execution. Change the names of the ones you don't want to be seen that get listed before the perl you want to use. But DO remember to change them back when you are done or you might have a few problems down the road.
I don't have my cygwin machine nearby so I can't test this, but perhaps you can front-end the perl command with a script: go to /bin under cygwin and move the perl.exe there to something else like perl-org.exe, then set up a shell script that execs your other perl with the same arguments.