Использование библиотек x86 и OpenMP на архитектуре macOS arm64

У меня есть MacBook M1, и я установил на свою машину библиотеку, скомпилированную для архитектуры x86/Intel. У меня есть исходный код, который использует OpenMP. Я хотел бы скомпилировать свой код и связать свой исполняемый файл с библиотекой x86 с помощью компилятора clang.

Я могу скомпилировать исходный код без зависимостей x86, следуя инструкциям здесь, используя реализацию clang, распространяемую вместе с brew.

Однако, когда я пытаюсь скомпилировать с аргументом -arch x86_64 и ссылкой на библиотеку x86, я обнаруживаю, что clang пытается связать мой исполняемый файл с библиотекой OpenMP, созданной для архитектуры arm64.

Можно ли установить версию clang на MacBook M1, где библиотеки OpenMP созданы для архитектуры x86?

Вот пример ошибки, которую я получаю при использовании моей текущей настройки, даже если я не связываюсь с библиотекой 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)

person Philip Maybank    schedule 04.05.2021    source источник
comment
В прошлый раз, когда я проверял, у процессора ARM был совершенно другой язык ассемблера и микрокод, чем у процессора Intel. Также ни один из них не может выполнять машинный код другого. Это означает, что исполняемый файл, предназначенный для архитектуры x86, не будет работать на платформе ARM без какого-либо интерпретатора.   -  person Thomas Matthews    schedule 04.05.2021
comment
@ThomasMatthews Разве Rosetta не используется для решения этой проблемы?   -  person Zoso    schedule 04.05.2021


Ответы (3)


Использование установки brew для x86 решает проблему для меня. Вот минимальный набор команд для установки x86-вариантов brew и clang и последующей компиляции моего кода 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
person Philip Maybank    schedule 06.05.2021

Во-первых, запуск двоичных файлов x86 на процессорах M1 ARM возможен благодаря Rosetta, но это экспериментально и поэтому не всегда работает.

Можно ли установить версию clang на MacBook M1, где библиотеки OpenMP созданы для архитектуры x86?

Это стало возможным благодаря кросс-компиляции. По крайней мере, Clang теоретически поддерживает это (используя опцию -target). Лучший способ — получить двоичные файлы из менеджера пакетов или скомпилировать libomp непосредственно из исходный код (вы можете следовать директивам здесь).

Пожалуйста, имейте в виду, что хотя исполняемые файлы x86_64 можно запускать на процессорах M1 с Rosetta, библиотеки разных архитектур нельзя смешивать вместе. Это означает, что вы должны скомпилировать все зависимости (включая одну из libomp, хотя у нее не должно быть много зависимостей).

Лучшее решение (рекомендуемое, более безопасное, быстрое и простое) — использовать нативные библиотеки и, таким образом, пересобирать библиотеки для процессоров M1 (возможно, из исходников, если это необходимо).

person Jérôme Richard    schedule 04.05.2021
comment
Я вижу, что это лучшее решение в тех случаях, когда у вас есть исходный код библиотеки и вы уверены, что знаете, как его скомпилировать. Чтобы охватить другие случаи, не знаете ли вы, где я мог бы разместить запрос на добавление функции для варочного варианта clang? Было бы неплохо, если бы вариант clang для brew поддерживал аргумент -arch x86_64 так же, как вариант clang для Apple. - person Philip Maybank; 05.05.2021

Brew может поддерживать параллельные установки x86 и Arm на машинах MacOS M1. Итак, что вам нужно сделать, это использовать установочный набор x86 и убедиться, что ваш PATH установлен правильно.

Он устанавливает приложения x86_64 в /usr/local (например, /usr/local/bin/brew) и приложения aarch64 в /opt/homebrew (например, /opt/homebrew/bin/brew).

См. https://docs.brew.sh/Installation.

person Jim Cownie    schedule 06.05.2021