この記事は Elixir Advent Calendar 2016 3日目の記事です。前日の記事は Joe-nohさんの ExUnit入門です。
Makefile
はじめに
今回の記事ですが、冬コミに向けてElixirの中身を一部読んでみたので、そちらの内容を一部記載していきます。
今回の内容ですがMakefileにてElixirがコンパイルされるまでのお話となっています。
Makefileのコードですが、2016年12月時点の最新のもので確認を行っています。
さてMakefileの中身をみていきましょう
default
default: compile
compile: lib/elixir/src/elixir.app.src erlang elixir
ElixirのMakefileでは default が一番上なのでデフォルトゴールとなっており、 default で実行される内容は compile のため、単純に make を実施すると compile が実施されます。
compile 自体は、
- lib/elixir/src/elixir.app.src
- erlang
- elixir
の順番に実施されていきますので、まずは、lib/elixir/src/elixir.app.src からみていきます。
lib/elixir/src/elixir.app.src
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
erlang:
$(Q) cd lib/elixir && $(REBAR) compile
lib/elixir に移動し、$(REBAR) compileを実施しています。
さて、$(REBAR) の中身には何が記載されているかというとrebarコマンドの場所が記載されております。
そのためrebar を使って Erlangのコードのcompileが実施されます。
ここでrebarなど入れていないっと思われる方もいらっしゃるかもしれませんが、 rebar自体はElixirのコードのトップディレクトリに配置されております。
そのためインストールされてなくてもトップディレクトリにある rebar を使って ElixirのErlangのコードのcompileが実施されるという動きが実施できるわけです。
elixir
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が呼び出されています。
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を!