elixirができるまで

この記事は [Elixir Advent Calendar 2016](http://qiita.com/advent-calendar/2016/elixir) 3日目の記事です。前日の記事は Joe-nohさんの [ExUnit入門](http://qiita.com/Joe-noh/items/ddd6cf3f38c8f841e90a)です。

# Makefile
## はじめに
今回の記事ですが、冬コミに向けてElixirの中身を一部読んでみたので、そちらの内容を一部記載していきます。
今回の内容ですがMakefileにてElixirがコンパイルされるまでのお話となっています。
Makefileのコードですが、2016年12月時点の最新のもので確認を行っています。

さてMakefileの中身をみていきましょう

## default

````makefile
default: compile

compile: lib/elixir/src/elixir.app.src erlang elixir
````
ElixirのMakefileでは default が一番上なのでデフォルトゴールとなっており、 default で実行される内容は compile のため、単純に make を実施すると compile が実施されます。
compile 自体は、
1. lib/elixir/src/elixir.app.src 
2. erlang 
3. elixir 
の順番に実施されていきますので、まずは、lib/elixir/src/elixir.app.src からみていきます。

## lib/elixir/src/elixir.app.src

````makefile
lib/elixir/src/elixir.app.src: src/elixir.app.src
  $(Q) $(call CHECK_ERLANG_RELEASE)
  $(Q) rm -rf lib/elixir/src/elixir.app.src
  $(Q) echo "%% This file is automatically generated from <project_root>/src/elixir.app.src" \
                               >lib/elixir/src/elixir.app.src
  $(Q) cat src/elixir.app.src >>lib/elixir/src/elixir.app.src
````

lib/elixir/src/elixir.app.src のターゲット内容ですが上記のようになっております。
気にするべきところは cat src/elixir.app.src　>>　lib/elixir/src/elixir.app.src です。

src/elixir.app.src はアプリケーションリソースファイルのテンプレート内容であり、 lib/elixir/src/ のディレクトリには、Elixirを実装するためのErlangのコードが記載されています。

上記のコマンドでアプリケーションリソースファイルのテンプレートを elixir の Erlangコードの箇所にコピーしています。

アプリケーションリソースファイルテンプレートのコピーが終わったので、次は erlang が実行されます。そのコードを見ていきましょう

## erlang

````makefile
erlang:
  $(Q) cd lib/elixir && $(REBAR) compile
````

lib/elixir に移動し、$(REBAR) compileを実施しています。
さて、$(REBAR) の中身には何が記載されているかというとrebarコマンドの場所が記載されております。
そのためrebar を使って Erlangのコードのcompileが実施されます。
ここでrebarなど入れていないっと思われる方もいらっしゃるかもしれませんが、 rebar自体はElixirのコードのトップディレクトリに配置されております。

<img width="992" alt="スクリーンショット 2016-12-03 20.58.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/3014/72271c20-fe24-bd64-2b3f-3ad9999e5360.png">

そのためインストールされてなくてもトップディレクトリにある rebar を使って ElixirのErlangのコードのcompileが実施されるという動きが実施できるわけです。

## elixir

````makefile
elixir: stdlib lib/eex/ebin/Elixir.EEx.beam mix ex_unit logger eex iex

stdlib: $(KERNEL) VERSION
$(KERNEL): lib/elixir/lib/*.ex lib/elixir/lib/*/*.ex lib/elixir/lib/*/*/*.ex
  $(Q) if [ ! -f $(KERNEL) ]; then                  \
    echo "==> bootstrap (compile)";                 \
    $(ERL) -s elixir_compiler core -s erlang halt;  \
  fi
  @ echo "==> elixir (compile)";
  $(Q) cd lib/elixir && ../../$(ELIXIRC) "lib/kernel.ex" -o ebin;
  $(Q) cd lib/elixir && ../../$(ELIXIRC) "lib/**/*.ex" -o ebin;
  $(Q) $(MAKE) unicode
  $(Q) rm -rf lib/elixir/ebin/elixir.app
  $(Q) cd lib/elixir && $(REBAR) compile

unicode: $(UNICODE)
$(UNICODE): lib/elixir/unicode/*
  @ echo "==> unicode (compile)";
  $(Q) cd lib/elixir && ../../$(ELIXIRC) unicode/unicode.ex -o ebin;

$(eval $(call APP_TEMPLATE,ex_unit,ExUnit))
$(eval $(call APP_TEMPLATE,logger,Logger))
$(eval $(call APP_TEMPLATE,eex,EEx))
$(eval $(call APP_TEMPLATE,mix,Mix))
$(eval $(call APP_TEMPLATE,iex,IEx))
````

まずは、elixir の中でも、stdlibが呼び出されています。

````makefile
KERNEL:=lib/elixir/ebin/Elixir.Kernel.beam
UNICODE:=lib/elixir/ebin/Elixir.String.Unicode.beam
````

stdlib で KERNEL で使われていますが、KERNEL自体は default: compile よりも上に記載されています。
stdlibの中で、 lib/elixir/ebin/Elixir.Kernel.beam を使って exファイル、つまりはElixirのコードのコンパイルが実施され、Erlangのbeamファイルへと変換されています。

## 最後に 

簡単にですが、Makefileの中身をみてきました。
ElixirがErlangから出来てきて、Elixirへとコンパイルされていく内容が簡単にですが見えてきたのではないでしょうか。

それでは良いElixir Lifeを！