rebar3使用介紹(二)
本篇主要介紹rebar3的配置部分
全局配置
rebar3支持全局配置,這也配置生效於環境中的所有rebar3,配置在操作系統的環境變量中,有以下內容:
REBAR_PROFILE=“term” # force a base profile
HEX_CDN=“https://…” # change the Hex endpoint for a private one
REBAR_CONFIG=“rebar3.config” # changes the name of rebar.config files
QUIET=1 # only display errors
DEBUG=1 # show debug output
# “QUIET=1 DEBUG=1” displays both errors and warnings
REBAR_COLOR=“low” # reduces amount of color in output if supported
REBAR_CACHE_DIR # override where rebar3 stores config and cache data
http_proxy # standard proxy ENV variable is respected
https_proxy # standard proxy ENV variable is respected
Alias 別名
別名允許你根據現有命令,創造一個新的命令出來,當然他們必須有固定的執行順序才行,比如
{alias, [{check, [eunit, {ct, "--sys_config=config/app.config"}]}]}.
配置中的元素可以是check這種單個atom代表一個動作,也可以是 {ct, “–sys_config=config/app.config”} 這種代表一個帶參的動作,執行順序永遠是從左到右串行執行。
Artifacts
Artifacts可以理解成一個項目編譯完成後的資源的集合體,這在你的項目中有非erlang的模塊時會非常實用,比如你用C編寫了共享庫,將它的產出文件配置進去,就可以判斷編譯是否成功。
如果發現已經構建了一個依賴項(意味着它的.app文件的模塊列表與其.beam文件匹配)那麼在隨後的rebar3調用中就都不會編譯這部分,也就不會觸發這部分的hook。
相對路徑於取決於它是否在傘狀項目的頂層定義。例如,假設我們有一個項目my_project包含應用程序my_app在apps/my_app/下,my_app會創建一個escript。在rebar3不要在意配置在my_project/rebar.config中,因爲它是整個項目的頂級rebar.config。該artifact會相對profile_dir,默認情況下是_build/default/:
{artifacts, ["bin/rebar3"]}.
像上面我們檢查的就是 _build/default/bin/rebar3
如果不是在頂層,比如my_app有自己的rebar.config,那麼定義在這個rebar.config中的相對目錄就是_build/default/lib/my_app/ 而不是 _build/default,因爲rebar的傘狀構建特性,必須要確保子項目能自己完成自己的檢查,這樣的設定也是合理的
相反的如果項目不是傘狀項目,即使my_app是在頂層,rebar.config在根目錄下,Artifacts項的相對目錄也是_build/default/lib/my_app/
rebar3提供了幾個宏來擴展相對目錄如下:
Key | 描述 |
---|---|
profile_dir | The base output directory with the profile string appended, default: _build/default/ . |
base_dir | The base output directory, default: _build . |
out_dir | The application’s output directory, default:_build/default/lib/<application>/ . |
再舉一個實例,eleveldb
{overrides,
[{override, eleveldb, [{artifacts, ["priv/eleveldb.so"]},
...
]
}]}.
因爲這個是eleveldb自己的rebar.config,所以"priv/eleveldb.so"
就相當於"{{out_dir}}priv/eleveldb.so"
Compilation
編譯選項定義在erl_opts字段下,具體可使用的字段和值參照erlang的編譯選項
{erl_opts, [
debug_info,
{parse_transform, lager_transform},
warn_export_all,
warn_unused_import,
{i, "include"},
{src_dirs, ["src"]}]}.
除此之外,還可以設置特定於平臺的選項。
{erl_opts, [{platform_define,
"(linux|solaris|freebsd|darwin)",
'HAVE_SENDFILE'},
{platform_define, "(linux|freebsd)",
'BACKLOG', 128},
{platform_define, "R13",
'old_inets'}]
}.
這裏支持匹配例如
{platform_define, "^((?!R1[456]).)*$", 'maps_support'}
一個單獨的編譯選項是聲明模塊在所有其他模塊之前編譯的選項:
{erl_first_files, ["src/lager_util.erl"]}.
還有一些額外的單獨編譯選項
{validate_app_modules, true}. % Make sure modules in .app match those found in code
{app_vars_file, undefined | Path}. % file containing elements to put in all generated app files
%% Paths the compiler outputs when reporting warnings or errors
%% relative (default), build (all paths are in _build, default prior
%% to 3.2.0, and absolute are valid options
{compiler_source_format, relative}.
其他與Erlang相關的編譯器支持自己的配置選項:
- Leex編譯器與{xrl_opts, […]}
- SNMP MIB編譯器與{mib_opts, […]}
- Yecc編譯器與{yrl_opts, […]}
測試選項
{ct_first_files, [...]}. % {erl_first_files, ...} but for CT
{ct_opts, [...]}. % same as options for ct:run_test(...)
{ct_readable, true | false}. % disable rebar3 modifying CT output in the shell
ct_opts支持的字段可以在這裏找到
Cover
具體看這
Dialyzer
{dialyzer, [Opts]}
支持選項看這
Distribution
多個功能和插件可能需要支持分佈式Erlang。通常,所有此類命令(例如ct和shell)的配置都遵循以下配置值:
{dist_node, [
{setcookie, 'atom-cookie'},
{name | sname, 'nodename'},
]}.
Directories 目錄
可支持選項和默認值如下:
%% directory for artifacts produced by rebar3
{base_dir, "_build"}.
%% directory in '<base_dir>/<profile>/' where deps go
{deps_dir, "lib"}.
%% where rebar3 operates from; defaults to the current working directory
{root_dir, "."}.
%% where checkout dependencies are to be located
{checkouts_dir, "_checkouts"}.
%% directory in '<base_dir>/<profile>/' where plugins go
{plugins_dir, "plugins"}.
%% directories where OTP applications for the project can be located
{project_app_dirs, ["apps/*", "lib/*", "."]}.
%% Directories where source files for an OTP application can be found
{src_dirs, ["src"]}.
%% Paths to miscellaneous Erlang files to compile for an app
%% without including them in its modules list
{extra_src_dirs, []}.
%% Paths the compiler outputs when reporting warnings or errors
%% relative (default), build (all paths are in _build, default prior
%% to 3.2.0, and absolute are valid options
{compiler_source_format, relative}.
EDoc
配置項看這裏
Escript
EUnit
{eunit_first_files, [...]}. % {erl_first_files, ...} but for CT
{eunit_opts, [...]}. % same as options for eunit:test(Tests, ...)
{eunit_tests, [...]}. % same as Tests argument in eunit:test(Tests, ...)
最小OTP版本檢查
{minimum_otp_vsn, "17.4"}.
Overrides
覆蓋是出於自己的項目需要對依賴項目作出改動,但是這個改動又不想套用到庫上,所以選作上層覆蓋,Overrides支持add, override, del操作
{overrides, [{add, app_name(), [{atom(), any()}]},
{del, app_name(), [{atom(), any()}]},
{override, app_name(), [{atom(), any()}]},
{add, [{atom(), any()}]},
{del, [{atom(), any()}]},
{override, [{atom(), any()}]}]}.
app_name有的時候只會對指定app進行操作,如果沒有指定,則會對所有app進行指定
這個特性允許你在不修改庫的前提下,強制同意一些編譯配置之類,或者針對自己的項目或者平臺進行擴展
Hook 鉤子
有兩種類型的鉤子:shell鉤子和功能鉤子
shell鉤子
{pre_hooks, [{clean, "./prepare_package_files.sh"},
{"linux", compile, "c_src/build_linux.sh"},
{compile, "escript generate_headers"},
{compile, "escript check_headers"}]}.
{post_hooks, [{clean, "touch file1.out"},
{"freebsd", compile, "c_src/freebsd_tweaks.sh"},
{eunit, "touch file2.out"},
{compile, "touch postcompile.out"}]}.
如果命令內容比較複雜,最好還是用腳本包裝起來後調用腳本,而不是在配置裏寫一大推
post_hooks 在調用失敗的情況下是不會調用的,比如clean操作本身失敗了,那麼post_hooks指定的動作也就不會執行
功能鉤子
功能鉤子,一般指的是通過用插件擴展的功能,不止侷限於rebar本身提供的功能
以下鉤子在運行clean之前compile運行。
{provider_hooks, [{pre, [{compile, clean}]}
{post, [{compile, {erlydtl, compile}}]}]}
不需要參數就只需要填寫命令的atom,如果需要用tuple帶入
功能鉤子都是在shell鉤子之前執行的
自寫功能中可以hook的點
只有部分功能支持附着鉤子,
Hook | before and after |
---|---|
clean | 每個應用程序和依賴項,和/或編譯所有頂級應用程序之前和之後 |
compile | 每個應用程序和依賴項,和/或編譯所有頂級應用程序之前和之後 |
erlc_compile | 編譯應用程序的樑文件 |
app_compile | 從.app.src爲應用程序構建.app文件 |
ct | 整個運行前後 |
edoc | 整個運行前後 |
escriptize | 整個運行前後 |
eunit | 整個運行前後 |
release | 整個運行前後 |
tar | 整個運行前後 |
*默認情況下,這些鉤子爲每個應用程序運行,因爲依賴項可以在它們自己的上下文中指定它們自己的鉤子。區別在於,在某些情況下(傘形應用程序),鉤子可以在許多級別上定義(省略覆蓋):
- 應用程序根目錄下的rebar.config文件
- 每個頂級應用程序(在apps/或中libs/)rebar.config
- 每個依賴項的rebar.config
默認情況下,當沒有傘形應用程序時,頂級rebar.config中定義的鉤子將被歸爲頂級應用程序的一部分。這允許鉤子在以後發佈庫時繼續爲依賴項工作。
但是,如果鉤子是在具有傘形應用程序的項目的根目錄下的rebar.config中定義的,則鉤子將在任務運行之前/之後爲所有頂級應用程序運行。
要保留傘狀項目中的每個應用程序行爲,必須在每個應用程序的rebar.config中定義鉤子。
RELX
SHELL
rebar3 shell如果relx找到條目,REPL將自動啓動應用程序,但可以使用顯式指定由shell啓動的應用程序{shell, [{apps, [App]}]}。
以下爲擴展配置:
Option | Value | Description |
---|---|---|
apps | [app1, app2, …] | 要啓動的app列表,追加在relx的配置後 |
config | “path/to/a/file.config” | 加載指定配置 |
script_file | “path/to/a/file.escript” | 執行自定義腳本 |
XRef
{xref_warnings,false}.
{xref_extra_paths,[]}.
{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used,
exports_not_used,deprecated_function_calls,
deprecated_functions]}.
{xref_queries,[{"(xc - uc) || (xu - x - b - (\"mod\":\".*foo\"/\"4\"))", []}]}.
{xref_ignores, [{M, F}, {M, F, A}]}.