http://www.cnblogs.com/panfeng412/archive/2011/08/14/2137990.htmlhtml
Rebar是一款Erlang的構建工具,使用它能夠方便的編譯、測試erlang程序、內聯驅動和打包Erlang發行版本。node
Rebar是一個獨立的erlang腳本,因此使用Rebar發佈程序很是簡單,甚至能夠直接集成在項目文件夾中。默認的狀況下,Rebar會按照Erlang/OTP來組織項目的結構,這樣一來,構建時的配置工做量就會大大減小。Rebar同時提供了依賴庫(包)管理機制,方便程序員重用已存在的模塊。Rebar的依賴管理機制支持的方式很是多,甚至包括Git, Hg等少見的方式。git
下面是一個簡單的例子演示如何將一個已經存在的項目轉化爲使用rebar來構建。程序員
學習使用Rebar的最好的方法是使用一個簡單的例子來演示如何用Rebar構建Erlang項目。github
首先,咱們爲這個例子項目建立一個文件夾:bootstrap
1 mkdir myapp
2 cd myapp
而後,下載rebar的二進制文件到這個項目的文件夾。注意:若是在你的PATH中間有已經有rebar了,不會對咱們這個例子有影響。bash
1 cd..;
2 git clone git://github.com/basho/rebar.git;
3 cd rebar;
4 ./bootstrap;
5 cd../myapp;
6 mv ../rebar/rebar ./
接下來,咱們使用rebar的模板系統來構建咱們程序的「骨架」。app
1 ./rebar create-app appid=myapp
這條命令執行後會產生一個子文件夾「src」,src包含三個文件夾:框架
如今,咱們可使用rebar來編譯這個應用程序:工具
1 ./rebar compile
執行完成後,會產生一個新的文件夾ebin,在其下會生成與src文件夾下源文件對應的beam文件。同時,rebar會根據myapp.app.src動態生成一個合適OTP項目資源文件。
編譯完成後,若是想清除編譯後的beam文件也很是簡單:
1 ./rebar clean
Rebar爲eunit和common_test兩個測試框架都提供了支持,在下面這個例子中,咱們使用eunit來爲咱們的應用程序寫一個測試用例。
打開文件src/myapp_app.erl,在-export()指令以後添加以下代碼:
1 -ifdef(TEST).
2 -include_lib(「eunit/include/eunit.hrl」).
3 -endif.
而後在這個文件的最後添加:
1 -ifdef(TEST).
2 simple_test() ->
3 ok = application:start(myapp),
4 ?assertNot(undefined == whereis(myapp_sup)).
5 -endif.
經過使用ifdef保護咱們的測試代碼,保證最後的測試代碼不會隨着編譯生成的代碼進入ebin文件夾。
下面咱們來運行這個單元測試用例:
1 ./rebar compile eunit
此時,屏幕上顯示如下相似輸出結果:
1 ==> myapp (compile)
2 Compiled src/myapp_app.erl
3 Compiled src/myapp_sup.erl
4 ==> myapp (eunit)
5 Compiled src/myapp_sup.erl
6 Compiled src/myapp_app.erl
7 Test passed.
注意:本次操做中rebar會編譯myapp_app.erl文件兩遍,第二遍編譯會將輸出放到一個特殊的文件夾(.eunit)下,生成的文件會包含調試信息和其餘有用的測試標記。
另外,若是你想檢查咱們單元測試的覆蓋率,能夠經過在myapp/rebar.config添加一行進行配置:
1 {cover_enabled, true}.
而後,從新運行咱們的測試用例,輸入結果以下:
1 ==> myapp (compile)
2 ==> myapp (eunit)
3 Test passed.
4 Cover analysis: /Users/dizzyd/tmp/myapp/.eunit/index.html
有關詳細的代碼覆蓋率分析,被保存在.eunit/index.html文件裏。
Rebar提供了開發中最經常使用的一些操做,包括:
另外,rebar和reltool提供模板機制以方便OTP嵌入式系統利用。
最常常使用的命令:
命令 | 描述 |
compile | 編譯項目中全部可用的源文件 |
eunit | 使用Eunit執行單元測試 |
doc | 使用Edoc生成文檔 |
clean | 去掉全部生成的文件。包括編譯,單元測試等過程生成的 |
較少用的命令(按照字母序):
命令 | 描述 |
analyze | 使用Dialyzer執行靜態分析 |
build_plt | 構建Dialyzer PLT; 具體描述請看:Dialyzer documentation |
check_plt | 檢查Dialyzer PLT是不是最新,須要的話從新構建 |
create | 根據模板建立一個典型的項目 |
create-app | 根據模板文件priv/templates/simpleapp.template ,建立一個典型的OTP應用 |
create-node | Create a prototypical OTP embedded system (described by the priv/templates/simplenode.reltool.config template) |
delete-deps | 刪除rebar.config 設置的依賴庫(包)源文件D |
generate | 使用 Reltool 構建一個embedded system |
get-deps | 檢索rebar.config 文件中配置的依賴的代碼 |
xref | 使用Xref 分析依賴 |
Rebar能夠經過compile指令編譯多種格式的源文件:
源文件 | 目標文件 | 描述 |
src/*.erl | ebin/*.beam | ERlang的源文件 |
src/*.app.src | ebin/*.app | Erlang應用程序的資源文件 |
c_src/*.c | priv/<app>.so | port driver的c語言源代碼或者NIF共享連接庫 |
mibs/*.mib | priv/mibs/*.bin | SNMP 的mib 文件 |
src/*.xrl | src/*.erl | Leex 生成的文件 |
src/*.yrl | src/*.erl | Yecc 生成的文件 |
asn1/*.asn1 | src/*.erl | ASN-1文件 |
templates/*.dtl | ebin/*_dtl.beam | ErlyDTL模板文件 (須要額外安裝 ErlyDTL) |
src/*.lfe | ebin/*.beam | LFE 源文件 (須要額外安裝LFE) |
src/*.peg | ebin/*.beam | Neotoma PEG 語法源文件 (須要額外安裝Neotoma) |
src/*.proto | ebin/*_pb.beam, include/*_pb.hrl | Protocol Buffers 參數(須要額外安裝protobuffs) |
Rebar能夠在rebar.config文件中配置的各類選項:
命令 | 選項參數 | 描述 |
compile | erl_first_files | 須要提早編譯的erlang源文件(例如behavior模塊) |
compile | erl_opts | 編譯器支持的其餘選項,詳情請見 here |
compile | mib_first_files | 須要提早編譯的mib文件列表 (例如, mib 文件中import部分的引用的RFC文件 |
compile | src_dirs | 列出其餘包含erlang源文件的目錄 |
compile | erlydtl_opts | 更多的支持的選項查閱 ErlyDTL Templates |
clean | clean_files | 須要在clean步驟刪除的文件列表,列出那些須要clean指令刪除的其餘模塊的文件 |
doc | edoc_opts | edoc 支持的指令,詳見:here |
eunit | eunit_opts | Eunit支持的指令,詳見 here |
eunit | cover_enabled | 開啓erlang的覆蓋率分析 |
eunit | eunit_compile_opts | Eunit編譯時用到的其餘的選項 |
analyze | dialyzer_opts | 指定Dialyzer PLT 文件 |
build_plt | dialyzer_opts | 指定Dialyzer PLT 文件 |
check_plt | dialyzer_opts | 指定 Dialyzer PLT 文件 |
get-deps, delete-deps | base_dir | 爲deps_dir 指定一個候選的目錄 |
get-deps, delete-deps | deps_dir | 制定一個文件夾存儲依賴 |
get-deps, delete-deps | deps | 依賴的列表 |
generate | target_dir | 目標文件夾 |
generate | overlay_vars | Overlay variables file |
xref | xref_warnings | 打開xref的警告 |
xref | xref_checks | Xref模塊中analyze/3支持的選項,具體能夠參考: here |
下載rebar:
1 $git clone git://github.com/basho/rebar.git
構建rebar:
1 $cd rebar
2 $./bootstrap
3 Recompile: src/rebar_core
4 ==> rebar (compile)
5 Congratulations! You now have a self-contained script called 「rebar」 in your current working directory. Place this script anywhere in your path and you can use rebar to build OTP-compliant apps.
此時,咱們有了一個rebar執行腳本,拷貝這個腳本到項目目錄,開始咱們的rebar之旅。
Rebar按照OTP的約定組織項目,OTP約定能夠參考:OTP設計原則。基於此,應用程序的目錄須要下列子文件夾:
應用程序的資源文件(*.app)應該放到ebin文件夾下。
除了上面文件夾,rebar還支持下列的原則:
我可使用個人模板嗎?
是的,只要把模板文件(mytemplate.template)放到.rebar/templates下,而後經過下列命令使用:
1 ./rebar create template=mytemplate
reltool.config簡介:
erlang經過配置文件reltool.config來幫助建立節點,配置文件中包含rebar和reltool(Erlang R13B引入的發佈管理工具)建立節點須要的信息。
建立應用以下:
1 ./rebar create-app appid=exemplar
注意:create-app和create-node選項可以在rebar_templater.erl中找到,其餘的支持的參數都能在simpleapp.template和simplenode.template中找到。
要建立一個節點,須要先手動建立一個rel目錄:
1 mkdir rel
2 cd rel
而後建立節點:
1 $../rebar create-node nodeid=exemplar
2 $ ls -lR
3 .:
4 total 8
5 drwxr-xr-x 2 jiuling.ypf users 4096 Apr 1111:08files
6 -rw-r–r– 1 jiuling.ypf users 806 Apr 1111:08 reltool.config
7 ./files:
8 total 28
9 -rw-r–r– 1 jiuling.ypf 334 Apr 1111:08 app.config
10 -rwxr–r– 1 jiuling.ypf users 1120 Apr 1111:08 erl
11 -rwxr–r– 1 jiuling.ypf users 4370 Apr 1111:08 exemplar
12 -rwxr–r– 1 jiuling.ypf users 4819 Apr 1111:08 nodetool
13 -rw-r–r– 1 jiuling.ypf users 423 Apr 1111:08 vm.args
同時,還須要在rebar.config中添加一行sub_dirs:
1 {sub_dirs, ["rel"]}.
最後,執行rebar:
1 $./rebar generate
2 ==> rel (generate)
此時,在rel子目錄中就會生成examplar應用:
$ ls -l rel/exemplar/
total 24
drwxr-xr-x 2 jiuling.ypf users 4096 Apr 1111:09 bin
drwxr-xr-x 8 jiuling.ypf users 4096 Apr 1111:09 erts-5.8
drwxr-xr-x 2 jiuling.ypf users 4096 Apr 1111:09 etc
drwxr-xr-x 18 jiuling.ypf users 4096 Apr 1111:09 lib
drwxr-xr-x 3 jiuling.ypf users 4096 Apr 1111:09 log
drwxr-xr-x 3 jiuling.ypf users 4096 Apr 1111:09 releases
在標準發佈版本中,rebar可以支持大部分erlang開發者的須要。當你碰到須要擴展rebar的需求時,rebar提供一種簡單的方法幫助加入新功能。
(1)Contexts
想要知道如何擴展rebar,一個關鍵的因素就是理解rebar的核心機制——Contexts。Contexts決定在項目目錄結構中選擇那些命令選項執行。
對於哪一個目錄可以執行哪一個選項,contexts沒有限制,經過配置資源文件rebar.app,例如想要在項目的任何一個目錄都執行any_dir_modules,須要在rebar.app中添加:
1 {application, rebar,
2 [{description,"Rebar: Erlang Build Tool"},
3 %% ...
4 {env, [
5 %% ...
6 %% any_dir processing modules
7 {any_dir_modules, [
8 %% ...
9 rebar_exemplar
10 ]},
11 %% …
12 ]}
13 ]}.
(2)Module context
Module context容許rebar的選項與項目中的文件夾和發佈文件夾都關聯。
你能夠經過查看rebar.app瞭解這些,從中學習如何用modules配置參數來使用app_dir和rel_dir。
例子,EDoc command<strong>修改</strong>rebar.app:
1 {application, rebar,
2 [{description,"Rebar: Erlang Build Tool"},
3 {vsn,"2"},
4 {modules, [ rebar,
5 %% ...
6 rebar_edoc,
7 %% ...
8 mustache ]},
9 {registered, []},
10 {applications, [kernel,
11 stdlib,
12 sasl]},
13 {env, [
14 %% ...
15 %% Dir specific processing modules
16 {modules, [
17 {app_dir, [
18 %% ...
19 rebar_edoc,
20 %% ...
21 ]},
22 {rel_dir, [
23 rebar_reltool
24 ]}
25 ]}
26 ]}
27 ]}.
(3)引入rebar_edoc模塊
1 -module(rebar_edoc).
2 -export([doc/2, clean/2]).
3 -include(「rebar.hrl」).
4
5 %% @doc Generate Erlang program documentation.
6 %% @spec doc(#config{}, string()) -> ok
7 -spec(doc(Config::#config{}, File::string()) -> ok).
8 doc(Config, File) ->
9 {ok, AppName, _AppData} = rebar_app_utils:load_app_file(File),
10 EDocOpts = rebar_config:get(Config, edoc_opts, []),
11 ok = edoc:application(AppName, 「.」, EDocOpts),
12 ok.
13
14 %% @doc Remove the generated Erlang program documentation.
15 %% @spec clean(#config{}, string()) -> ok
16 -spec(clean(Config::#config{}, File::string()) -> ok).
17 clean(Config, _File) ->
18 EDocOpts = rebar_config:get(Config, edoc_opts, []),
19 DocDir = proplists:get_value(dir, EDocOpts, 「doc」),
20 rebar_file_utils:rm_rf(DocDir).