18

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

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

./configure
make
sudo make install

我尝试过使用--hostand--target标志,aarch64-apple-darwin无论arm-apple-darwin是否有任何运气。

二进制始终默认为x86_64

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

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

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

3 回答 3

8

我在此页面上找到了使用此功能的提示:

-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,所以我假设这是可行的。

于 2020-12-20T23:54:35.080 回答
3

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

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

强烈推荐。

于 2021-03-24T22:26:57.307 回答
2

我们最终解决了这个问题,并能够在 GitHub Actions 的 x86-64 机器上编译darwin-arm64和二进制文件。debian-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 ${wl}suppress \
  -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 ${wl}suppress \
  -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
于 2021-03-31T20:58:08.973 回答