はじめに
Nerves プロジェクトを触っていると、MIX_TARGET という単語をよく目にします。
なんとなく設定してはいるものの、そもそもこれは何なのか深く考えたことがありませんでした。
自分用のメモとして、基本だけをサッと整理してみました。
Mix について
Mix is a build tool that provides tasks for creating, compiling, and testing Elixir projects, managing its dependencies, and more.
— Mix – Hexdocs
Elixir に標準で組み込まれている ビルドツールが Mix です。
以下のような役割を担っています:
- プロジェクトの作成 (
mix new) - 依存関係の管理 (
mix deps.get) - コンパイル・テストの実行 (
mix compile,mix test) - カスタムタスクの定義(例:
mix firmware)
Nerves プロジェクトでも mix コマンドが多用されており、その振る舞いには MIX_TARGET が関わってきます。
Mix Target とは
Besides environments, Mix supports targets. Targets are useful when a project needs to compile to different architectures and some of the dependencies are only available to some of them.
— Mix – Hexdocs
Mix には「ターゲット(target)」という概念があります。
これは、ビルド対象のプラットフォーム(ホストOSやCPUアーキテクチャなど)に応じて処理や依存関係を切り替える仕組みです。
- デフォルト値は
:host - 環境変数
MIX_TARGETにより指定 - 現在のターゲットを取得するには:
Mix.target/0 - ターゲットを明示的に設定するには:
Mix.target/1 - 実装: elixir-lang/elixir@v1.19.4
Nerves のように 複数のハードウェア向けにビルドする必要があるプロジェクトでは、この仕組みが特に重要になります。
Nerves における Mix Target
Nerves supports a variety of hardware. These are called targets and are identified by short tag names. Examples of tag names are
rpi0,bbb, etc.
— Nerves: Supported Targets
Nerves では、Raspberry Pi や BeagleBone など様々なハードウェアに対応しています。
これらのプラットフォームは ターゲット(target) と呼ばれ、短いタグ名(例:rpi0, rpi3, bbb)で識別されます。
プロジェクトをビルドする際には、環境変数 MIX_TARGET にこのタグ名を指定することで、適切な依存関係や設定ファイルが使われるようになります。
$ MIX_TARGET=rpi3 mix firmware
この例では、Raspberry Pi 3 向けのファームウェアをビルドしています。
Nerves のプロジェクトでは、config/ ディレクトリ配下に target.exs を用意しておくことで、ターゲットごとに設定を分離・管理することも可能です。
実行時に MIX_TARGET を参照できるか?
結論から言うと、実行時には MIX_TARGET を直接参照できません。
MIX_TARGET はビルドツールである Mix の概念であり、ビルド時にのみ有効な環境変数です。
そのため、以下のように Mix.target/0 を IEx(実行時環境)で呼び出しても、エラーになります:
iex> Mix.target
** (ArgumentError) errors were found at the given arguments:
* 1st argument: the table identifier does not refer to an existing ETS table
(stdlib 7.1) :ets.lookup(Mix.State, :target)
lib/mix/state.ex:30: Mix.State.get/2
iex:1: (file)
Mix はビルド時専用ツールとして動作しており、実行時にはロードされないため、ターゲット情報も参照できません。
実行時にターゲット情報を取得するには?
MIX_TARGET はビルド時限定の環境変数ですが、Nerves ではビルド時のターゲット情報をランタイムに引き継ぐ仕組みが用意されています。
それが Nerves.Runtime.mix_target/0 です。
iex(1)> Nerves.Runtime.mix_target()
:rpi3
この関数により、現在動作しているファームウェアがどのターゲット向けにビルドされたかを実行時に取得できます。
裏では Nerves.Runtime.KV に保存された key-value を参照しています。
この KV はビルド時に埋め込まれる情報で、ランタイムから安全にアクセスできます。
おわりに
MIX_TARGET は、ビルド対象のプラットフォームを指定するための環境変数です。
Elixir/Mix に元々備わっている機能で、Nerves プロジェクトではこれを活用して、ハードウェアごとの設定や依存関係を切り替えています。
ビルド時と実行時の区別を意識しておくと、ターゲット別の処理や条件分岐を行う際の戸惑いがなくなります。
![]()
![]()
![]()
