I’m looking to build an escript in an Elixir Umbrella project. I’ve got two sibling apps Compressor and Printer
Compressor depends on the snappyer package which is a nif wrapper around the google’s snappy compression algorithm.
# apps/compressor/mix.exs
defmodule Compressor.MixProject do
# ..
defp deps do
[
{:snappyer, "~> 1.2.4"},
]
end
end
# apps/compressor/lib/compressor.ex
defmodule Compressor do
def compress(message) do
:snappyer.compress(message)
end
end
Printer requires Compressor, compresses some data and prints the result.
# apps/printer/mix.exs
defmodule Printer.MixProject do
# ..
def project do
[
app: :printer,
version: "0.1.0",
build_path: "../../_build",
config_path: "../../config/config.exs",
deps_path: "../../deps",
lockfile: "../../mix.lock",
elixir: "~> 1.7",
escript: escript(),
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
defp escript do
[main_module: Printer.CLI]
end
defp deps do
[
{:compressor, in_umbrella: true},
]
end
end
# apps/printer/lib/printer/cli.ex
defmodule Printer.CLI do
def main(args \\ []) do
IO.inspect Compressor.compress(<<1, 2, 3>>)
end
end
When I run Printer.CLI.main([])
through mix it prints the result as expected
$ mix run -e "Printer.CLI.main([])"
{:ok, <<3, 8, 1, 2, 3>>}
However when I run it through an escript it fails with:
$ cd apps/printer && mix escript.build && ./printer
Generated escript printer with MIX_ENV=dev
** (UndefinedFunctionError) function :snappyer.compress/1 is undefined (module :snappyer is not available)
(snappyer) :snappyer.compress(<<1, 2, 3>>)
(printer) lib/printer/cli.ex:3: Printer.CLI.main/1
(elixir) lib/kernel/cli.ex:105: anonymous fn/3 in Kernel.CLI.exec_fun/2
Are escripts allowed in sibling umbrella apps? If not are there any known work arounds?
Here's the minimal, complete, and verifiable example .