安装和更新 Perl 模块为“通用”(x86_64、arm64)?

l -*_*c l 5 macos perl cpan x86-64 apple-silicon

是否可以安装和更新具有通用(x86_64、arm64)架构支持的 Perl(CPAN)模块?如果是,那么如何?

\n

背景

\n

在基于arm的macOS计算机上,可以为一个指定的架构安装Perl CPAN模块,如下所示:

\n
sudo cpan -i Encode\n### equivalent since `-arm64` is the native processor in this situation:\nsudo arch -arm64 cpan -i Encode\n\nfile /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle\n# /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle:\n#     Mach-O 64-bit bundle arm64\n\nsudo arch -x86_64 cpan -i Encode\n\nfile /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle\n# /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle:\n#     Mach-O 64-bit bundle x86_64\n
Run Code Online (Sandbox Code Playgroud)\n

但请注意,Appleperl本身就是一个“通用二进制文件”:

\n
file /usr/bin/perl\n\n# /usr/bin/perl: Mach-O universal binary with 2 architectures: \n#    [x86_64:Mach-O 64-bit executable x86_64] \n#    [arm64e:Mach-O 64-bit executable arm64e]\n# /usr/bin/perl (for architecture x86_64):  \n#     Mach-O 64-bit executable x86_64\n# /usr/bin/perl (for architecture arm64e):  \n#     Mach-O 64-bit executable arm64e\n
Run Code Online (Sandbox Code Playgroud)\n

当本机和非本机应用程序共享相同的 Perl 依赖项时,一种体系结构或另一种体系结构的 XOR 会产生冲突。例如,GnuCash Finance::Quote 不能在 Arm 上本机运行,而MacTeX LaTeX Live Update可以在 Intel 或 Arm 处理器上本机运行。两个应用程序都使用Pearl Encode 模块

\n

如果找不到所需的体系结构版本,应用程序日志错误消息将是以下之一:

\n
\n

\'/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle\'(mach-o 文件,但是是一个不兼容的架构(有 \'arm64\',需要 \'x86_64\ '))

\n
\n
\n

\'/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle\'(mach-o 文件,但是是一个不兼容的架构(有 \'x86_64\',需要 \'arm64\ '))

\n
\n
\n

注意:运行应用程序的解决方法是安装x86_64架构的通用 Perl 模块依赖项,然后在 Rosetta2 (x86_64) 模式下运行通用应用程序。

\n
\n

其他发现

\n

cc 选项 \'-bundle\'

\n

cc -bundle在保存的安装日志中找到。

\n
rm -f blib/arch/auto/Encode/Encode.bundle\ncc  -bundle -undefined dynamic_lookup  Encode.o def_t.o encengine.o  -o blib/arch/auto/Encode/Encode.bundle \nchmod 755 blib/arch/auto/Encode/Encode.bundle\n\xe2\x80\xa6\nManifying 18 pod documents\nFiles found in blib/arch: installing files in blib/lib into architecture dependent library tree\nInstalling /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle\n
Run Code Online (Sandbox Code Playgroud)\n

但是,man cc并且cc --help不提供有关-bundlecc clang LLVM 编译器选项的任何开发人员信息。因此,目前还不清楚-bundle到底在做什么,或者 Perl 新手如何使用这条信息。

\n

脂类

\n

看来“构建通用二进制文件的最安全方法是单独编译模块,然后用于lipo合并生成的.bundle文件。” 请参阅:meta::cpan Config_u.pm

\n

Apple 文章“构建通用 macOS 二进制文件”提供了这样一个多步骤示例:

\n
\n

以下示例显示了一个 makefile,它为每个体系结构编译一个单源文件两次\xe2\x80\x94once。然后,它通过将生成的可执行文件与lipo

\n
\n
x86_app: main.c\n    $(CC) main.c -o x86_app -target x86_64-apple-macos10.12\narm_app: main.c\n    $(CC) main.c -o arm_app -target arm64-apple-macos11\nuniversal_app: x86_app arm_app\n    lipo -create -output universal_app x86_app arm_app\n
Run Code Online (Sandbox Code Playgroud)\n

lipo需要单独的架构文件作为输入-create通用文件的输入。

\n

文件编码.bundle

\n

对所有人进行搜索和审查Encode.bundle发现了通用和非通用二进制文件的混合。

\n
find / -name "Encode.bundle"\n\nfile /Applications/FreeCAD_0.20.app/Contents/Resources/lib/perl5/5.32/core_perl/auto/Encode/Encode.bundle\nfile /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle\nfile /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle\nfile /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/Encode.bundle\nfile /Users/USERNAME/.cpan/build/Encode-3.19-0/blib/arch/auto/Encode/Encode.bundle\n\n# /Applications/FreeCAD_0.20.app/\xe2\x80\xa6/core_perl/auto/Encode/Encode.bundle: \n#     Mach-O 64-bit bundle x86_64\n\n# /Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle: \n#     Mach-O 64-bit bundle x86_64\n\n# /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle: \n#     Mach-O universal binary with 2 architectures: \n#         [x86_64:Mach-O 64-bit bundle x86_64] \n#         [arm64e:Mach-O 64-bit bundle arm64e]\n\n# /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/Encode.bundle:\n#     Mach-O universal binary with 2 architectures: \n#         [x86_64:Mach-O 64-bit bundle x86_64]\n#         [arm64e:Mach-O 64-bit bundle arm64e]\n\n# /Users/USERNAME/.cpan/build/Encode-3.19-0/blib/arch/auto/Encode/Encode.bundle: \n#     Mach-O 64-bit bundle x86_64\n
Run Code Online (Sandbox Code Playgroud)\n

观察结果:

\n
    \n
  1. file /System/Library/Perl/\xe2\x80\xa6Encode.bundle表明 Pearl 确实存在通用的二进制使用。
  2. \n
  3. file /Library/Perl/\xe2\x80\xa6Encode.bundle表明用户安装和/或更新可能掩盖了通用/System/Library/Perl/\xe2\x80\xa6Encode.bundle共享应用程序使用的通用性。
  4. \n
\n

目标

\n

理想情况下,整体解决方案应:

\n
    \n
  1. 通常足以不需要修改添加的每个单独的模块。
  2. \n
  3. 适用于初始模块安装和任何后续更新。
  4. \n
  5. 不会在 Perl 安装中产生依赖冲突。
  6. \n
\n

可能的方法

\n

无论是隐式还是明确地调用,lipo似乎都需要创建通用二进制文件。

\n

只是大声思考一些方法方向:

\n
    \n
  • 修改 Perl make 文件?(如何安全地做到这一点?这是一种实用的方法吗?)

    \n
  • \n
  • 创建Config_u的更新版本?

    \n
  • \n
\n
perl -MConfig_u Makefile.PL\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • 有并行/Perl/arm64/\xe2\x80\xa6/Perl/x86_64/\xe2\x80\xa6树,然后通过脚本lipo合并成一些。/Perl/some_universal_version/\xe2\x80\xa6

    \n
  • \n
  • 这可能很简单吗sudo arch -x86_64 -arm64 -arm64e cpan -i Encode

    \n
  • \n
\n

Håk*_*and 1

是否可以安装和更新具有通用(x86_64、arm64)架构支持的 Perl(CPAN)模块?

我相信您可以.bundle通过-archMakefile.PL. 我通过手动Encode编译来测试这一点,而不是像这样使用(macOS M1,ventura 13.1,homebrew perl 版本 5.34):Encode.bundleExtUtils::MakeMaker

#! /bin/bash
arch_opt="-arch x86_64 -arch arm64"
opt1="-I./Encode -fno-common -DPERL_DARWIN -fno-strict-aliasing"
opt2="-mmacosx-version-min=12.0 -fstack-protector-strong"
opt3="-pipe -DPERL_USE_SAFE_PUTENV -Wno-error=implicit-function-declaration -O3"
opt4=-DVERSION=\"3.19\"
opt5=-DXS_VERSION=\"3.19\"
opt6="-I/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/5.34.0/darwin-thread-multi-2level/CORE"
ccopts="$arch_opt $opt1 $opt2 $opt3 $opt4 $opt5 $opt6"
ldopts="$arch_opt $opt2"
cc -c  $ccopts Encode.c
cc -c $ccopts def_t.c
cc -c $ccopts encengine.c
cc -bundle -undefined dynamic_lookup $ldopts \
   Encode.o def_t.o encengine.o -o blib/arch/auto/Encode/Encode.bundle
file blib/arch/auto/Encode/Encode.bundle
Run Code Online (Sandbox Code Playgroud)

最后一个命令的输出现在是:

blib/arch/auto/Encode/Encode.bundle: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit bundle x86_64] [arm64:Mach-O 64-bit bundle arm64]
blib/arch/auto/Encode/Encode.bundle (for architecture x86_64):  Mach-O 64-bit bundle x86_64
blib/arch/auto/Encode/Encode.bundle (for architecture arm64):   Mach-O 64-bit bundle arm64
Run Code Online (Sandbox Code Playgroud)

这表明已更新为具有架构和的Encode.bundle通用二进制文件x86_64arm64