是否可以安装和更新Perl(CPAN)模块与通用(x86_64,arm 64)架构支持?如果是,那么如何?
- 背景 *
在基于arm的macOS计算机上,Perl CPAN模块可以安装在一个指定的架构中,如下所示:
sudo cpan -i Encode
### equivalent since `-arm64` is the native processor in this situation:
sudo arch -arm64 cpan -i Encode
file /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle
# /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle:
# Mach-O 64-bit bundle arm64
sudo arch -x86_64 cpan -i Encode
file /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle
# /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle:
# Mach-O 64-bit bundle x86_64
但是,请注意,perl
本身是一个“通用二进制”:
file /usr/bin/perl
# /usr/bin/perl: Mach-O universal binary with 2 architectures:
# [x86_64:Mach-O 64-bit executable x86_64]
# [arm64e:Mach-O 64-bit executable arm64e]
# /usr/bin/perl (for architecture x86_64):
# Mach-O 64-bit executable x86_64
# /usr/bin/perl (for architecture arm64e):
# Mach-O 64-bit executable arm64e
- 当本机和非本机应用程序共享相同的Perl依赖项时,一个架构或另一个架构的XOR会出现冲突。* 例如,GnuCash Finance::Quote* 不能 * 在Arm上本机运行,而MacTeX LaTeX Live Update可以在Intel或Arm处理器上本机运行。这两个应用程序都使用Pearl Encode module。
如果未找到所需的体系结构版本,应用程序日志错误消息将为以下内容之一:
'/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle'(mach-o文件,但是不兼容的架构(有'arm 64',需要'x86_64'))
'/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle'(mach-o文件,但是不兼容的架构(有'x86_64',需要'arm 64'))
注意:运行应用程序的一个变通方法是为x86_64
体系结构安装通用Perl模块依赖项,然后在Rosetta 2(x86_64)模式下运行通用应用程序。
其他发现
cc选项'-bundle'
在保存的安装日志中找到cc -bundle
。
rm -f blib/arch/auto/Encode/Encode.bundle
cc -bundle -undefined dynamic_lookup Encode.o def_t.o encengine.o -o blib/arch/auto/Encode/Encode.bundle
chmod 755 blib/arch/auto/Encode/Encode.bundle
…
Manifying 18 pod documents
Files found in blib/arch: installing files in blib/lib into architecture dependent library tree
Installing /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle
然而,man cc
和cc --help
没有提供任何关于cc clang LLVM编译器的-bundle
选项的开发人员信息。因此,不清楚-bundle
实际上在做什么,或者Perl新手如何使用这条信息。
抽脂
看起来“构建通用二进制文件的最安全方法是单独编译模块,然后使用lipo
合并生成的.bundle
文件。”meta::cpan Config_u.pm
Apple的文章"Building a Universal macOS Binary"提供了一个这样的多步骤示例:
下面的示例显示了一个makefile,它为每个体系结构编译一次单源文件两次。然后,它通过使用lipo
工具合并生成的可执行文件来创建通用二进制文件。
x86_app: main.c
$(CC) main.c -o x86_app -target x86_64-apple-macos10.12
arm_app: main.c
$(CC) main.c -o arm_app -target arm64-apple-macos11
universal_app: x86_app arm_app
lipo -create -output universal_app x86_app arm_app
lipo
需要单独的体系结构文件作为-create
通用文件的输入。
文件Encode.bundle
对所有Encode.bundle
文件的搜索和审查发现了通用和非通用二进制文件的混合。
find / -name "Encode.bundle"
file /Applications/FreeCAD_0.20.app/Contents/Resources/lib/perl5/5.32/core_perl/auto/Encode/Encode.bundle
file /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle
file /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle
file /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/Encode.bundle
file /Users/USERNAME/.cpan/build/Encode-3.19-0/blib/arch/auto/Encode/Encode.bundle
# /Applications/FreeCAD_0.20.app/…/core_perl/auto/Encode/Encode.bundle:
# Mach-O 64-bit bundle x86_64
# /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle:
# Mach-O 64-bit bundle x86_64
# /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle:
# Mach-O universal binary with 2 architectures:
# [x86_64:Mach-O 64-bit bundle x86_64]
# [arm64e:Mach-O 64-bit bundle arm64e]
# /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/Encode.bundle:
# Mach-O universal binary with 2 architectures:
# [x86_64:Mach-O 64-bit bundle x86_64]
# [arm64e:Mach-O 64-bit bundle arm64e]
# /Users/USERNAME/.cpan/build/Encode-3.19-0/blib/arch/auto/Encode/Encode.bundle:
# Mach-O 64-bit bundle x86_64
- 评论:*
file /System/Library/Perl/…Encode.bundle
表明Pearl确实存在通用的二进制使用。file /Library/Perl/…Encode.bundle
表示用户安装和/或更新可能会屏蔽通用/System/Library/Perl/…Encode.bundle
,使其无法共享应用程序。
目标
理想情况下,整体解决方案将:
1.通常足以不需要对所添加的每个单独模块进行修改。
1.适用于初始模块安装和任何后续更新。
1.不会在Perl安装中与创建依赖项冲突。
可能的办法
无论是隐式调用还是显式调用,lipo
似乎都是创建通用二进制文件所必需的。
只是大声思考一些方法方向:
- 修改Perl make文件?(如何安全地做到这一点?这是一个实用的方法吗?)
- 创建Config_u的更新版本?
perl -MConfig_u Makefile.PL
- 具有并行的
/Perl/arm64/…
和/Perl/x86_64/…
树,然后通过脚本将lipo
合并为一些/Perl/some_universal_version/…
。 - 这会像
sudo arch -x86_64 -arm64 -arm64e cpan -i Encode
一样简单吗?
1条答案
按热度按时间2mbi3lxu1#
是否可以安装和更新具有通用(x86_64,arm64)体系结构支持的Perl(CPAN)模块?
我相信你可以通过在
Makefile.PL
中添加相关架构的-arch
标志来更新.bundle
文件。我用Encode
手工编译Encode.bundle
而不是像这样使用ExtUtils::MakeMaker
(macOS M1,ventura 13.1,homebrew perl version 5.34)来测试这个:最后一个命令的输出现在是:
这表明
Encode.bundle
已更新为具有x86_64
和arm64
体系结构的通用二进制文件