查看源代码 mix escript.build (Mix v1.16.2)

为项目构建 escript。

escript 是一个可以在命令行中调用的可执行文件。escript 可以运行在任何安装了 Erlang/OTP 的机器上,并且默认情况下不需要安装 Elixir,因为 Elixir 作为 escript 的一部分被嵌入其中。

此任务保证项目及其依赖项被编译,并将它们打包到 escript 中。在调用 mix escript.build 之前,只需要在你的 mix.exs 文件中定义一个带有 :main_module 选项的 :escript 键。

escript: [main_module: MyApp.CLI]

escript 应该用作在开发人员之间共享脚本的机制,而不是用作部署机制。对于运行实时系统,请考虑使用 mix run 或构建发布。有关系统生命周期的更多信息,请参见 Application 模块。

config/config.exs 中定义的所有配置都将作为 escript 的一部分包含在内。对于 Elixir escript,还会包含 config/runtime.exs。加载配置后,此任务将启动当前应用程序。如果不需要这样做,请将 :app 配置设置为 nil。

此任务还会从编译的 .beam 文件中删除文档和调试块,以减小 escript 的大小。如果不需要这样做,请查看 :strip_beams 选项。

priv 目录支持

escript 不支持需要从 priv 目录存储或读取工件的项目和依赖项。

命令行选项

期望与 mix compile 相同的命令行选项。

配置

以下选项必须在你的 mix.exs 中的 :escript 键下指定

  • :main_module - escript 启动后要调用的模块。该模块必须包含一个名为 main/1 的函数,该函数将接收命令行参数。默认情况下,参数将作为二进制列表给出,但如果项目配置为 language: :erlang,则它将是字符列表。

可以指定其余选项以进一步自定义 escript

  • :name - 生成的 escript 的名称。默认为应用程序名称。

  • :path - 写入 escript 的路径。默认为应用程序名称。

  • :app - 随 escript 启动的应用程序。默认为应用程序名称。如果不需要启动任何应用程序,请将其设置为 nil

  • :strip_beams - 如果为 true,则会剥离 escript 中的 BEAM 代码,以移除运行时不需要的块,例如调试信息和文档。可以将其设置为 [keep: ["Docs", "Dbgi"]] 以剥离并保留其他情况下将被剥离的一些块,例如文档和调试信息。默认为 true

  • :embed_elixir - 如果为 true,则会将 Elixir 及其子应用程序(ex_unitmix 等)嵌入到 mix.exsapplication/0 函数中提到的 :applications 列表中。

    对于 Elixir 项目,默认为 true,对于 Erlang 项目,默认为 false

    注意:如果将此选项设置为 false 且项目是 Elixir 项目,则在运行生成的 escript 时,需要将路径添加到 Elixir 的 ebin 目录到 ERL_LIBS 环境变量中,以便代码加载器能够找到 :elixir 应用程序及其子应用程序(如果使用)。

  • :shebang - 用于执行 escript 的 shebang 解释器指令。默认为 "#! /usr/bin/env escript\n"

  • :comment - escript 中 shebang 指令后要跟随的注释行。默认为 ""

  • :emu_args - 要嵌入 escript 文件中的模拟器参数。默认为 ""

有一个项目级选项会影响 escript 的生成方式

  • language: :elixir | :erlang - 对于由 Mix 管理的 Erlang 项目,将其设置为 :erlang。这样做将确保默认情况下不会嵌入 Elixir。你的应用程序仍然会作为 escript 加载的一部分启动,并使用构建期间使用的配置。

示例

在你的 mix.exs

defmodule MyApp.MixProject do
  use Mix.Project

  def project do
    [
      app: :my_app,
      version: "0.0.1",
      escript: escript()
    ]
  end

  def escript do
    [main_module: MyApp.CLI]
  end
end

然后定义入口点,例如在 lib/cli.ex 中定义以下内容

defmodule MyApp.CLI do
  def main(_args) do
    IO.puts("Hello from MyApp!")
  end
end