檢視原始碼 mix compile.app (Mix v1.16.2)

撰寫 .app 檔案。

.app 檔案是一個包含 Erlang 項目的檔案,用於定義您的應用程式。Mix 會根據您的 mix.exs 設定自動產生這個檔案。

為了產生 .app 檔案,Mix 預期您的專案同時有 :app:version 鍵。此外,您可以在 mix.exs 中定義一個 application/0 函式來設定產生的應用程式,該函式會傳回一個關鍵字清單。

最常使用的鍵為

  • :extra_applications - 您的應用程式所依賴、但未包含在 :deps 中的 OTP 應用程式清單(通常定義在 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

以及一個範例 :my_included_app 在其 mix.exs 中定義函式

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, [])