在 macOS arm64 架构上使用 x86 库和 OpenMP

Using x86 libraries and OpenMP on macOS arm64 architecture

我有一台 MacBook M1,并在我的机器上安装了一个为 x86 / Intel 架构编译的库。我有一些使用 OpenMP 的源代码。我想使用 clang 编译器将我的代码和 link 我的可执行文件编译到 x86 库。

我能够按照说明 here,使用随 brew 分发的 clang 的实现编译没有 x86 依赖项的源代码。

然而,当我尝试使用 -arch x86_64 参数和 link 编译到 x86 库时,我发现 clang 尝试将我的可执行文件 link 编译到一个 OpenMP 库,该库是为arm64 架构。

是否可以在 OpenMP 库是为 x86 架构构建的 MacBook M1 上安装 clang 版本?

这是我使用当前设置时遇到的一个错误示例,即使未link访问 x86 库也是如此。

源代码:

#include <omp.h>
int main()
{
    return 0;
}

调用编译器:

/opt/homebrew/opt/llvm/bin/clang++ -arch x86_64 omp_ex.cpp \ 
    -L/opt/homebrew/opt/llvm/lib -Wl,-rpath,/opt/homebrew/opt/llvm/lib \
    -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include

错误信息:

ld: in '/opt/homebrew/opt/llvm/lib/libunwind.dylib', building for macOS-x86_64 but attempting to link with file built for macOS-arm64
clang-12: error: linker command failed with exit code 1 (use -v to see invocation)

首先,由于 Rosetta,运行在 M1 ARM 处理器上使用 x86 二进制文件是可能的,但这是实验性的,因此并不总是有效。

Is it possible to install a version of clang on a MacBook M1 where the OpenMP libraries are built for x86 architectures?

感谢cross-compilation,这应该是可能的。至少,Clang 理论上支持这一点(使用选项 -target)。 最好的方法是从包管理器检索二进制文件或直接从 source code (you can follow the directives here).

编译 libomp

请记住,虽然 x86_64 个二进制文件可以在带有 Rosetta 的 M1 处理器上 运行,但不同体系结构的库不能混合在一起。这意味着您应该编译所有依赖项(包括 libomp 之一,尽管它不应该有很多依赖项)。

最好的解决方案(推荐、更安全、更快和更简单)是使用本机库,从而为 M1 处理器重建库(如果需要,可能来自源)。

Brew 可以支持在 MacOS M1 机器上并行安装 x86 和 Arm。所以您需要做的是使用 x86 安装集并确保您的 PATH 设置正确。

它在 /usr/local(例如 /usr/local/bin/brew)中安装 x86_64 个应用程序,在 /opt/homebrew(例如 /opt/homebrew/bin/brew)中安装 aarch64 应用程序。

https://docs.brew.sh/Installation

使用 x86 安装的 brew 解决了我的问题。这是用于安装 brew 和 clang 的 x86 变体,然后编译我的 C/C++ 代码的最小命令集:

# launch x86_64 shell
arch -x86_64 zsh  
# install x86_64 variant of brew 
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
# install x86_64 variant of clang
arch -x86_64 /usr/local/bin/brew install llvm 
# compile using x86_64 variant of clang
/usr/local/opt/llvm/bin/clang++ -arch x86_64 omp_ex.cpp

brew 应用程序现在安装在我机器上的两个不同位置:

# arm64 (default) location
/opt/homebrew/bin/brew
# x86_64 location
/usr/local/bin/brew

clang 安装在三个不同的位置:

# Apple arm64 (default) location
/usr/bin/clang
# brew arm64 location
/opt/homebrew/opt/llvm/bin/clang
# brew x86_64 location
/usr/local/opt/llvm/bin/clang