查看源代码 mix compile.app (Mix v1.16.2)

写入 .app 文件。

一个 .app 文件是一个包含 Erlang 项的文件,用于定义您的应用程序。 Mix 会根据您的 mix.exs 配置自动生成此文件。

为了生成 .app 文件,Mix 期望您的项目同时包含 :app:version 键。此外,您可以通过在您的 mix.exs 中定义一个返回关键字列表的 application/0 函数来配置生成的应用程序。

最常用的键是

  • :extra_applications - 您的应用程序依赖的 OTP 应用程序列表,这些应用程序未包含在 :deps 中(通常在您的 mix.exs 中的 deps/0 中定义)。例如,您可以在此处声明对 Erlang/OTP 或 Elixir 附带的应用程序的依赖关系,例如 :crypto:logger。可选的额外应用程序可以声明为元组,例如 {:ex_unit, :optional}。Mix 保证所有非可选应用程序在您的应用程序启动之前启动。

  • :registered - 应用程序中所有已注册进程的名称。如果您的应用程序定义了一个名为 MyServer 的本地 GenServer,建议将 MyServer 添加到此列表中。这在检测注册相同名称的应用程序之间的冲突时最为有用。

  • :env - 应用程序环境的默认值。应用程序环境是配置应用程序最常见的方法之一。有关读取和写入应用程序环境的机制,请参阅 Application 模块。

例如

def application do
  [
    extra_applications: [:logger, :crypto, ex_unit: :optional],
    env: [key: :value],
    registered: [MyServer]
  ]
end

其他选项包括

  • :applications - 您的应用程序在运行时依赖的所有应用程序。默认情况下,此列表会从您的依赖项中自动推断。Mix 和其他工具使用应用程序列表在启动应用程序本身之前启动其依赖项。

  • :mod - 指定在启动应用程序时调用的模块。它必须采用 {Mod, args} 格式,其中 args 通常是一个空列表。指定的模块必须实现由 Application 模块定义的回调。

  • :start_phases - 指定在应用程序启动后调用的阶段列表及其参数。请参阅下面的“阶段”部分。

  • :included_applications - 指定将包含在应用程序中的应用程序列表。主要应用程序负责启动所有包含应用程序的监督树,因为只有主要应用程序才会启动。包含应用程序中的进程认为自己属于主要应用程序。

  • :maxT - 指定允许应用程序运行的最长时间,以毫秒为单位。如果达到 :maxT,则应用程序将停止,其顶级主管将以原因 :normal 终止。此阈值在任何资源文件中都是技术上有效的,但仅对具有回调模块的应用程序有效。默认值为 :infinity

除了上述选项之外,.app 文件还期望其他选项,例如 :modules:vsn,但这些选项由 Mix 自动添加。完整的列表可以在 Erlang 的应用程序规范 中找到。

命令行选项

  • --force - 无论修改时间如何,都强制编译
  • --compile-path - 用于查找 .beam 文件和写入生成的 .app 文件的位置,默认为 Mix.Project.compile_path/0

阶段

应用程序提供一个启动阶段机制,该机制将按顺序为应用程序及其所有包含的应用程序调用。如果未为包含的应用程序定义阶段,则该应用程序将被跳过。

让我们看一个 MyApp.application/0 函数示例

def application do
  [
    start_phases: [init: [], go: [], finish: []],
    included_applications: [:my_included_app]
  ]
end

以及一个在 mix.exs 上定义了函数 :my_included_app 的示例

def application do
  [
    mod: {MyIncludedApp, []},
    start_phases: [go: []]
  ]
end

在此示例中,应用程序回调的调用顺序为

Application.start(MyApp)
MyApp.start(:normal, [])
MyApp.start_phase(:init, :normal, [])
MyApp.start_phase(:go, :normal, [])
MyIncludedApp.start_phase(:go, :normal, [])
MyApp.start_phase(:finish, :normal, [])