reltool使用指南
| Author: |
litaocheng |
| Mail: |
litaocheng@gmail.com |
| Revision: |
1 |
| Date: |
2009.10.28 |
目錄
- 1 概述
- 2 使用
- 2.1 GUI 相關
- 2.1.1 System Window
- 2.1.2 System Settings
- 3 用命令產生relase(target system)
- 3.1 基本配置
- 3.2 sys 配置
- 3.3 app 配置
- 3.4 mod 配置
- 4 例子
- 5 config type定義
1 概述
reltool 是 Erlang 提供的 release 管理工具. 我們依據 Erlang/OTP 開發的 application, 最後需要發布,這時需要使用 reltool 幫我們產生最終的 release, 也稱為 target system. 同時 reltool 可以分析 application 的依賴關係,協助我們正確的發布應用.
reltool 包括一個基於 wx 的 GUI 前端(wxWidgets erlang bind), 其可以用來查看 application 的依賴關係,可以查看模組的依賴關係,可以查看原始碼. reltool 也提供使用命令來產生自訂的發布包.
1.1 適用範圍和目的
本文檔主要介紹如何使用 reltool, reltool 為 Erlang/OTP 開發環境的一部分. 本文假設讀者對Erlang相關開發比較熟悉,瞭解 Eralng/OTP 開發規範. Erlang/OTP 要求R13B02及以上版本.
1.2 瞭解更多內容
可以通過下列相關文檔瞭解更多 Erlang/OTP 開發相關資訊
- reltool 參考手冊
- reltool user guide
- Erlang/OTP System Principles
- Erlang/OTP Design Principles
- 圖書 Programming Erlang: Software for a concurrent World (2007)
2 使用
前面講過, reltool 提供 GUI 和命令兩種互動方式, 本章首先簡單的介紹GUI介面相關內容, 重點是使用命令產生 release, 發布自己的應用. 之所以重點介紹命令方式,主要基於兩個因素:
- 命令方式是基礎, GUI 只是提供了一個介面封裝, 本質還是調用的相關的命令
- GUI 目前功能還不是很完整,很多操作不支援
2.1 GUI 相關2.1.1 System Window
通過調用 reltool:start/0,1 啟動 reltool, reltool 在啟動時,首先掃描所有的 application 和 module, 分析其相互依賴關係.隨後啟動 system window.
system window 包含四個page window (tabs):
- Libraries
- System settings
- Applications
- Releases
點擊對應的tag, 可以切換page.
system window 如:
Librarie 視窗如
在 library 視窗, 我們設定 reltool 將要使用的代碼. 本頁面以 tree 的形式來組織內容, 你可以點擊每行前面的標記摺疊/展開對應內容.
Library directories, Escript files 都可以進行操作. 選擇對應的項目,按住滑鼠右鍵顯示對應的菜單, 移動滑鼠選擇對應的功能表項目,釋放滑鼠右鍵.
雙擊 lib 下某個 application, 可以顯示對應的 application window.
通過 reltool GUI, 我們還可以查看很多 windows, 如 aplication 依賴圖:
原始碼視窗:
2.1.2 System Settings
Avaiable 中顯示的所有可用的 applications. 在 system page 中,我們可以設定全域的 application 包含規則, 即 incl_cond.
incl_cond 包含三種策略,我們在介紹命令方式建立release時,會詳細介紹.
3 用命令產生relase(target system)
先說一下為自己的 application 產生 release 的步驟:
- 依據 Erlang/OTP 項目完成, 測試通過
- 定義 reltool 使用的關於最終 release 的各種配置參數 Config
- reltool:start_server(Config) 啟動 reltool
- reltool:get_target_spec/1 擷取根據 Config 產生的用來建立 target system 的一系列"動作"(Spec)
- reltool:eval_target_spec/3 根據 Spec 產生 target system
- 書寫輔助的指令碼,用來產生最終的安裝包(可以為tar包,或者zip等)
我們假設第1步,您已經完成.
產生 target system 的重點就是 config 的設定了, 讓我們詳細的描述一下 reltool 手冊中各項 config 參數.
config 可以大體分為4種類型:
- 基本配置
- sys 配置
- app 配置
- mod 配置
其中,很多配置資訊在 sys, application, mod 三個等級中均會出現,其關係為: mod > app > sys, 即 mod 配置覆蓋 app 配置, app 配置覆蓋 sys 配置.
3.1 基本配置
root_dir
Reltool 根據當前開發環境產生 target system, 因此 config 資訊中勢必包含 erlang root_dir 資訊.
root_dir 指明 erlang 的當前安裝目錄(比如在 ubuntu 9.04 下, 預設為 /usr/local/lib/erlang).本選項可以不用指定, reltool 會自動化佈建 root_dir.
lib_dirs
除卻 $ERL_LIB 外, 指定附加的 library 目錄. 主要用來指定非 Erlang/OTP 正式發布版本中的 application 或 library.如第三方 library, 或我們自己的 application.
3.2 sys 配置
erts
指定 erts application 資訊, 具體的欄位參考後面介紹的 app 配置.
escript
escript 指令碼配置資訊, 包含 escript 檔案,以及對應的配置資訊
app
target system 中包含的 app 資訊. 比如所有的 release 都要包含 kernel, stdlib, 具體的app的相關配置,輕參考後面介紹的 app level 配置
mod_cond
設定 module 的包含策略. 其包含多種方式:
- all - 表示如果某個 app 被包含,那麼其包含的所有模組全部被包含. 假設 app 名為 demoapp, all 不僅包含 demoapp/ebin 下的所有模組, 同時 demoapp.app 中 modules 欄位描述的所有模組也將被包括(預設)
- ebin - 表示 ebin 目錄下所有的模組,以及相關的模組會被包含
- app - 表示 .app 描述檔案,以及相關的模組會被包含
- derived - 表示被其他包含的模組用到的相關模組會被包含
此處配置的 mod_cond 是 sys level 的配置, 控制所有的 app 中的 module 包含策略. 當然我們可以對這個資訊, 在 app level 進行覆蓋.
incl_cond 設定 applicaion 以及 escript 的包含策略.
其包含3種類型:
- derived - 表示 包含 沒有明確設定 incl_cond, 同時被其他 application 直接或間接引用的application. (預設)
- include - 表示 包含 所有沒有明確設定 incl_cond 的application
- exclude - 表示 排除 排除沒有明確設定 incl_cond 的application
include 和 exclude 意義相反. 一個是包含沒有設定 incl_cond 的 apps, 一個是排除沒有設定 incl_cond 的 apps.
一般我們使用預設的 derived 選項,這樣保證所有相關的 application 均被包含, 不會出現 target system 中,某個模組沒有定義的錯誤.我們可以通過前面 reltool GUI 部分介紹的 application 依賴關係圖 來瞭解 application 的互動相關資訊.
boot_rel
指定 target system 中預設啟動項 (rel), 一個target system 中可能包含很多的 release(通過 rel 來指定)
rel
指定 rel 內容 (Release specific configuration), 每個 rel 定義會被映射成 rel, script 和 boot 檔案,請參考 Erlang/OTP Design Principles Release
relocable
指定 target system 中erl 執行時自動檢測路徑相關資訊({relocable, true}), 還是寫入程式碼指定路徑啟動({relocable, false}). 如果 relocable 為 false, 那麼 target system 必須首先通過 reltool:install/2 進行安裝, 如果 relocable 為 true, target system 移動到其他目錄時,仍然可以方便的運行. {relocable, true} (預設)
profile 指定 tareget system 的類型, 此選項主要影響:incl_sys_filters, excl_sys_filters, incl_app_filters 和 excl_app_filters. 不同的 profile 類型, 以上4個 filters 不同.
主要包含3種:
- development - 開發測試模式(預設)
- embedded - 嵌入式完整模式
- standalone - 單獨模式,不攜帶相關的可執行檔
在產生 target system 時, 實際上主要有兩個步驟:首先建立一個完整的檔案候選列表,它包含儘可能多的檔案; 隨後調用各種相關的 filter 定義,對結果進行過濾, 最後聲稱最終的 target system.
一般情況下,我們的target system 要是一個完整的可執行檔系統,因此我們許要設定 profile 為 embedded. (當然不設定 profile, 只是修改4個相關的 filter, 也可以達到我們想要的效果)
app_file
控制 app 的內容, 因為有各種各樣的 filter, 因此最終的 target system 中包含的模組,可能與 app 檔案定義的模組列表不一致, 本選項控制 app 的內容. 主要包含3種:
- keep - 將 app 直接拷貝到 target system 中(預設)
- strip - 依據 app 檔案產生 target system 中的 app 檔案, 並將未被包含的模組從 app 檔案中移出
- all - 依據 app 檔案產生 tarege system 中的 app 檔案, 同時所有的模組將添加到 app 檔案中, 如果某個應用沒有 app 檔案,那麼會自動建立一個 app 檔案.
debug_info
是否去除 beam 檔案中的調試資訊: keep 表示保持; strip 表示去除
incl_sys_filters
指定一個Regex列表,用來表示哪些系統檔案可以出現在 target system 中. 如果某個系統檔案想被包括, 那麼其必須滿足 incl_sys_filters 中的某個Regex, 同時不能滿足 excl_sys_filters 中的任何錶達式.
比如:
{incl_sys_filters,["^bin","^erts","^lib","^releases"]},表示 $ERL_ROOT 目錄下的 bin, erts, lib, releases 目錄均要包含.
incl_app_filters, excl_app_filters 同 sys 相關的 filters 含義大致相同,只是用來控制 application 的包含規則.
excl_sys_filters
指定一個Regex列表,表示哪些系統檔案不可以出現在 target system 中. 預設 為 [].
incl_app_filters
指定一個Regex列表,表示 application 中的哪些檔案可以被包含. 如果某個檔案想被包含,至少要滿足Regex列表中的一個運算式. 預設為 [".*"], 如果設定為 [], 那麼 application 中的任何檔案都不會被包含.
excl_app_filters
指定一個Regex列表,表示 application 的哪些檔案不可以出現在 target system 中. 預設 為 [].
incl_archive_filters
指定 application 中哪些一級子目錄包含在壓縮包中(與包含正常的目錄對應), 通過一個Regex列表指定要包含在壓縮包中的一級子目錄. 預設為 [".*"]
excl_archive_filters
指定一個Regex列表,指定 application 的哪些一級目錄不包含在壓縮包中. 如果某個目錄,匹配任何一個Regex,則不會包含在壓縮包中. 預設為 ["^include$", "^priv$"]
archive_opts
建立壓縮包對應的參數,在 zip:create/3 中使用, 請參考 zip module, 預設 為 [].
3.3 app 配置
vsn
指定要包含的 application 的版本, 因為在系統中,可能存在同一應用的多個版本. 如果忽略,則使用最新版本.
mod
模組相關的配置資訊. 必須包含一個模組名稱,以及其他可選的模組配置(參照後面 mod 配置)
mod_cond - 同 sys level 的同名配置含義相同
incl_cond - 同上
debug_info - 同上
incl_app_filters - 同上
excl_app_filters - 同上
incl_archive_filters - 同上
excl_archive_filters - 同上
archive_opts - 同上
3.4 mod 配置
4 例子
最後是一個執行個體,我們為 erlips (erlang ip service) 產生 target system.
config (erlips.config)如下:
{sys, [ {lib_dirs,["/home/litaocheng/erlang"]}, {boot_rel, "erlips"}, {rel, "erlips", "0.1", [kernel, stdlib, sasl, mochiweb, erlips]}, {relocatable, true}, {profile, embedded}, {app_file, keep}, {debug_info, strip}, {mod_cond, all}, {incl_cond, derived}, {incl_app_filters, ["^include", "^priv", "^ebin", "^src"]}, {excl_app_filters, []}, {incl_archive_filters,[]}, {excl_archive_filters,[".*"]}, {app, kernel, [{incl_cond, include}]}, {app, stdlib, [{incl_cond, include}]}, {app, sasl, [{incl_cond, include}]}, {app, erlips, [{incl_cond, include}, {incl_app_filters, [".*"]}, {excl_app_filters, ["^log", "^var", "^release"]}]}, {app, mochiweb, [{incl_cond, include}]}, {app, runtime_tools, [{incl_cond, include}]} ]}.
我們為一個名叫 erlips 的 application 產生 target system.
隨後執行:
> {ok, Server} = reltool:start_server([{config, "erlips.config"}]).> {ok, Spec} = reltool:get_target_spec(Server).> RelDir = "target_dir".> file:make_dir(RelDir).> ok = reltool:eval_target_spec(Spec, code:root_dir(), RelDir).> zip:zip(RelDir ++ ".zip", [RelDir]). % 建立zip包
將產生的 zip 包拷貝到沒有安裝 Erlang 環境的電腦中, 解壓 zip 包, 隨後運行:
./bin/erl
則自動啟動 erlips 應用.
5 config type定義
下面為 reltool 中各相關 config 的 type 定義(參考 reltool):
options() = [option()]option() = {config, config() | file()} | {trap_exit, bool()} | {wx_debug, term()}config() = {sys, [sys()]}sys() = {root_dir, root_dir()} | {lib_dirs, [lib_dir()]} | {profile, profile()} | {erts, app()} | {escript, escript_file(), [escript()]} | {app, app_name(), [app()]} | {mod_cond, mod_cond()} | {incl_cond, incl_cond()} | {boot_rel, boot_rel()} | {rel, rel_name(), rel_vsn(), [rel_app()]} | {relocatable, relocatable()} | {app_file, app_file()} | {debug_info, debug_info()} | {incl_sys_filters, incl_sys_filters()} | {excl_sys_filters, excl_sys_filters()} | {incl_app_filters, incl_app_filters()} | {excl_app_filters, excl_app_filters()} | {incl_archive_filters, incl_archive_filters()} | {excl_archive_filters, excl_archive_filters()} | {archive_opts, [archive_opt()]}app() = {vsn, app_vsn()} | {mod, mod_name(), mod()} | {mod_cond, mod_cond()} | {incl_cond, incl_cond()} | {debug_info, debug_info()} | {app_file, app_file()} | {incl_sys_filters, incl_sys_filters()} | {excl_sys_filters, excl_sys_filters()} | {incl_app_filters, incl_app_filters()} | {excl_app_filters, excl_app_filters()} | {incl_archive_filters, incl_archive_filters()} | {excl_archive_filters, excl_archive_filters()} | {archive_opts, [archive_opt()]}mod() = {vsn, app_vsn()} | {incl_cond, incl_cond()} | {debug_info, debug_info()}rel_app() = app_name() | {app_name(), app_type()} | {app_name(), [incl_app()]} | {app_name(), app_type(), [incl_app()]}app_name() = atom()app_type() = permanent | transient | temporary | load | noneapp_vsn() = string()archive_opt = zip_create_opt()boot_rel() = rel_name()app_file() = keep | strip | alldebug_info() = keep | stripdir() = string()escript() = {incl_cond, incl_cond()}escript_file() = file()excl_app_filters() = regexps()excl_archive_filters() = regexps()excl_sys_filters() = regexps()file() = string()incl_app() = app_name()incl_app_filters() = regexps()incl_archive_filters() = regexps()incl_cond() = include | exclude | derivedincl_sys_filters() = regexps()lib_dir() = dir()mod_cond() = all | app | ebin | derived | nonemod_name() = atom()profile() = development | embedded | standalonere_regexp() = string()reason() = string()regexps() = [re_regexp()] | {add, [re_regexp()]} | {del, [re_regexp()]}rel_file() = term()rel_name() = string()rel_vsn() = string()relocatable = boolean()root_dir() = dir()script_file() = term()server() = server_pid() | options()server_pid() = pid()target_dir() = file()
轉載:http://erlangdisplay.iteye.com/blog/508944