在Elixir伞项目中构建`escript`

时间:2018-08-13 20:22:20

标签: elixir

我正在寻找在Elixir Umbrella project中编写脚本的方法。 我有两个同级应用程序 Compressor Printer

Compressor 取决于snappyer package,它是围绕Google的快速压缩算法的nif包装器。

# 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

打印机需要 Compressor ,压缩一些数据并打印结果。

# 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

当我通过混音运行Printer.CLI.main([])时,它会按预期打印结果

$ mix run -e "Printer.CLI.main([])"
{:ok, <<3, 8, 1, 2, 3>>}

但是,当我通过电子脚本运行它时,它失败并显示:

$  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

兄弟保护伞应用程序中允许使用脚本吗?如果不是,是否有已知的解决方法?

这里是 minimal, complete, and verifiable example

1 个答案:

答案 0 :(得分:0)

我不确定这是否有帮助,但我认为该问题可能与伞式应用无关。我认为该问题是由于您要使用的nif而引起的。

escript docs

  

注意:电子脚本不支持需要从priv目录存储或读取工件的项目和依赖项。

此外,请参见elixir issue的答案:

  

不幸的是,这是手稿的限制。他们无法访问priv中的任何内容,因此无法访问嵌入式.so文件。换句话说,当前无法构建包含NIF的脚本。