安装 Perl 模块时出现“致命错误:找不到‘EXTERN.h’文件”

Posted

技术标签:

【中文标题】安装 Perl 模块时出现“致命错误:找不到‘EXTERN.h’文件”【英文标题】:"Fatal error: 'EXTERN.h' file not found" while installing Perl modules 【发布时间】:2019-03-11 22:42:38 【问题描述】:

在尝试安装 JSON::XS 或 YAML::XS 等 Perl 模块时,我收到相同的错误:

XS.xs:1:10:致命错误:找不到“EXTERN.h”文件

我使用 MacBook,xCode 是最新的,其他所有可以提供帮助的东西也是最新的。

【问题讨论】:

听起来您的 Perl 安装不完整。它缺少一些标题。 我认为在安装 Perl 后更新某些库时会发生这种情况。尝试重新安装 Perl? 就像@melpomene 所说,您缺少 Perl 本身的关键部分。许多 linux 发行版默认只安装部分 Perl,并留给您使用他们的包管理器 (apt / yum) 根据需要安装遗漏的部分。 MacBook 可能也一样? 【参考方案1】:

自 OS X El Capitan 以来,Apple 引入了 System Integrity Protection,它限制写入 /usr/lib /usr/bin 和其他敏感目录(甚至是 root 或 sudo 用户),这些目录由与操作系统捆绑的 Perl 安装使用系统。在安装新模块以及尝试安装 XS 模块(链接到外部 C 库的模块)时,这可能会导致问题。

因此,您不应将默认 Perl 安装视为工作开发环境,尤其是在安装自定义模块时。

查看this thread on PM 和其他人。自从 El-Capitan 之前通过从 tarball 手动构建并添加一些参数或环境变量来设置路径以来,我已经设法解决了这个问题,我认为最好保留对系统 Perl 的使用,但这不是要走的路。这使您的环境难以构建,而且对操作系统更新也很脆弱且敏感,这些更新可能会以多种不同方式破坏事物。

最佳实践似乎是从使用 brew install perl 的 Perl 开始并在此环境中工作,记住按照安装程序的指示设置 bash_profile。

还值得记住做一个brew link perl。如果您收到有关这种破坏看起来像系统 Perl 库的警告的警告 - 这些可能是您安装在顶部的模块,它会减少您链接这些的麻烦。如果您有疑虑,请记下将清除哪些模块安装,并在配置环境后重新安装它们(即您的模块安装程序方法是使用 cpanm 配置的或坚持使用旧的 perl -MCPAN -e shell 等)

brew 的这个新 Perl 设置消除了继续运行 sudo 的需要,这增加了另一层可能出错的事情,因为环境变量没有遵循并且出现权限冲突等。

最后,为了简化包/模块的安装,我建议做一个brew install cpanminus。如果您之前已经安装了这个,您可以通过执行 brew reinstall cpanminus 来确保配置路径等

如果您想更进一步,那么您也可以安装 perlbrew,这将使您能够以您的用户身份运行多个版本的 Perl,并使用他们自己的库和模块配置这些版本,这非常有用,特别是如果与您的生产环境保持一致以进行测试等。

如果从系统 Perl 迁移到这种方法,您可能会遇到一个问题,即需要处理使用 sudo 安装东西的任何遗留问题。值得花一点时间来正确设置所有这些,并且您未来的问题将大大减少,并且您不会因为担心一切都破裂而不想改变任何东西的唠叨感觉.

我也遇到过Perl Blog Article that suggests a fix for XS issues with perlbrew on Mojave

Gist 描述了更新您的 cpan shell 安装根目录,尽管这不是必需的,除非您的 cpan 在执行上述步骤后卡在旧配置中。

我也在PerlMonks上提出了这个新问题

【讨论】:

brew link perl 刚才对我来说不是必需的。我也不确定在安装 perlbrew 之前通过 Homebrew 安装 Perl 是否有用(然后通过它重新安装 Perl)。也可以将 Perl 环境与 Homebrew 更新隔离开来;不只是 macOS。 perlbrew install-cpanm 看起来也不错。【参考方案2】:

阅读https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes#3035624 并通过以下方式安装附加标头后

sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /

我成功编译,没有丢失 'EXTERN.h' 错误

【讨论】:

是的,感谢您的意见。完全删除和清理,正确重新安装后,我的问题得到了解决。好像我搞砸了。 执行 /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg 为我修复了这个问题,即使我已经安装了 Xcode10 和命令行工具。谢谢!【参考方案3】:

为了遵循常见的建议,我还尝试使用 Perlbrew 安装 Perl 的专用开发版本。尤其是牢记建议首先,不要在 MacOS 上使用系统 Perl。已安装的版本适用于 Apple,而不适用于您(请参阅此处的讨论:https://www.perlmonks.org/?node_id=1224727)。

很遗憾,出现以下错误:

Test Summary Report
-------------------
porting/libperl.t                                                (Wstat: 65280 Tests: 35 Failed: 0)
  Non-zero exit status: 255
  Parse errors: No plan found in TAP output
Files=2653, Tests=1217766, 708 wallclock secs (52.74 usr  9.40 sys + 395.38 cusr 49.90 csys = 507.42 CPU)
Result: FAIL
make: *** [test_harness] Error 1
##### Brew Failed #####

因此,我决定按照以下方式安装它(由于错误而没有遵循建议)。

即使在 Catalina (macOS 10.15.2) 上安装了上述 macOS SDK 头文件后,它对我也不起作用。我在安装 Perl 模块 Mac-SystemDirectory-0.13 时遇到了这个问题。以下步骤(通过识别丢失的文件,希望有一种更通用的方法来解决或多或少等效的问题)起到了作用:

    找到头文件(在本例中为 EXTERN.h

    sudo find /Library -type f -name EXTERN.h
    /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE/EXTERN.h
    /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Perl/5.28/darwin-thread-multi-2level/CORE/EXTERN.h
    /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE/EXTERN.h
    

    确保安装的 Perl 版本(此处为 5.18)与头文件匹配:

    perl -v | grep version 
    This is perl 5, version 18, subversion 4 (v5.18.4) built for darwin-thread-multi-2level
    

    导出 C 编译器的路径(注意 MacOSX10.15.sdk 用于 Catalina 和 Perl 版本 5.18)

    export CPATH=/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE
    

    用 perl 调用 Makefile.PL

    perl Makefile.PL
    

【讨论】:

【参考方案4】:

顺便说一句——对于仍在为此苦苦挣扎的任何人,我的解决方法是:

bash% module="Sub::Util"    # For example

bash% cpanm --configure-args="INC=-I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE" "$module"

【讨论】:

【参考方案5】:

没有承诺,但 yum install perl-devel 为我工作。

【讨论】:

【参考方案6】:

对于 Big Sur 和 perl 5.30,EXTERN.h 位于 /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk/System/Library/Perl/5.30/darwin-thread-multi-2level/CORE

我正在尝试升级 CPAN 本身并收到该错误。但是我有 /usr/bin/cpan,我不能在那里写,所以我必须调整它以将更新的版本写入 /usr/local/bin/cpan。

【讨论】:

【参考方案7】:

请试试这个

CPATH=$(dirname $(find /usr/local/Cellar/ -name EXTERN.h)) cpan JSON::XS

【讨论】:

以上是关于安装 Perl 模块时出现“致命错误:找不到‘EXTERN.h’文件”的主要内容,如果未能解决你的问题,请参考以下文章

使用 Perl API 连接 plotly 站点时出现 HTTP::Response 失败

安装的 Perl 模块不可用

在 Sun Unix 上为 Perl 安装 DBD::mysql 时出现问题

编译 SWIG 输出的包装器模块时出现 6 个错误?

在 perl 中编译正则表达式时出现“reg_node overrun”

使用 Perl64 在 Windows 7(64 位)上构建 BerkeleyDB 时出现编译/链接错误