Build Apple Silicon binary on Intel machine Build Apple Silicon binary on Intel machine c c

Build Apple Silicon binary on Intel machine


I found a hint on this page to use this:

-target arm64-apple-macos11

When I run this from my mac:

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

The resulting a.out binary is listed as:

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

I have XCode 12.2 installed.

I don't have an Arm Mac in front of me, so I'm assuming this works.


Mr. Curious was curious about cross-compilation to M1 as well. One unexpected solution is Zig. It aims to be the best way to cross-compile C, among other things; it easily targets M1 from Linux.

There was a series of streams about cross compiling to M1 a couple of weeks ago: Part 1 shows how to use Zig as a cross-compiler in existing makefiles, and in Part 3 they successfully demonstrate compiling Redis on Linux for M1.

Highly recommended.


We ended up solving solving this and being able to compile darwin-arm64 and debian-aarch64 binaries on GitHub Actions' x86-64 machines.

We pre-compiled all our dependencies for arm64 and linked them statically as well as dynamically.

export RELAY_DEPS_PATH=./build-deps/arm64export PKG_CONFIG_PATH=./build-deps/arm64/lib/pkgconfigcd ./relay-depsTARGET=./build-deps make installcd ./relayphpize./configure CFLAGS='-target arm64-apple-macos' \  --host=aarch64-apple-darwin \  --enable-relay-jemalloc-prefix  [snip...]make# Dynamically linked binarycc --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/libcp .libs/relay.so modules/relay.so# Build a statically linked shared objectcc --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...]

The relink.sh:

#!/bin/bashset -eprintUsage() {    echo "$0 <shared-object> <prefix>"    exit 1}if [[ ! -f "$1" || -z "$2" ]]; then    printUsage    exit 1fiINFILE=$1PREFIX=$2links=(libjemalloc libhiredis [snip...])if [ -z "$PREFIX" ]; then    PREFIX=libsfifor 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