在 Intel 机器上构建 Apple Silicon 二进制文件

Posted

技术标签:

【中文标题】在 Intel 机器上构建 Apple Silicon 二进制文件【英文标题】:Build Apple Silicon binary on Intel machine 【发布时间】:2021-03-29 09:08:55 【问题描述】:

如何在 macOS 11 (Intel) 上编译 C 项目以在 Silicon 上运行?

我当前的构建脚本很简单:

./configure
make
sudo make install

我尝试将--host--target 标志与aarch64-apple-darwinarm-apple-darwin 一起使用,但没有任何运气。

二进制始终默认为x86_64

> file foobar.so
foobar.so: Mach-O 64-bit bundle x86_64

更新: 指定--host 时似乎找不到cc 和gcc。

checking for arm-apple-darwin-cc... no
checking for arm-apple-darwin-gcc... no

【问题讨论】:

您安装了最新的 XCode 12?您至少需要它。 @selbie:这在 GitHub 操作上运行,Xcode 版本为 12.2。 在下面查看我的答案。您可能想要 -target arm64-apple-macos11 。请注意,目标参数前面有一个单破折号,而不是双破折号。 你有没有让它为 arm 编译? 不,我们最终租了一台 MacStadium M1 机器,但仍然需要在 x84 上为 arm 编译这个 ????‍♂️ 【参考方案1】:

我在this page 上找到了使用此功能的提示:

-target arm64-apple-macos11

当我从我的 mac 运行它时:

clang++ main.cpp -target arm64-apple-macos11

生成的 a.out 二进制文件如下所示:

% file a.out
a.out: Mach-O 64-bit executable arm64

我安装了 XCode 12.2。

我面前没有 Arm Mac,所以我假设这是可行的。

【讨论】:

使用./configure时如何指定clang++作为编译器? 您可能不必这样做。 Clang 是默认编译器,g++ 命令行实际上只是一个转发给 clang 的 shim。 不幸的是,我们必须使用 ./configure,因为我们有几个标志。有没有办法告诉./configure 使用clang++ 我不是 autoconf(生成配置脚本的工具)方面的专家。但您可能只需要设置脚本CC=clangCXX=clang++ 我们尝试过,但没有任何运气。自动工具?‍♂️【参考方案2】:

先生。 Curious 也对 M1 的交叉编译感到好奇。一个意想不到的解决方案是Zig。它旨在成为交叉编译 C 的最佳方式,等等;它可以轻松地从 Linux 瞄准 M1。

几周前有一系列关于交叉编译到 M1 的流:Part 1 展示了如何在现有 makefile 中使用 Zig 作为交叉编译器,Part 3 他们成功演示了在 Linux 上编译 Redis M1.

强烈推荐。

【讨论】:

感谢分享,今天下午我会深入研究 Zig!【参考方案3】:

我们最终解决了这个问题,并能够在 GitHub Actions 的 x86-64 机器上编译 darwin-arm64debian-aarch64 二进制文件。

我们为 arm64 预编译了所有依赖项,并以静态和动态方式链接它们。

export RELAY_DEPS_PATH=./build-deps/arm64
export PKG_CONFIG_PATH=./build-deps/arm64/lib/pkgconfig

cd ./relay-deps
TARGET=./build-deps make install

cd ./relay
phpize
./configure CFLAGS='-target arm64-apple-macos' \
  --host=aarch64-apple-darwin \
  --enable-relay-jemalloc-prefix
  [snip...]

make

# Dynamically linked binary
cc --target=arm64-apple-darwin \
  $wl-flat_namespace $wl-undefined $wlsuppress \
  -o .libs/relay.so -bundle .libs/*.o \
  -L$RELAY_DEPS_PATH/lib -lhiredis -ljemalloc_pic [snip...]

# re-link to standard paths
./relay-deps/utils/macos/relink.sh .libs/relay.so /usr/local/lib
cp .libs/relay.so modules/relay.so

# Build a statically linked shared object
cc --target=arm64-apple-darwin \
  $wl-flat_namespace $wl-undefined $wlsuppress \
  -o .libs/relay-static.so -bundle .libs/*.o \
  $RELAY_DEPS_PATH/lib/libhiredis.a \
  $RELAY_DEPS_PATH/lib/libjemalloc_pic.a \
  [snip...]

relink.sh:

#!/bin/bash
set -e

printUsage() 
    echo "$0 <shared-object> <prefix>"
    exit 1


if [[ ! -f "$1" || -z "$2" ]]; then
    printUsage
    exit 1
fi

INFILE=$1
PREFIX=$2

links=(libjemalloc libhiredis [snip...])

if [ -z "$PREFIX" ]; then
    PREFIX=libs
fi

for link in $links[@]; do
    FROM=$(otool -L "$INFILE"|grep $link|awk 'print $1')
    FILE=$(basename -- "$FROM")
    TO="$PREFIX/$FILE"

    echo "$FROM -> $TO"
    install_name_tool -change "$FROM" "$TO" "$1"
done

【讨论】:

以上是关于在 Intel 机器上构建 Apple Silicon 二进制文件的主要内容,如果未能解决你的问题,请参考以下文章

阿里云机器学习PAI构建AI集团军作战,联手Intel在AI软硬件领域发力

如何在 osx 机器中将 Apple 配置文件从一个用户转移到另一个用户?

如何创建可在 Apple 自研芯片和基于 Intel 的 Mac 机上运行的应用程序

Apple 开源机器学习框架 Turi Create 简介与实践

芯片超Intel,盈利比肩Apple,三星成科技界"全民公敌"

SQL 注入