如何在 macOS 10.13 High Sierra 上安装 Perl

How to install Perl on macOS 10.13 High Sierra

我最近升级到 macOS 10.13 High Sierra,不久之后在尝试安装更新版本的 Perl (5.26.1) 时遇到问题。问题的要点是 cpan/DB_File 的自测在 macOS 10.13 High Sierra(家用笔记本电脑)上始终失败,但在 macOS 10.12 Sierra(工作笔记本电脑)上成功。

这是显示失败的安装日志部分:

../cpan/Config-Perl-V/t/30_plv5240.t ............................... ok
../cpan/Config-Perl-V/t/31_plv52511.t .............................. ok
../cpan/DB_File/t/db-btree.t ....................................... ok
Use of uninitialized value $value in string eq at t/db-hash.t line 224.
Use of uninitialized value $values[0] in string eq at t/db-hash.t line 224.
Use of uninitialized value $value in lc at t/db-hash.t line 224.
Use of uninitialized value $h{""} in string eq at t/db-hash.t line 243.
Use of uninitialized value in numeric eq (==) at t/db-hash.t line 252.
Use of uninitialized value in numeric eq (==) at t/db-hash.t line 252.
Use of uninitialized value in numeric eq (==) at t/db-hash.t line 252.
Use of uninitialized value in numeric eq (==) at t/db-hash.t line 252.
Use of uninitialized value in numeric eq (==) at t/db-hash.t line 252.
Use of uninitialized value in numeric eq (==) at t/db-hash.t line 252.
Use of uninitialized value in numeric eq (==) at t/db-hash.t line 252.
Use of uninitialized value in numeric eq (==) at t/db-hash.t line 252.
Use of uninitialized value $foo[18] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[36] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[48] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[58] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[59] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[60] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[62] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[63] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[92] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[114] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[140] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[187] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[188] in join or string at t/db-hash.t line 261.
Use of uninitialized value $foo[189] in join or string at t/db-hash.t line 261.
Use of uninitialized value $h{"Fred"} in string eq at t/db-hash.t line 572.
Use of uninitialized value $v in concatenation (.) or string at t/db-hash.t line 748.
../cpan/DB_File/t/db-hash.t ........................................ 
Dubious, test returned 2 (wstat 512, 0x200)
Failed 76/166 subtests 

无论是使用 perlbrew install perl-5.26.1 安装还是简单地下载 the Perl tarfile 并手动安装,我都能够重复同样的失败。当我尝试调试有问题的测试 t/db-hash.t 时,我可以看到测试哈希 %h 已创建并被填充到测试文件中,但是当我 print Dumper(\%h) 我看到hash 看起来有正确的键,但是 all 的值是 undef,而不是测试脚本中分配的值。

这些 undef 值导致测试失败。奇怪的是,当我打印整个散列或尝试制作散列值数组时,会出现未定义的值。如果我要求一个特定的散列键值,例如my $value = $h{key},该值打印正常。

问题:

TL;DR

这是有效的方法:

  1. 安装 Berkeley DB。我用 Homebrew, but you can get the source files at the Oracle site.

    brew install berkeley-db
    
  2. 安装 Perl。我使用 Perlbrew, but you can get the source files at the Perl site.

    perlbrew install perl-5.26.1
    

部分解释

回顾失败的安装日志,DB_File 部分附近有一条警告提供了线索:

...
./miniperl -Ilib make_ext.pl lib/auto/DB_File/DB_File.bundle  MAKE="/Applications/Xcode.app/Contents/Developer/usr/bin/make" LIBPERL_A=libperl.a LINKTYPE=dynamic
Parsing config.in...
Looks Good.
Warning (mostly harmless): No library found for -ldb
Generating a Unix-style Makefile
Writing Makefile for DB_File
...

未找到 db 库,大部分 无害。

根据 DB_File module 的文档,它是...

... a module which allows Perl programs to make use of the facilities provided by Berkeley DB...

安装 berkeley-db 后,Perl 安装日志的同一部分不再显示相同的警告:

...
./miniperl -Ilib make_ext.pl lib/auto/DB_File/DB_File.bundle  MAKE="/Applications/Xcode.app/Contents/Developer/usr/bin/make" LIBPERL_A=libperl.a LINKTYPE=dynamic
Parsing config.in...
Looks Good.
Generating a Unix-style Makefile
Writing Makefile for DB_File
...

在此过程中,之前失败的测试通过,安装成功完成:

...
../cpan/DB_File/t/db-btree.t ....................................... ok
../cpan/DB_File/t/db-hash.t ........................................ ok
../cpan/DB_File/t/db-recno.t ....................................... ok
...

我无法在网上找到任何关于为什么 macOS 10.13 High Sierra 中似乎缺少 Berkeley DB 的文档,以及这是否与以前的 macOS 版本有所不同,就像它看起来的那样。

非常感谢 Tim D 帮助我解决问题。

要安装 perl 本身(它包含 DB_File 模块),或者从 CPAN 安装 DB_File 模块,解决方案是一样的:编辑它的 config.in 以指向berkeley-db 的正确位置。

例如,我使用 sudo port install db48 通过 macports 安装了 db48 包。在 perl 下载本身中,我导航到 cpan/DB_File 并编辑其 config.in,从而更改现有的 INCLUDE 和 LIB 分配:

INCLUDE    = /opt/local/include/db48
LIB        = /opt/local/lib/db48

然后我可以恢复 perl 构建过程并且 DB_File 可以编译。

参考文献:

Perl RT#133280
CPAN RT#125238