I am building a Perl module using Module::Build. The Build.PL file is below:
use strict ;
use warnings ;
use Module::Build;
my $build = Module::Build->new
(
module_name => 'Company::LDAP::SyncAttr',
license => 'perl',
installdirs => 'vendor',
install_path => {
'bin' => '/usr/bin',
'script' => '/usr/bin'
},
) ;
$build->create_build_script ;
The module itself is here:
# SyncAttr.pm
package Company::LDAP::SyncAttr;
use Authen::Krb5;
1;
I have a test file in t/test.t that looks like this:
# test.t
use Company::LDAP::SyncAttr;
When I run ./Build test I get this error:
t/test.t .. Can't load '/usr/lib/x86_64-linux-gnu/perl5/5.20/auto/Authen/Krb5/Krb5.so' for module Authen::Krb5: /usr/lib/x86_64-linux-gnu/perl5/5.20/auto/Authen/Krb5/Krb5.so:
undefined symbol: krb5_free_krbhst at /usr/lib/x86_64-linux-gnu/perl/5.20/DynaLoader.pm line 187.
at /tmp/gg/blib/lib/Company/LDAP/SyncAttr.pm line 3.
Compilation failed in require at /tmp/gg/blib/lib/Company/LDAP/SyncAttr.pm line 3.
If I run the test.t file directly, I get no such error:
perl -Ilib/ t/test.t
What do I have to do to get ./Build test to not error out?
UPDATE: The problem lies with Module::Build. There is a routine do_tests in the Module::Build::Base module that forces the environment variable PERL_DL_NONLAZY to 1. If I change that line to set PERL_DL_NONLAZY to 0, then the tests all pass. The module Module::Build::Base does not provide an option to not set PERL_DL_NONLAZY, so I have submitted a bug report asking them add such an option. In the meantime, I will just have to skip running ./Build test.
Related
I am very much a perl newbie, I know very little about the system.
I am trying to install App/Lingua/BO/Wylie/Transliteration.pm which seems to be dependent on true.
I am getting an error on the install of true. This seems very surprising, so I am very open to something very fundamental and wrong with the perl installation. Running perl v5.30.2 on MacOS 11.3.1.
cpan error log:
force install true.pm
Running install for module 'true'
CHOCOLATE/true-v1.0.2.tar.gz
Has already been unwrapped into directory /Users/phil/.cpan/build/true-v1.0.2-0
CHOCOLATE/true-v1.0.2.tar.gz
Has already been prepared
Running make for C/CH/CHOCOLATE/true-v1.0.2.tar.gz
"/usr/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- true.bs blib/arch/auto/true/true.bs 644
cc -c -I/Users/phil/perl5/lib/perl5/darwin-thread-multi-2level/B/Hooks/OP/Annotation/Install -I/System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/B/Hooks/OP/Check/Install -g -pipe -fno-strict-aliasing -fstack-protector-strong -DPERL_USE_SAFE_PUTENV -O3 -Wall -W -DVERSION=\"v1.0.2\" -DXS_VERSION=\"v1.0.2\" -iwithsysroot "/System/Library/Perl/5.30/darwin-thread-multi-2level/CORE" true.c
true.xs:8:10: fatal error: 'hook_op_check.h' file not found
#include "hook_op_check.h"
^~~~~~~~~~~~~~~~~
1 error generated.
make: *** [true.o] Error 1
CHOCOLATE/true-v1.0.2.tar.gz
/usr/bin/make -- NOT OK
Failed during this command:
CHOCOLATE/true-v1.0.2.tar.gz : make NO
true.xs:8:10: fatal error: 'hook_op_check.h' file not found
This looks like a bug in the system Perl installation that comes preinstalled on macOS. The module B::Hooks::OP::Check comes preinstalled in /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/B/Hooks/OP/ but the file /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/B/Hooks/OP/Check/Install/hook_op_check.h is missing for some reason. As a consequence, it is not possible to install the module true which depends on that file being there.
You can override the preinstalled version by running:
$ cpan -f B::Hooks::OP::Check
This will install the module into /Library/Perl/5.30/darwin-thread-multi-2level/B/Hooks/OP if you are using sudo with cpan, or into ~/perl5/lib/perl5/darwin-thread-multi-2level/B/Hooks/OP if you are using local::lib with cpan. This latter installation will be found before the preinstalled version due to the ordering of the perl #INC include path, so it will override the preinstalled version of the module.
This will enable you to install the module true, but after installing this the installation of App::Lingua::BO::Wylie::Transliteration still fails:
$ cpan App::Lingua::BO::Wylie::Transliteration
Loading internal logger. Log::Log4perl recommended for better logging
Reading '/Users/hakonhaegland/.cpan/Metadata'
Database was generated on Sat, 01 Jan 2022 22:29:03 GMT
Running install for module 'App::Lingua::BO::Wylie::Transliteration'
Fetching with LWP:
http://www.cpan.org/authors/id/D/DB/DBR/App-Lingua-BO-Wylie-Transliteration-0.1.0.tar.gz
Fetching with LWP:
HASH(0x13444b3c8)authors/id/D/DB/DBR/CHECKSUMS
Fetching with LWP:
HASH(0x13444b3c8)authors/id/D/DB/DBR/CHECKSUMS.gz
Fetching with LWP:
http://www.cpan.org/authors/id/D/DB/DBR/CHECKSUMS
Checksum for /Users/hakonhaegland/.cpan/sources/authors/id/D/DB/DBR/App-Lingua-BO-Wylie-Transliteration-0.1.0.tar.gz ok
Configuring D/DB/DBR/App-Lingua-BO-Wylie-Transliteration-0.1.0.tar.gz with Build.PL
Created MYMETA.yml and MYMETA.json
Creating new 'Build' script for 'App-Lingua-BO-Wylie-Transliteration' version '0.1.0'
DBR/App-Lingua-BO-Wylie-Transliteration-0.1.0.tar.gz
/usr/bin/perl Build.PL -- OK
Running Build for D/DB/DBR/App-Lingua-BO-Wylie-Transliteration-0.1.0.tar.gz
Building App-Lingua-BO-Wylie-Transliteration
DBR/App-Lingua-BO-Wylie-Transliteration-0.1.0.tar.gz
./Build -- OK
Running Build test for DBR/App-Lingua-BO-Wylie-Transliteration-0.1.0.tar.gz
t/00-check-deps.t ........ ok
t/00-load.t .............. 1/1
# Failed test 'use App::Lingua::BO::Wylie::Transliteration;'
# at /Library/Perl/5.30/Test/UseAllModules.pm line 71.
# Tried to use 'App::Lingua::BO::Wylie::Transliteration'.
# Error: Couldn't find declarator 'method' at /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/Devel/Declare/Context/Simple.pm line 47.
# Devel::Declare::Context::Simple::skip_declarator(Method::Signatures::Simple=HASH(0x12704f6d8)) called at /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/Devel/Declare/MethodInstaller/Simple.pm line 62
# Devel::Declare::MethodInstaller::Simple::parser(Method::Signatures::Simple=HASH(0x12704f6d8), "method", 0, 1) called at /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/Devel/Declare/MethodInstaller/Simple.pm line 25
# Devel::Declare::MethodInstaller::Simple::__ANON__("method", 0) called at /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/Devel/Declare.pm line 277
# Devel::Declare::linestr_callback("const", "method", 0) called at lib/App/Lingua/BO/Wylie/Transliteration.pm line 37
# require App/Lingua/BO/Wylie/Transliteration.pm called at /Library/Perl/5.30/Test/UseAllModules.pm line 71
# Test::UseAllModules::BEGIN() called at lib/App/Lingua/BO/Wylie/Transliteration.pm line 37
# eval {...} called at lib/App/Lingua/BO/Wylie/Transliteration.pm line 37
# eval 'package Test::UseAllModules;
# BEGIN { ${^WARNING_BITS} = $args[-1] if defined $args[-1] }
# #line 71 /Library/Perl/5.30/Test/UseAllModules.pm
# use App::Lingua::BO::Wylie::Transliteration #{$args[0]};
# 1;
# ' called at /System/Library/Perl/5.30/Test/More.pm line 1034
# Test::More::_eval("package Test::UseAllModules;\x{a}BEGIN { \${^WARNING_BITS} = \$args"..., ARRAY(0x1268938e0), "UUUUUUUUUUUUUUUUUUU") called at /System/Library/Perl/5.30/Test/More.pm line 1009
# Test::More::use_ok("App::Lingua::BO::Wylie::Transliteration") called at /Library/Perl/5.30/Test/UseAllModules.pm line 71
# Test::UseAllModules::all_uses_ok() called at t/00-load.t line 4
# main::BEGIN() called at lib/App/Lingua/BO/Wylie/Transliteration.pm line 37
# eval {...} called at lib/App/Lingua/BO/Wylie/Transliteration.pm line 37
# Compilation failed in require at /Library/Perl/5.30/Test/UseAllModules.pm line 71.
# BEGIN failed--compilation aborted at /Library/Perl/5.30/Test/UseAllModules.pm line 71.
Bailout called. Further testing stopped: failed: App::Lingua::BO::Wylie::Transliteration
this is due to a recent change in Devel::Declare and a corresponding change in the parser in bleed described in these bug reports, report1 and report2.
A workaround is to install a an earlier version of perl together with an earlier version of Devel::Declare. You can do this using perlbrew. For example:
$ perlbrew install perl-5.26.3
$ cpanm Devel::Declare#0.006019
$ cpanm App::Lingua::BO::Wylie::Transliteration
The system is Ubuntu. There is a perl in /usr/bin/, and is version is 5.18.2.
In this state, I tried to install many software by "sudo apt-get install **" and it was OK.
But a few days before, I installed a new perl in an other
directory(/share/Software/perl-5.26.0/bin/perl). And I remove the original perl then link the new perl to /use/bin/. The commands are:
sudo mv /usr/bin/perl /usr/bin/old/; (the old/ directory was make before)
sudo ln -s /share/Software/perl-5.26.0/bin/perl /usr/bin/perl
After that, I got the error informations when I install system software by apt-get. The error likes below:
1 not fully installed or removed.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n] y
debconf: Perl may be unconfigured (Can't locate Debconf/Log.pm in #INC (you may need to install the Debconf::Log module) (#INC contains: /share/Software/perl-5.26.0/lib/site_perl/5.26.0/x86_64-linux /share/Software/perl-5.26.0/lib/site_perl/5.26.0 /share/Software/perl-5.26.0/lib/5.26.0/x86_64-linux /share/Software/perl-5.26.0/lib/5.26.0) at (eval 1) line 4.
BEGIN failed--compilation aborted at (eval 1) line 4.
) -- aborting
Setting up doc-base (0.10.5) ...
Can't locate Debian/DocBase/Common.pm in #INC (you may need to install the Debian::DocBase::Common module) (#INC contains: /share/Software/perl-5.26.0/lib/site_perl/5.26.0/x86_64-linux /share/Software/perl-5.26.0/lib/site_perl/5.26.0 /share/Software/perl-5.26.0/lib/5.26.0/x86_64-linux /share/Software/perl-5.26.0/lib/5.26.0) at /usr/sbin/install-docs line 8.
BEGIN failed--compilation aborted at /usr/sbin/install-docs line 8.
Some software can be installed successfully, but some can not be.
If I put perl back to the previous, it is normal again. (That must be!)
Module "Debconf::Log" is located at /share/Software/perl-5.26.0/lib/perl5, but I can not find Debian/DocBase/Common.pm.
Path of /share/Software/perl-5.26.0/lib/perl5 is inside #INC of perl. Why it can not find it?
I even think that it is the problem when perl installed. I get below error when perl installed: ("make test")
Useless use of single ref constructor in void context at op/gv.t line 1191.
In file included from ../../../../perl.h:5644:0,
from ExtTest.xs:2:
ExtTest.c: In function ‘XS_ExtTest_constant’:
../../../../embed.h:691:40: warning: ‘pv’ may be used uninitialized in this function [-Wmaybe-uninitialized]
#define sv_setpvn(a,b,c) Perl_sv_setpvn(aTHX_ a,b,c)
^
ExtTest.xs:420:14: note: ‘pv’ was declared here
const char *pv;
^
In file included from ../../../../perl.h:5644:0,
from ExtTest.xs:2:
../../../../embed.h:691:40: warning: ‘iv’ may be used uninitialized in this function [-Wmaybe-uninitialized]
#define sv_setpvn(a,b,c) Perl_sv_setpvn(aTHX_ a,b,c)
^
ExtTest.xs:418:6: note: ‘iv’ was declared here
IV iv;
^
In file included from ../../../../perl.h:5644:0,
from ExtTest.xs:2:
ExtTest.c: In function ‘XS_ExtTest_constant’:
../../../../embed.h:691:40: warning: ‘pv’ may be used uninitialized in this function [-Wmaybe-uninitialized]
#define sv_setpvn(a,b,c) Perl_sv_setpvn(aTHX_ a,b,c)
^
ExtTest.xs:194:14: note: ‘pv’ was declared here
const char *pv;
^
In file included from ../../../../perl.h:5644:0,
from ExtTest.xs:2:
ExtTest.c: In function ‘XS_ExtTest_constant’:
../../../../embed.h:675:42: warning: ‘iv’ may be used uninitialized in this function [-Wmaybe-uninitialized]
#define sv_setiv_mg(a,b) Perl_sv_setiv_mg(aTHX_ a,b)
^
ExtTest.xs:166:6: note: ‘iv’ was declared here
IV iv;
^
# Failed test 'cp updated mtime'
# at t/cp.t line 26.
# '38'
# <=
# '1'
# Looks like you failed 1 test of 1.
Request to remove file /share/Software/perl-5.26.0-src/cpan/File-Temp/suffixOEXZVr.dat could not be completed since it is not there!
at t/mktemp.t line 75.
# parser guessed wrong encoding expected 'CP1252' got 'UTF-8'
# Failed test 'File 1 atime set correctly'
# at t/utime.t line 113.
# '37.684463262558'
# <
# '0.1'
# Failed test 'File 1 mtime set correctly'
# at t/utime.t line 114.
# '37.684463262558'
# <
# '0.1'
# Failed test 'File 2 atime set correctly'
# at t/utime.t line 118.
# '37.684463262558'
# <
# '0.1'
# Failed test 'File 2 mtime set correctly'
# at t/utime.t line 119.
# '37.684463262558'
# <
# '0.1'
# Looks like you failed 4 tests of 18.
Can't open copy1-87150: Permission denied at ../lib/File/Copy.t line 326.
# Looks like your test exited with 13 just after 366.
Failed 3 tests out of 2449, 99.88% okay.
### Since not all tests were successful, you may want to run some of
### them individually and examine any diagnostic messages they produce.
### See the INSTALL document's section on "make test".
### You have a good chance to get more information by running
### ./perl harness
### in the 't' directory since most (>=80%) of the tests succeeded.
### You may have to set your dynamic library search path,
### LD_LIBRARY_PATH, to point to the build directory:
### setenv LD_LIBRARY_PATH `pwd`:$LD_LIBRARY_PATH; cd t; ./perl harness
### LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH; cd t; ./perl harness
### export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH; cd t; ./perl harness
### for csh-style shells, like tcsh; or for traditional/modern
### Bourne-style shells, like bash, ksh, and zsh, respectively.
make: *** [test] Error 1
Each Perl is compiled with a few #INC directories where it will search for modules. The error message explains which directories are searched:
#INC contains:
/share/Software/perl-5.26.0/lib/site_perl/5.26.0/x86_64-linux
/share/Software/perl-5.26.0/lib/site_perl/5.26.0
/share/Software/perl-5.26.0/lib/5.26.0/x86_64-linux
/share/Software/perl-5.26.0/lib/5.26.0
This does not include the directories where APT has installed modules for Perl, e.g. under /usr/lib.
However, adding those directories will not help. Some modules are compiled for a specific Perl versions. You cannot upgrade Perl in-place, but would have to reinstall all modules. Since APT contains pre-built modules you cannot use modules installed via APT with a custom Perl.
Therefore: leave the system Perl because Ubuntu depends on its proper functioning. It is safe to install another Perl alongside, e.g. via perlbrew. It is safe to add a custom Perl to your PATH, e.g. via perlbrew switch. This will also fix a couple of additional environment variables that are required for a second Perl to work.
Context
Here is a perl test script, in which I wanted to see how you can use a specific event loop with AnyEvent :
# file test.pl :
#!/usr/bin/perl
use strict;
use warnings;
use AnyEvent;
use AnyEvent::Impl::EV;
my $cv = AnyEvent->condvar;
my $wait_one_and_a_half_seconds = AnyEvent->timer (
after => 0.5, # after how many seconds to invoke the cb?
cb => sub { # the callback to invoke
print ("Hello from callback\n");
$cv->send;
},
);
# now wait till our time has come
$cv->recv;
Problem
Here is the error I get when running the above code :
$ perl test.pl
Can't locate EV.pm in #INC (you may need to install the EV module) (#INC
contains: /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 /usr/local/lib/perl/5.18.2/AnyEvent/Impl/EV.pm
line 28.
BEGIN failed--compilation aborted at /usr/local/lib/perl/5.18.2/AnyEvent/Impl/EV.pm line 28.
Compilation failed in require at test.pl line 6.
BEGIN failed--compilation aborted at test.pl line 6.
Yet I installed the AnyEvent package using cpanm, and the AnyEvent/Impl/EV.pm file is present in one of the #INC path :
$ ls /usr/local/lib/perl/5.18.2/AnyEvent/Impl/
Cocoa.pm Event.pm FLTK.pm IOAsync.pm Perl.pm Qt.pm UV.pm
EventLib.pm EV.pm Glib.pm Irssi.pm POE.pm Tk.pm
Question
How do I fix this ?
Extra remark
The error message says it is looking for EV.pm, but I would have expected AnyEvent/Impl/EV.pm.
How come the use AnyEvent::Impl::EV; I wrote got turned into perl is looking for EV.pm at runtime ?
Just tried to reproduce this with cpan install AnyEvent and can confirm I get the same error.
Line 28 of 'EV.pm' is use EV 4.00;. Your use EV; is a bit of a red herring - that's not the source of the error. This module explicitly includes a 'use' line (which frankly is a bit wierd, it's 'using' itself it seems?)
I don't think that's ever going to work, unless the #INC path is changed - I can only assume that the loading of this module is handled elsewhere, without deconstructing source code.
Referencing the man page - this module gets loaded automatically as required. So you probably don't need to use it in the first place.
Edit: Just compared perl versions. Perl 5.8.5 shows the same behaviour. My 5.20.1 install doesn't.
I'm not sure upgrading perl is necessarily the right step, but it might be worth trying? I'll try and figure out why 5.20.1 works though. It's got to be something to do with handling of #INC.
Edit:
"The handling of return values of #INC filters (subroutines returned by subroutines in #INC) has been fixed in various ways. Previously tied variables were mishandled, and setting $_ to a reference or typeglob could result in crashes."
http://perldoc.perl.org/perl5200delta.html
I think that might be what the problem is.
You're certainly not alone in having this:
http://www.cpantesters.org/cpan/report/d5939816-a510-11e0-bd04-22322d9f2468
From:
http://cpansearch.perl.org/src/MLEHMANN/AnyEvent-7.08/Changes
5.29 Sun Dec 5 10:49:21 CET 2010
- convert EV backend to EV 4.00 API (so better upgrade EV too).
The error message was actually a very correct and forward pointer to what should be done : there is an EV package which needs to be installed separately :
$ sudo cpanm EV
--> Working on EV
Fetching http://www.cpan.org/authors/id/M/ML/MLEHMANN/EV-4.18.tar.gz ... OK
Configuring EV-4.18 ... OK
Building and testing EV-4.18 ... OK
Successfully installed EV-4.18
1 distribution installed
After that, everything works :
$ cat test.pl
#!/usr/bin/perl
use strict;
use warnings;
use AnyEvent;
use EV;
my $wait_one_and_a_half_seconds = AnyEvent->timer (
after => 0.5, # after how many seconds to invoke the cb?
cb => sub { # the callback to invoke
print ("Hello from callback\n");
},
);
# now wait till our time has come
EV::run();
$ perl test.pl
Hello from callback
I used Module::Starter to create the skeleton of a module, and one of the test files it creates ("t/00-load.t") looks like this:
#!perl -T
use 5.006;
use strict;
use warnings FATAL => 'all';
plan tests => 1;
BEGIN {
use_ok( 'My::Module' ) || print "Bail out!\n";
}
But when I run make && make test, this test fails because turning on taint mode ("perl -T") removes "." from #INC, so that My::Module is not found. I can see the value of turning on taint checking in general, but how am I supposed to then test this code? This is the error message that's output:
# Failed test 'use My::Module;'
# at t/00-load.t line 10.
# Tried to use 'My::Module'.
# Error: Can't locate My/Module.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 (eval 4) line 2.
# BEGIN failed--compilation aborted at (eval 4) line 2.
This is on perl 5.16.1, with Module::Starter 1.62 and ExtUtils::MakeMaker 6.86. The skeleton was created with "module-starter --module=My::Module", so using defaults for everything else.
When the module is created with Module::Starter, which in turn relies on MakeMaker (or Module::Build), then all building and testing should be done via the provided Makefile (or Build file, if using Module::Build). I.e., with make && make test or ./Build && ./Build test.
I have a Perl module that appears to compile fine by itself, but is causing other programs to fail compilation when it is included:
me#host:~/code $ perl -c -Imodules modules/Rebat/Store.pm
modules/Rebat/Store.pm syntax OK
me#host:~/code $ perl -c -Imodules bin/rebat-report-status
Attempt to reload Rebat/Store.pm aborted
Compilation failed in require at bin/rebat-report-status line 4.
BEGIN failed--compilation aborted at bin/rebat-report-status line 4.
The first few lines of rebat-report-status are
...
3 use Rebat;
4 use Rebat::Store;
5 use strict;
...
Edit (for posterity): Another reason for this to occur, and perhaps the most common reason, is that there is a circular dependency among the modules you are using.
Look in Rebat/Store.pm for clues. Your log says attempt to reload was aborted. Maybe Rebat already imports Rebat::Store, and Rebat::Store has some package-scope check against being loaded twice.
This code demonstrates the kind of situation I mean:
# m1.pl:
use M1;
use M1::M2;
M1::M2::x();
# M1.pm
package M1;
use M1::M2;
1;
# M1/M2.pm
package M1::M2;
our $imported = 0;
sub import {
die "Attempt to reload M1::M2 aborted.\n" if $imported++;
}
sub x { print "42\n" }
1;
$ perl m1.pl
Attempt to reload M1::M2 aborted.
BEGIN failed--compilation aborted at m1.pl line 3.
The code will compile (and print 42) if you just remove the use M1::M2 line in m1.pl. In your case, you might not need to explicitly use Rebat::Store in your program.
perldoc perldiag:
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.