Skip to content

Latest commit

 

History

History
119 lines (83 loc) · 3.65 KB

INSTALL-IOS.md

File metadata and controls

119 lines (83 loc) · 3.65 KB

Cross Compiling Erlang/OTP - IOS

Introduction

This document describes how to cross compile Erlang/OTP to iOS platforms. iOS has the peculiarity that it does not support the creation of shared libraries. So the build process needs to be amended to generate statically linkable and executable Erlang binaries.

Get Xcode Tools

iOS binaries can only be cross-compiled from Apple macOS computers. For compilation the Xcode tools must be used.

Environment Variables

In order to inform the build system that it should generate the static linkable libbeam.a add the following environment variable during configuration and compilation:

$ export RELEASE_LIBBEAM=yes

Configure Erlang/OTP

To build without OpenSSL support, run `configure` like this:

$ ./otp_build configure \
     --xcomp-conf=./xcomp/erl-xcomp-arm64-ios.conf  \
     --without-ssl

To build with OpenSSL statically linked, run configure like this (note that 1.1.1k works, but needs a manual patch in ios cross build config to include engines):

$ ./otp_build configure \
     --xcomp-conf=./xcomp/erl-xcomp-arm64-ios.conf  \
     --with-ssl=/path/to/libcrypto.a \
     --disable-dynamic-ssl-lib

Compile Erlang/OTP

$ ./otp_build boot

Linking a binary with your App

To use the resulting libbeam.a it needs to be packaged into a Xcode .xcframework package together with all other required .a files. These include:

  • libbeam.a
  • libz.a
  • libcrypto.a

Basically all .a files that have been generated by the build.

One way of creating a combined archive out of all of these is to use libtool:

$ libtool -static -o liberlang.a /Path/to/libbeam.a /Path/to/....a

This list should also include static nifs you want to include:

Finally packaging the archive into a .xcframework directory:

$ xcodebuild -create-xcframework -output ./liberlang.xcframework -library liberlang.a

If you're building for multiple iOS targets (e.g. simulator and phone):

$ xcodebuild -create-xcframework -output ./liberlang.xcframework -library /Path/to/phonelib/liberlang.a -library /Path/to/simulatorlib/liberlang.a

Starting Erlang

To execute erlang from within an iOS project a native C/C++ wrapper is needed that can call the function:

erl_start(int argc, char *argv[]); 

An example call could look like this:

$ const char *args[] = {
        "my_main",
        "-sbwt",
        "none",
        "--",
        "-root",
        root_dir.c_str(),
        "-progname",
        "erl",
        "--",
        "-home",
        home_dir.c_str(),
        "--",
        "-kernel",
        "shell_history",
        "enabled",
        "--",
        "-start_epmd",
        "false",
        "-elixir",
        "ansi_enabled",
        "true",
        "-noshell",
        "-s",
        "elixir",
        "start_cli",
        "-mode",
        "interactive",
        "-config",
        config_path.c_str(),
        "-boot",
        boot_path.c_str(),
        "-boot_var",
        "RELEASE_LIB",
        lib_path.c_str(),
        "--",
        "--",
        "-extra",
        "--no-halt",
};

erl_start(sizeof(args) / sizeof(args[0]), (char **)args);

Reference Example

At the time of writing (October 2021) there is a full reference iOS application available at https://github.com/elixir-desktop/ios-example-app.

An implementation of the native wrapper can be viewed at https://github.com/elixir-desktop/ios-example-app/blob/main/native-lib.cpp.