Running perl script with Scalar::Util fails with "Attempt to reload Scalar/Util.pm aborted." - macos

I have recently switched to a Mac Book Pro M1 (from Ubuntu) and installed Perl from homebrew.
I've installed a number of perl packages I commonly use without any issues. Unfortunately at runtime any perl programs that depend on (or use a package that depends on) Scalar::Util or List::Util fail with errors like:
Attempt to reload Scalar/Util.pm aborted.
Compilation failed in require at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/YAML.pm line 21.
BEGIN failed--compilation aborted at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/YAML.pm line 21.
...
or
Can't load '/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle' for module List::Util: dlopen(/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle, 0x0001): symbol not found in flat namespace (_Perl_croak_memory_wrap) at /System/Library/Perl/5.30/XSLoader.pm line 96.
at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/List/Util.pm line 24.
Compilation failed in require at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/Scalar/Util.pm line 23.
I've also tried to install perlbrew as an alternative but haven't succeeded there. I've also checked that everything appears in the PERL5LIB path correctly.
With List::Util I've managed to install a newer version from CPAN but still get the same error. (The builtin Scalar::Util is the latest version)
Any suggestions on what to try to get them working I fear that it's an M1 issue but I'm not sure it could be an xcode issue I guess.
You can replicate this with:
$ cpanm VCSL::Which
$ vcsvimdiff -v
Can't load '/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle' for module List::Util: dlopen(/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle, 0x0001): symbol not found in flat namespace (_Perl_croak_memory_wrap) at /System/Library/Perl/5.30/XSLoader.pm line 96.
at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/List/Util.pm line 24.
Compilation failed in require at /opt/homebrew/Cellar/perl/5.34.0/bin/vcsvimdiff line 12.
BEGIN failed--compilation aborted at /opt/homebrew/Cellar/perl/5.34.0/bin/vcsvimdiff line 12.
Unfortunately running
perl -MScalar::Util -e 1
or
perl -MList::Util -e 1
both run successfully. I looked at my PERL5LIB path and only see the homebrew perl paths there.
$ perl -E 'say join "\n", split /:/, $ENV{PERL5LIB}'
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0
All that looks fine with no system perl references

The summary:
check that you aren't missing something
check perl -V to see which perl it is and it's default module search path
check environment variables such as PERL5LIB for conflicting values
look in the shebang line for the programs you are running
Do you have everything?
As HÃ¥kon noted, it looks like there are two perl installations interfering with each other. But, also as ikegami said "never seen that" error message. I haven't either, but StackOverflow has seen it.
The entry in [perldiag] is says that the program tried to load the module, failed the first time, and then something tried again:
Attempt to reload %s aborted.
(F) You tried to load a file with "use" or "require" that failed to
compile once already. Perl will not try to compile this file again
unless you delete its entry from %INC. See "require" in perlfunc and
"%INC" in perlvar.
I don't know what keeps it from failing the first time, but you should check with something simple to see if you can load the module:
$ perl -MScalar::Util -e 1
But, it's actually more tricky than this. Maybe that perl can load it, but some other perl can't. And, maybe you have multiple installations of Scalar::Util, but the particular perl and environment and program settings conspire to choose the wrong one.
The environment can tell perl where to look
But, perhaps none of that works.
First, figure out which perl you want to use, and check its settings:
$ perl -V
At the end of the output you should see the interesting environment settings and the default module search path. With a clean session, I don't have any environment variables that contain PERL:
%ENV:
#INC:
/usr/local/perls/perl-5.36.0/lib/site_perl/5.36.0/darwin-2level
/usr/local/perls/perl-5.36.0/lib/site_perl/5.36.0
/usr/local/perls/perl-5.36.0/lib/5.36.0/darwin-2level
/usr/local/perls/perl-5.36.0/lib/5.36.0
However, I can dirty up my environment. I'll set a PERL5LIB value, which prepends directories to the default module search path:
$ export PERL5LIB=/usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level:/usr/local/perls/perl-5.10.1/lib/5.10.1:/usr/local/perls/perl-5.10.1/lib/site_perl/5.10.1/darwin-2level:/usr/local/perls/perl-5.10.1/lib/site_perl/5.10.1
Check perl -V again and this interesting thing happens:
Perl lib version (5.10.1) doesn't match executable version (v5.36.0) at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/Config.pm line 50.
Compilation failed in require.
BEGIN failed--compilation aborted.
If I try to load Scalar::Util from the command line with -M, which is what I'd expect if you've mixed up the perls:
$ perl -MScalar::Util -e 1
Can't load '/usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/auto/List/Util/Util.bundle' for module List::Util: dlopen(/usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/auto/List/Util/Util.bundle, 0x0001): symbol not found in flat namespace '_PL_sv_no' at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/XSLoader.pm line 73.
at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/List/Util.pm line 23
Compilation failed in require at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/Scalar/Util.pm line 23.
Compilation failed in require.
BEGIN failed--compilation aborted.
Programs may be incorrectly adjusting #INC
I don't think this is a problem with cpanm because the world would have complained by now. However, if some program is doing funky things with #INC, it may be adding the wrong things.
I think the likely case for this is a set of vendor module directories they use and that some of those modules are targeted at a particular perl. When you use a different perl, you get the binary mismatch thing.
Programs choose their interpreter
MacOS: two Perl installs: "Dumper.c: loadable library and perl binaries are mismatched" notes that their home-brew cpanm was hardcoded to use the system perl.
But, there's another part involved. You are running some programs, and those programs choose the perl. If you look at their first lines, they either have an absolute path to a perl, like this:
#!/usr/bin/perl
Or they play a trick to find the first perl in your PATH:
#!/usr/bin/env perl
I don't like that second one because I'm never sure which perl it will find first. In Mastering Perl, I have a long example of someone calling a program "perl", dropping it in a user-controlled directory in PATH (or adding that to PATH for you), then acting like its the real perl but turning off taint-checking along the way. Probably not your problem, but when you let the program guess who is going to handle it weird things can happen.
For example, I guess I haven't installed cpanm for v5.36.0 yet:
$ head -1 `which cpanm`
#!/usr/local/perls/perl-5.34.1/bin/perl
When I run just cpanm, it's going to use v5.34.1 and whatever settings I have for that.
I could tell it directly which perl to use, but I then need to tell that perl where to find the program:
$ perl5.36.0 `which cpanm` ...
Likewise, I have older versions of some programs that I address with the version I intend to use (I do a lot of stuff that runs something against many, many perls):
$ head -1 `which cpan5.10.1`
#!/usr/local/perls/perl-5.10.1/bin/perl
$ head -1 `which cpan5.12.5`
#!/usr/local/perls/perl-5.12.5/bin/perl
When you install programs, such as cpanm, the installation adjusts the shebang line for the perl that installed it. Simply running cpanm does not mean that you are installing into the perl you think you are.

Related

How can I make a Perl script executable in Windows 64bit?

I am trying to run the perl script through command line but it is not reorganizing the script file ie.
myscript.pl... is not working
but perl myscript.pl is working fine
I have tried the following suggestions but they didn't work either
How do I make my Perl scripts act like normal programs on Windows?
Perl execution from command line question
I am using Active Perl:- Perl 5 , Version 18.
It gives following warnings in both cases.
Using a hash as a reference is deprecated
earlier I installed strawberry perl before installing active perl, is that causing some problem.
The error message
Using a hash as a reference is deprecated
is a Perl message. Your script is being run just fine, but contains an error.
(It is remotely possible that you have two Perl versions installed, and that you configured Windows to use the wrong one. Reconfigure it to use the correct on then, using the guides you already found.)

How to use default path for ActivePerl 5.20 Mac OS X (/usr/bin/perl) instead of /usr/local/ActivePerl...?

I have installed ActivePerl 5.20.2 today on Mac OS X 10.9.5
Checking the version of perl in Terminal (perl -v) I see 5.20.2
So everything seems to be ok. But..
When I start my CGI scripts the script is running under built in perl (which is 5.16) (if using #!/usr/bin/perl).
If I use #!/usr/local/ActivePerl5.20.2/bin/perl then it runs under 5.20.2 that is required.
The question is: is it somehow possible to change the directory for using in my scripts from #!/usr/local/ActivePerl5.20.2/bin/perl to simple and familiar #!/usr/bin/perl keeping running under ActivePerl instead of built in.
I need to override the system's default version with the new ActivePerl.
I would be appreciated for your detailed answers (with name of files and directories where they are located) if ones are to be changed to implement salvation.
Thanks!
The question is: is it somehow possible to change the directory for using in my scripts from #!/usr/local/ActivePerl5.20.2/bin/perl to simple and familiar #!/usr/bin/perl keeping running under ActivePerl instead of built in.
Don't even try. That way lies damnation, not salvation. The ability to specify the specific interpreter that will handle your scripts is an important feature.
Instead, package your CGI script as a simple CPAN module. Then, install it using the familiar
$ /usr/local/ActivePerl5.20.2/bin/perl Makefile.PL
$ make install
routine. The shebang line will be automatically adjusted to reflect the perl that was used to build and install your package.
First, instead of specifying a particular path to your Perl interpreter in your script:
#! /usr/local/ActivePerl5.20.2/bin/perl
or
#! /usr/bin/perl
Specify this:
#! /usr/bin/env perl
This will find the first executable Perl interpreter in your $PATH and then use that to execute your Perl script. This way, instead of having to change your program, you only have to change the $PATH variable.
Next time, take a look at PerlBrew for installing a different version of Perl. PerlBrew will allow you to install multiple versions of Perl all under user control, and let you select which version of Perl you'd like to use.
I also recommend to put /usr/local/bin as the first entry in your $PATH. Then, link the executables you want to run to that directory. You can use something like this to create your links:
for file in $/usr/local/ActivePerl5.20.2/bin/*
do
basename=$(basename $file)
ln -s "$file" "/usr/local/bin/$basename"
done
This way, all programs you want to execute are in the same directory which makes setting $PATH so much easier. I even put /usr/local/bin in before /usr/bin and /bin because I want to be able to override the system's default version.

perl can't find installed modules but CPAN can, plus I can find them. Why can't perl?

I'm using macports supplied perl 5.16.3 installed in /opt/local/bin on my macbook 10.6
jason-danckss-macbook:eg Jason$ which perl
/opt/local/bin/perl
I was testing the demo.pl file that came with AI:Categorizer.pm from metaCPAN. I installed AI:Categorizer via CPAN supplied with macports perl:
tried to run it:
original:
./demo.pl /users/Jason/Desktop/Dropbox/capstone/capstone/notes/HTML/sock
Can't locate AI/Categorizer.pm in #INC (#INC contains: /sw/lib/perl5/5.10.0/darwin-thread-multi-
2level /sw/lib/perl5/5.10.0 /sw/lib/perl5/darwin-thread-multi-2level /sw/lib/perl5 /sw/lib/perl5
/darwin /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 ./demo.pl line 21.
BEGIN failed--compilation aborted at ./demo.pl line 21.
slightly modified with: use lib "/opt/local/lib/perl5/5.16.3"; because that's where the modules are being written when I use CPAN (I use perl -MCPAN -e shell IDK if that matters)
jason-danckss-macbook:eg Jason$ ./demo.pl ../HTML/sock
Can't locate AI/Categorizer.pm in #INC (#INC contains: /opt/local/lib/perl5/5.16.3/darwin-thread-
multi-2level /opt/local/lib/perl5/5.16.3 /sw/lib/perl5/5.10.0/darwin-thread-multi-2level /sw/lib
/perl5/5.10.0 /sw/lib/perl5/darwin-thread-multi-2level /sw/lib/perl5 /sw/lib/perl5/darwin
/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 ./demo.pl line 21.
BEGIN failed--compilation aborted at ./demo.pl line 21.
check its in the right spot:
jason-danckss-macbook:eg Jason$ find /opt/local/lib/perl5 -name 'Categorizer.pm'
/opt/local/lib/perl5/site_perl/5.16.3/AI/Categorizer.pm
I even tried to use diagnostic. Neither I nor perl can find diagnostic.pm. CPAN cant find it. I'm guessing it was removed in more recent perl versions?
OK so I have both fink and macports on my computer, along with a default perl installation. the macports version perl is the first perl found in $PATH. I'm OK with it after all its its pretty recent: 5.16.3
I don't know or think reading modules from multiple locations is a bad idea. but IDK. I'd hate to think what kind of gymnastics I might need to do to fix this.
Has anyone encountered this before?
I have just had a look at the AI::Categorizer bundle and the included demo.pl file has a hardcoded shebang of #!/usr/bin/perl so I believe it is trying to use the system perl.
Assuming you haven't already tried changing this line (the first line of demo.pl) to point at /opt/local/bin/perl then I suspect doing so will fix your problem.
You might also consider setting the shebang to /usr/bin/env perl which should use the version of perl from your path. Also have a look at perlbrew which is probably a better way to install non-system versions of Perl.

git-slave for windows

git-slave documentation only has the following not-so-helpful comment regarding installation on Windows:
* Limited windows support
Multiple users have been successful in using gitslave with Windows.
This is "supported" only in the sense that people have reported it to
work and we accept bugfixes, not that you can `make` install or check,
or that it is QAed on this platform prior to release."
When I try to download and run 'nmake install' I get the equally cryptic error:
makefile(2) : fatal error U1001: syntax error : illegal character '{' in macro
Stop.
Does anyone have any experience with this and can point me in the right direction?
The Makefile for git-slave has only been used with GNU Make - as it is a rather simple makefile, there is no reason it shouldn't work with Microsoft nmake as well, except for "gratuitous" use of Make extensions that are not supported by Microsoft nmake. ( How similar/different are gnu make, microsoft nmake and posix standard make? has a good summary of the differences).
On lines 2-4 of gitslave/Makefile, if you replace ${prefix} with $(prefix) and ${mandir} with $(mandir) [essentially replace braces with parentheses (brackets)] nmake should no longer choke on Makefile. However, unless you have installed a bunch of POSIX utilities or something that allows commands like mkdir -p, rm -f, and sed to work, fixing the nmake incompatibility would only allow (at best) make testcheck to work.
None of the gitslave developers have regular(?) access to Windows development machines, so like the documentation says: "we accept bugfixes, [but do] not [claim] that you can make install or check,
or that it is QAed on this platform."
I imagine that the other people who have used git-slave on windows just made sure that Perl and gitslave and any POSIX utilities that gitslave depends on (e.g. grep and rm) are installed somewhere in PATH.
On Windows you can download and install the free unix tool kit including all necessary programs:
https://sourceforge.net/projects/unxutils/
You also need a perl tool kit because "pod2man" is used in the make process.
Furthermore the script "gits" is a perl script which runs under *ix because of the "she-bang" instruction in the first line ("#!/usr/bin/perl") - this doesn't work on Windows.
I created a small wrapper batch scripts that uses my perl to start the original script:
gits.bat:
perl gits %*
Hope this helps.

OCaml Installation, not finding binaries

I am attempting to install and run objective-caml on a remote unix server.
I have successfully built and installed all files included in the ocaml package. However, when attempting to use it, eg:
[~]# ocamllex
gives:
-bash: /home1/PATHTOMYHOME/local/bin/ocamllex: /usr/local/bin/ocamlrun: bad interpreter: No such file or directory
Is there any way to tell it to look somewhere else for ocamlrun? The correct directory is in the $PATH variable (ocamlrun works).
You can pass the name of the bytecode file to ocamlrun:
/correct/path/to/ocamlrun /home1/PATHTOMYHOME/local/bin/ocamllex
Alternately, it may just work to edit the first line of the bytecode file: there is a #! and a hardcoded path there. The rest of the file is bytecode though, but if your editor does not mess with it, there is a chance...
As a third solution, use the native-compiled version ocamllex.opt: it does not rely on ocamlrun.
On unix systems, Ocaml bytecode executables begin with a shebang line that gives the path to the bytecode interpreter (ocamlrun). It seems that your executables start with #!/usr/local/bin/ocamlrun. Change this to /home1/PATHTOMYHOME/local/bin/ocamlrun.
If you want ocamlrun to be looked up in the $PATH, change the shebang line to #!/usr/bin/env ocamlrun.
Here's a way to change the path to the bytecode executables in the current directories, leaving other files intact. Remove the *.orig files once you've checked the replacement works.
perl -i.orig -pe 's~^#!.*/ocamlrun.*~#!/usr/bin/env ocamlrun~ if $.==1; close ARGV if eof' *
I suggest that you compile OCaml with ./configure -prefix /home1/PATHTOMYHOME/local. That way all programs will look in the right directories automatically.

Resources