Chapter 13. Cross compiling

Erlang.mk supports cross-compiling. While the compiled Erlang code is portable as-is, the C code is not and releases need to use the correct runtime system for the target environment.

There are therefore two steps that might require some intervention: compiling and building the release. If you do not have any C code you can just compile as you would normally, however.

13.1. Compiling

To cross-compile the C code you need a cross compiler. If you were to target Windows from an Arch Linux machine you would install the mingw-w64-gcc package. You would then need to define the CC environment variable to point to this compiler instead of the default:

CC=/usr/bin/x86_64-w64-mingw32-gcc

Additionally, on Windows the shared libraries use a different extension than on Linux, so it needs to be specified as well:

C_SRC_OUTPUT_SHARED_EXTENSION=.dll

These values can be added to the Makefile or given from the command line, for example:

$ CC=/usr/bin/x86_64-w64-mingw32-gcc C_SRC_OUTPUT_SHARED_EXTENSION=.dll make
 DEPEND my_nif.d
 ERLC   my_nif.erl
 APP    my_nif
 C      my_nif.c
 LD     my_nif.dll
$ file priv/my_nif.dll
priv/my_nif.dll: PE32+ executable (DLL) (console) x86-64, for MS Windows

You could also add this configuration to your Makefile hidden behind a flag:

ifdef WINDOWS_BUILD
CC = /usr/bin/x86_64-w64-mingw32-gcc
C_SRC_OUTPUT_SHARED_EXTENSION = .dll
endif

And then just compile like this:

$ make WINDOWS_BUILD=1

13.2. Building the release

For the release there are two options. You can either include the correct runtime system directly in the release; or you can not include the runtime system in the release and instead let it use the one installed in the target environment.

To include the target runtime system, add the include_erts tuple to your relx.config file:

{include_erts, "/path/to/alternate/erlang"}.

If you were to target Windows for example, you could copy the Erlang installation from the Program Files directory and then configure relx.config like this:

{include_erts, "/path/to/erl10.1"}.

You need to make sure that the runtime system version you will use is capable of running the compiled Erlang code you used to build your project, otherwise it will fail to run.

If you choose to not include the runtime system at all, configure relx.config as follow:

{include_erts, false}.

In that case the runtime system needs to be available in the $PATH of the target environment.