Packages
mob_dev
0.5.13
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.37
0.3.35
0.3.34
0.3.33
0.3.28
0.3.26
0.3.23
0.3.21
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.18
0.2.17
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Development tooling for the Mob mobile framework
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/mob.release.openssl.ex
defmodule Mix.Tasks.Mob.Release.Openssl do
@shortdoc "Build OpenSSL + crypto NIF static archives for one Mob release target"
@moduledoc """
Drives the OpenSSL cross-compile + the OTP crypto NIF static archive
for one target — replaces running `scripts/release/openssl/<plat>.sh`
and `scripts/release/openssl/build_crypto_static_<plat>.sh` in
sequence.
mix mob.release.openssl android_arm64 # one target
mix mob.release.openssl android_arm32
mix mob.release.openssl ios_sim
mix mob.release.openssl ios_device
mix mob.release.openssl all # all four, sequentially
## What runs
For each target:
1. `MobDev.Release.OpenSSL.build/2` — cross-compile OpenSSL 3.x,
produces `<prefix>/lib/libcrypto.a` + headers.
2. `MobDev.Release.OpenSSL.CryptoNif.build/2` — compile OTP's
crypto NIF C sources with `-DSTATIC_ERLANG_NIF`, archive as
`<otp_src>/lib/crypto/priv/lib/<arch>/crypto.a`, verify the
`crypto_nif_init` symbol is exported.
Both steps are required for the release tarball (handled in iter 4
by `mix mob.release.tarball`); this task just produces the two
artefacts and stops.
## Options
* `--openssl-src PATH` — OpenSSL source checkout. Default:
`$OPENSSL_SRC` env or `~/code/openssl`.
* `--otp-src PATH` — OTP source checkout. Default: `$OTP_SRC` env
or `~/code/otp`.
* `--prefix PATH` — OpenSSL install prefix. Default per-target:
`/tmp/openssl-<target>`.
* `--ndk-root PATH` — Android NDK root (Android targets only).
Default: `~/Library/Android/sdk/ndk/<recommended-version>`.
## Errors
Failure produces a tagged `MobDev.Release.Errors` tuple formatted
via `Mix.raise/1`. Common failure modes:
* `precondition failed — OPENSSL_SRC missing` — clone openssl/openssl
* `precondition failed — Android NDK not at <path>` — check NDK install
* `precondition failed — iOS iphonesimulator SDK not available` —
run `xcode-select --install`
* `command failed (exit N)` — actual tool error, output in the
raised message
"""
use Mix.Task
alias MobDev.Release.{Errors, OpenSSL}
alias OpenSSL.CryptoNif
@valid_targets [
"android_arm64",
"android_arm32",
"ios_sim",
"ios_device",
"all"
]
@switches [
openssl_src: :string,
otp_src: :string,
prefix: :string,
ndk_root: :string
]
@impl Mix.Task
def run(args) do
{opts, positional, _} = OptionParser.parse(args, strict: @switches)
case positional do
[target_str] when target_str in @valid_targets ->
targets =
if target_str == "all" do
OpenSSL.targets()
else
[String.to_atom(target_str)]
end
Enum.each(targets, &run_one(&1, opts))
[bad] ->
Mix.raise("unknown target: #{bad}\nvalid: #{Enum.join(@valid_targets, ", ")}")
[] ->
Mix.raise("missing target argument\nusage: mix mob.release.openssl <target>")
_ ->
Mix.raise("too many arguments — pass exactly one target")
end
end
defp run_one(target_id, opts) do
Mix.shell().info("==> OpenSSL #{target_id}")
case OpenSSL.build(target_id, build_opts(opts, target_id)) do
{:ok, info} ->
Mix.shell().info(" ✓ libcrypto.a → #{info.libcrypto}")
run_crypto_nif(target_id, info, opts)
{:error, _} = err ->
Mix.raise(Errors.format(err))
end
end
defp run_crypto_nif(target_id, openssl_info, opts) do
Mix.shell().info("==> crypto NIF #{target_id}")
crypto_opts =
opts
|> build_opts(target_id)
|> Keyword.put(:openssl_prefix, openssl_info.prefix)
|> Keyword.drop([:openssl_src, :prefix])
case CryptoNif.build(target_id, crypto_opts) do
{:ok, info} ->
Mix.shell().info(" ✓ crypto.a → #{info.archive}")
{:error, _} = err ->
Mix.raise(Errors.format(err))
end
end
defp build_opts(opts, _target_id) do
opts
|> Keyword.take([:openssl_src, :otp_src, :prefix, :ndk_root])
|> Enum.reject(fn {_k, v} -> is_nil(v) end)
end
end