LoginSignup
22
20

More than 5 years have passed since last update.

mix compile中に任意のコンパイル処理をする

Posted at

結論

  • mix compileは複数のcompile.*タスクから成る。
  • 自前のcompile.hogehogeタスクもcompileタスクに組み込むことができる。
  • コンパイルのタイミングはmix.exsで指定する。
Code.require_file "lib/mix/tasks/compile.hogehoge.ex"

defmodule MyAwesomeApp.Mixfile do
  use Mix.Project

  def project do
    [app: :my_awesome_app,
     version: "0.0.1",
     elixir: "~> 1.0",
     compilers: [:hogehoge, :elixir, :app],
     deps: deps]
  end

  # 略
end

説明

何したい

例えばNIFなど、Cで書いた関数を使うElixirモジュールを作りたいとする。そのElixirモジュールはCの関数に依存するわけなので、Elixirモジュールのコンパイルの前にはCのコンパイルが済んでいてほしい。自分でやるなら勝手にどうぞって感じだけど、他人にライブラリとして提供する場合はそうもいかない。mix deps.compileのタイミングで、Cのソースもコンパイルしたい。

どうする

mix deps.compile

mix deps.compileは、依存するライブラリを全てコンパイルする。どうやってコンパイルするかは、そのライブラリが持つファイルによって決まる

ファイル コマンド 優先度
mix.exs mix compile
rebar.config rebar compile
Makefile.win nmake /F Makefile.win
Makefile make

Makefileを置いてmakeをさせたいけれど、Mixプロジェクトはmix compileされてしまう。

mix compile

mix compile複数のタスクを実行する。ここにCをコンパイルするタスクを忍ばせる。タスクはcompile.hogehogeのように、compile名前空間になければならない。どのタイミングで実行するかはmix.exsproject/0で指定する。デフォルトのcompilersMix.compilersで取得できるので、それらの前に付ける方法がGithubではよく見られる(特にPhoenixプロジェクト)。

defmodule Mix.Tasks.Compile.Hogehoge do
  use Mix.Task

  def run(_), do: Mix.shell.cmd "make"
end

def MyAwesomeApp.Mixfile do
  def project do
    [app: :my_awesome_app,
     version: "0.0.1",
     elixir: "~> 1.0",
     compilers: [:hogehoge] ++ Mix.compilers,
     deps: deps]
  end
end

これでmix compile時にmakeが走る。ライブラリとして提供した際にもmix deps.compileのときにmakeが走ってNIFが使えるようになる。compile名前空間内なのでコンパイル以外の処理をするのはどうかなー感があるが、Cのコンパイルに限らず任意の処理が可能。

22
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
20