Install homebrew, brew cask and then:
brew cask install gcc-arm-embedded
Answer from fferri on Stack OverflowHi,
I have been writing a CPP application that uses cmake that is mainly designed to run on Linux ARM but can be run on anything (including Mac) as it has hardware abstraction layers.
To date I develop on Mac and can build and run the application and unit tests on Mac. But when I want to build it for Linux ARM I move over to my old cheap windows laptop and use WSL to build it for ARM. This is painful and the laptop is very slow.
What is the best (lightweight) way to build for Linux ARM on Mac? I have a 2016 MacBook Pro that uses an Intel chip.
I have looked into the ARM toolchains here: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
But they are only suitable for bare metal targets, my OrangePi runs Linux so I don't think that is suitable.
I had thought of docker, so I could have a Linux container to do it, but its a pretty big install these days and having to run a VM in the background just seems excessive for wanting to do the odd build, but maybe there is no other better alternative.
Thanks!
Cross compiling to non-ARM targets - Apple Community
Cross-compiling from macOS to ARM
c - Build Apple Silicon binary on Intel machine - Stack Overflow
How to cross compile for Apple M1 host on linux x86_64 build machine?
Install homebrew, brew cask and then:
brew cask install gcc-arm-embedded
In the directory build-gcc/gcc, there exists an as script file to be invoked instead of the /usr/bin/as. When I renamed as to as_temp, and rerun, everything works fine.
The environmental variable AS=/usr/bin/as does not seem to solve this issue.
I needed one more modification that /opt/cross/arm-elf-eabi/sys-root/usr/include should be created in order to prevent another error message.
I also found that this site is pretty useful in cross compilation on Mac OS X.
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.out
a.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.
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/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...]
The 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
I have an x86_64 device running Ubuntu 18.04. How would I go about cross compiling for MacOS M1 chip?
Would I need to build in a MacOS docker image with an aarch64 clang toolchain?
Any guidance would be appreciated. Most of what I see online is how to compile native for M1, but not much on cross compiling.
As an extension, how would I compile for the M1 chip on a x86_64 mac? Would I just need to install the aarch64 clang toolchain and use that?
After the answer to Siguza, the difficult part was to find a linker that could do the job.
This is what finally worked for me.
Install macos cross toolchain with:
brew install aarch64-unknown-linux-gnu
After that I have this binary that can be added to PATH:
/opt/homebrew/Cellar/aarch64-unknown-linux-gnu/11.2.0/bin/aarch64-unknown-linux-gnu-ld
Then I could build the binary with:
clang --target=arm64-linux-gnu -fuse-ld=aarch64-unknown-linux-gnu-ld hello.s -nostdlib
And I could verify the binary by using this Dockerfile:
FROM scratch
ADD a.out /bin/
ENTRYPOINT ["/bin/a.out"]
Build a container with:
docker build -t app .
Run it and get the output:
docker run app
Hello World!
You will need lld or some other linker that can output ELF binaries, as Xcode only ships with Apple's ld64, which is limited to Darwin targets. Once you have lld in your path, you can build your assembly file with:
clang --target=arm64-linux-gnu -fuse-ld=lld hello.s -nostdlib
Of course, if you want to use libraries or eventually compile C code and include header files, you will have to either find or build an SDK to pass to clang with --sysroot. I'm not aware of any standard process for doing this, but I've had some success with just pulling public deb files from Ubuntu/Debian package mirrors and unpacking them into one folder.