Cross Compile On Linux For Mac
- Mingw Linux Cross Compile
- Cross Compile On Linux For Macbook Pro
- Cross Compile Linux Kernel
- Cross Compile Linux Kernel Module
- Cross Compile On Linux For Macs
Here’s how to create your own, shiny ARM gcc cross-compile toolchain for your Mac. A cross-compile toolchain enables to compile code for a different hardware architecture than the development system. We will be using the Intel/macOS to generate ARM/Linux (Cortex-Axx CPUs) or ARM/bare-metal (Cortex-Mxx Microcontrollers) code. Since the ARM architecture is omnipresent these days in UAV work, this is kind of handy to have working. Trivial to do on Linux as a host system, but our trusty Mac needs some special treatment.
The tool to use is crosstool-ng, which is designed to compile the gcc toolchain for various architectures. The main audience for the tool is Linux, but it works fine on the Mac with a few tricks. There are other sources of information on this topic, but they deal with older versions of macOS and crosstool-ng
Cross compilation issues¶. In GCC world, every host/target combination has its own set of binaries, headers, libraries, etc. So, it’s usually simple to download a package with all files in, unzip to a directory and point the build system to that compiler, that will know about its location and find all it needs to when compiling your code.
Using these two, we can compile a program in a Mac that will run on that Linux like this: crystal build yourprogram.cr -cross-compile -target 'x8664-unknown-linux-gnu' This will generate a.o ( Object file ) and will print a line with a command to execute on the system we are trying to cross-compile to. To cross-compile cgo projects you can set the CC and CXX environment flags when building to x8664-linux-musl-gcc and x8664-linux-musl-g (or corresponding), on top of the usual GOOS and GOARCH. To use this toolchain as the target linker for Rust cross-compilation, add lines like these to your.cargo/config. I used the very helpful post on how to build a gcc cross-compiler by Jeff Preshing and his script here as the basis for a script that worked for me. His script in the link doesn't work when compiling glibc on my version of OSX (which seems to be a very common complaint for those cross-compiling from OSX to Linux).
[1][2], so here is an update that works on macOS Sierra with the latest crosstool-ng version. Those other websites are still a good source of information, and well worth visiting in the process. Most of the workarounds listed on these pages are no longer required, but at the time of writing a small number of new hiccups need to be considered.In this tutorial I am using places and paths that I find logical. These can be changed to any other location as desired, of course.
Step 1:
You need X-Code or the command line tools installed to provide build tools on macOS. Nothing that follows will work without it.
Mingw Linux Cross Compile
Step 2:
Some of the macOS build tools are not equivalent to the GNU/Linux versions. Building a beast like gcc, however, requires those extra functionalities. The package manager Homebrew can be used to install those tools quite easily. Other methods might work as well but have not been tested. Convert from pdf to word for mac.
Note: Homebrew contains a formula to install crosstool-ng 1.22. This is outdated and does not work on macOS at the time of writing. So we need to build the tool from the git master for now.
So you need to install Homebrew, which is quite easy. Then install the following packages:
- autoconf
- automake
- libtool
- help2man
- coreutils
- binutils
- wget
- gnu-sed
- gawk
- libelf
- make
- grep
Some of these tools have their equivalent in macOS, so Homebrew installs them with a prefix g, so make becomes gmake and so on. Crosstool-ng is set up nicely to find these alternate versions for you during building. However in the current version (Feb. 2017) is one remaining bug that requires this knowledge.
Step 3:
gcc is a Linux tool and Linux uses case sensitive file systems by default. The Mac does not. So trying to build gcc on the standard Mac disk will inevitably fail. So we need to create a case sensitive disk somehow. Luckily, this is actually quite easy with disk utility. Check out [1] on how to do that. Basically, you want to create a sparse disk image with case sensitive file system somewhere on your disk. Be aware that disk utility actually changes the file system properties as you set the options, so make sure that it is set to case sensitive file system before creating the image.
Step 4:
Create a directory to build crosstools-ng. This can be anywhere on the Mac disk, or in the newly created disk image. Crosstool-ng does not require a case sensitive file system. The clone the git repository into this directory
This creates the directory crosstool-ng, containing the source code. Enter that folder and issue
to generate the configuration scripts. Then we will need to decide where we want to install the crosstool executable. I find it sensible to install it into the build disk image to have it all in one spot. To do that, issue
where I choose PATH_TO_INSTALL_DIR to be /Volumes/ct-ng/ct-ng in the build disk image. This will make and install crosstool-ng in that directory. Any errors will indicate that some of the previous instructions did not succeed. Checking the output of the configuration step might show that some of the GNU/Linux tools were not recognised correctly. You’ll need to verify the Homebrew installation of those tools in this case. If all went well, there should be a working version of crosstool-ng in the INSTALL_DIR.
Step 5:
To try it out, navigate to that directory and issue
to generate the configuration for one of the per-defined builds as a test case. Then
to enter the build configuration menu. This is the same as used for the Linux kernel. In there, we need to change the default locations of the download- and output directories to point into the case sensitive disk image (the download directory doesn’t need to be there but again, it keeps things organised. Then issue
to build the toolchain. (The ulimit command increases the number of open files allowed, otherwise the build will fail just before the end…)
This will fail immediately, but no worries, the information printed will allow us to fix the problem. As mentioned before, some of the tools installed by Homebrew have the prefix g. And this is the bug in crosstools, where in one file this is not set correctly. Everywhere else it is, so do not try to rename to tool (sed), but make a small change in one of the source files of crosstool. This might get fixed soon as there is an issue open on Github for this. But for now, we need to go into the file printed in the error message (/scripts/functions) and change the broken command (line number given in the error msg) from sed to gsed. Then save the file and try the build again. All should be working fine now. The build will take 40 minutes or so. Once done, there should be a ARM-gcc toolchain in the x-tools directory.
Update [27/02/2017]: This problem appears to be fixed, at least based on my limited testing over the past few days.
Step 6:
To use the toolchain, set the compiler path to
and use the gcc command
to compile the code.
This covered just the basic procedure. When it all works, the toolchain can be configured more specifically to the hardware target using the menuconfig system. This might be the topic of another article.
This document contains instructions to build AVR and ARM cross compilers on Mac OS X from source packages. Note, that precompiled binaries are available in our download area.
So far, only the ARM toolchain had been tested on Leopard, running on a PPC. Be warned, that building on other OS X releases or building the AVR toolchain may not work as described.
Installing Xcode
Apple's Xcode package contains all the tools we need to build the cross toolchain. Open Terminal and enter
If the response is similar to
then GCC is already available and probably there is no need to install it again. However, if the response is
then you need to download Xcode from
developer.apple.com/tools/xcode/
A registration is required, but this is free of charge.
Leave the Terminal window open. We'll need it later on.
Download Toolchain Sources
In the Terminal window create a new directory and change to it. Feel free to use any name and create it at any place.
Now use the following commands to download the sources.
Additionally we need the C libraries, avr-libc for the AVR or newlib for the ARM platform. Get the newlib sources with
The avr-libc sources can be downloaded with
Next we unpack the sources, using
and
for the AVR library or
for the ARM library. Note the different option -xzf for the gzipped newlib. Each command takes at least several seconds to execute.
We will finally end up with 3 new subdirectories in our toolcahin folder. You may remove the downloaded archives or keep them in case you want to start all over again later on.
Build Environment Setup
The toolchain will be built in 5 steps:
- Building the binary utilities
- Building the compiler
- Building the libraries
- Rebuilding the compiler (ARM)
- Building the debugger
In the second step we get different results while building for AVR or ARM. For ARM targets we are building an intermediate compiler first, which is rebuilt in step 4.
The last step, building GDB, is optional and needed for in-circuit debugging only. This requires some additional tools, which are not discussed in this document.
In all steps we are going to use the same environment. Thus, once set in the Terminal window, you need to keep the window open to preserve these settings.
First we specify the target platform:
for the AVR or
for the ARM toolchain. For both targets we set
which defines the directory where the final binaries will be installed. If you prefer any different location, go ahead. Within this folder we need to create a bin directory in advance and add that to our PATH variable.
Note, that we need root authorization to access the path /usr/local, which had been stored in the variable $prefix. Thus the prepended sudo command, which will prompt you for your user password. If you chose a different location, this may not be required.
Building the Binary Utilities
GNU binutils is a collection of binary tools, which needs to be build first. As with all parts of the toolchain, we create a specific build directory inside the package's directory.
The next command, which configures the build, differs slightly among targets. For the AVR we simply use
while the ARM requires
When this went through without errors, we can start building and installing the binaries.
This will take several minutes. When done, try
to check the AVR build or
to check the ARM variant.
This should display the GNU assembler version information. If the command can't be found, check your PATH and prefix settings.
Building the Compiler
Building the ARM compiler requires a readily built library. Building the newlib library, however, requires a compiler. To solve this chicken and egg problem, we build an intermediate bootstrap compiler first, which requires the library's header files only. For the AVR, however, the final compiler is built in this step.
Cross Compile On Linux For Macbook Pro
For both targets, create a build directory and change to it.
As expected, the configure options differ among our targets. For the AVR use
The intermediate ARM compiler is configured as follows.
Note, that we may need the sudo command to gain access to the installation directory, where the newlib header files will be copied to.

Building and installing the AVR compiler is done using the standard commands.
To build and install the intermediate ARM compiler use
Again, this will take several minutes. When done, we can use
to test the AVR compiler or
for the ARM compiler. This should display the compiler version information.
If the build fails, you may try to exclude the C++ compiler by simply removing ,c++ from the --enable-languages option.
Building the Libraries
As stated earlier, we use avr-libc for the AVR and newlib for the ARM.
To configure the AVR build, use
Note the grave accents, acute accents will not work.
The following commands are used to configure the ARM library.
Both libraries are built with
Rebuilding the Compiler
As explained above, this step is only required when building for the ARM target.
Building the Debugger
Even if we do not have all tools available for in-circuit debugging, it is a good idea to build the GNU debugger now, so it will be available later. Here are the related commands, valid for both targets:
Stripping the Binaries
In an additional step we may strip the installed binaries to save disk space and decrease load times.
What's Next?
Now we have all tools available on our OS X machine to create firmware binaries for AVR and/or ARM target boards, either from C, C++ or assembler source code.
If you want to compile applications running on Nut/OS, you may now download the Ethernut package from the local download page.
Selecting a tool for uploading firmware binaries to your target board highly depends on the specific CPU and the programming adapter being used. For AVR targets, AVRDUDE is a good choice, while we recommend OpenOCD for ARM targets.

The document OpenOCD and Ethernut 3 contains additional information about installing and running OpenOCD on a Mac.
Finally you may want to set up an integrated development environment, which includes a source code editor, compiler, linker, debugger and more. If you are already familiar with Xcode, this might be the right way to go. If you are, like me, working on several different platforms, then Eclipse is probably a good choice.
External Links
dirkraffel.wordpress.com/2008/02/22/building-a-gnu-arm-cross-compiler-toolchain-on-mac-os-x/
Building a GNU ARM cross-compiler toolchain on Mac OS X.
www.nslu2-linux.org/wiki/HowTo/SetUpAToolChainOnAMac
Describes another way to set up an ARM toolchain on Mac OS X.
Cross Compile Linux Kernel
www.cocoamachine.com/blog/
Blog about setting up a cross development for the iPhone, which is based on an ARM CPU.
developer.apple.com/tools/xcode/
Xcode is Apple's premiere development environment for Mac OS X.
gcc.gnu.org/
Homepage of the GNU Compiler Collection.
www.gnu.org/software/binutils/
GNU Binutils' homepage.
sourceware.org/gdb/
GDB, the GNU Project Debugger.
Cross Compile Linux Kernel Module
www.eclipse.org/
An open development platform based on Java.
savannah.nongnu.org/projects/avrdude/
AVRDUDE is software for programming Atmel AVR Microcontrollers.
Cross Compile On Linux For Macs
openocd.sourceforge.net
The Open On-Chip Debugger aims to provide debugging, in-system programming and boundary-scan testing for ARM based target devices.