zoukankan      html  css  js  c++  java
  • Rebar:Erlang构建工具

    Rebar:Erlang构建工具

    http://www.cnblogs.com/panfeng412/archive/2011/08/14/2137990.html

    Rebar是一款Erlang的构建工具,使用它可以方便的编译、测试erlang程序、内联驱动和打包Erlang发行版本。

    Rebar是一个独立的erlang脚本,所以使用Rebar发布程序非常简单,甚至可以直接集成在项目文件夹中。默认的情况下,Rebar会按照Erlang/OTP来组织项目的结构,这样一来,构建时的配置工作量就会大大减少。Rebar同时提供了依赖库(包)管理机制,方便程序员重用已存在的模块。Rebar的依赖管理机制支持的方式非常多,甚至包括Git, Hg等少见的方式。

    下面是一个简单的例子演示如何将一个已经存在的项目转化为使用rebar来构建。

    1. 准备开始
    2. Rebar的命令参数
    3. 构建Rebar
    4. Rebar和OTP约定
    5. 模板支持
    6. 处理发行版本
    7. 扩展Rebar

    1. 准备开始

    学习使用Rebar的最好的方法是使用一个简单的例子来演示如何用Rebar构建Erlang项目。

    1.1 创建项目

    首先,我们为这个例子项目创建一个文件夹:

    1 mkdir myapp
    2 cd myapp

    然后,下载rebar的二进制文件到这个项目的文件夹。注意:如果在你的PATH中间有已经有rebar了,不会对我们这个例子有影响。

    复制代码
    1 cd..;
    2 git clone git://github.com/basho/rebar.git;
    3 cd rebar;
    4 ./bootstrap;
    5 cd../myapp;
    6 mv ../rebar/rebar ./
    复制代码

    接下来,我们使用rebar的模板系统来构建我们程序的“骨架”。

    1 ./rebar create-app appid=myapp

    这条命令执行后会产生一个子文件夹“src”,src包含三个文件夹:

    • myapp.app.src:OTP应用程序的资源文件
    • myapp_app.erl:一个OTP应用程序的Application behaviour
    • myapp_sup.erl: 一个OTP应用程序的Supervisor behaviour

    1.2 编译

    现在,我们可以使用rebar来编译这个应用程序:

    1 ./rebar compile

    执行完成后,会产生一个新的文件夹ebin,在其下会生成与src文件夹下源文件对应的beam文件。同时,rebar会根据myapp.app.src动态生成一个合适OTP项目资源文件。

    编译完成后,如果想清除编译后的beam文件也非常简单:

    1 ./rebar clean

    1.3 测试

    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文件里。

    2. Rebar的命令参数

    Rebar提供了开发中最常用的一些操作,包括:

    • 编译
    • 单元测试和覆盖分析
    • 静态分析(通过Dialyzer和Xref)
    • 生成文档
    • 依赖管理

    另外,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

    3. 构建Rebar

    下载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之旅。

    4. Rebar和OTP约定

    Rebar按照OTP的约定组织项目,OTP约定可以参考:OTP设计原则。基于此,应用程序的目录需要下列子文件夹:

    • src
    • ebin
    • priv
    • include

    应用程序的资源文件(*.app)应该放到ebin文件夹下。

    除了上面文件夹,rebar还支持下列的原则:

    5. 模板支持

    我可以使用我的模板吗?

    是的,只要把模板文件(mytemplate.template)放到.rebar/templates下,然后通过下列命令使用:

    1 ./rebar create template=mytemplate

    6. 管理发行版本

    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
    复制代码

    7. 扩展Rebar

    在标准发布版本中,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).
    复制代码
  • 相关阅读:
    topcoder srm 681 div1
    topcoder srm 683 div1
    topcoder srm 684 div1
    topcoder srm 715 div1
    topcoder srm 685 div1
    topcoder srm 687 div1
    topcoder srm 688 div1
    topcoder srm 689 div1
    topcoder srm 686 div1
    topcoder srm 690 div1 -3
  • 原文地址:https://www.cnblogs.com/fvsfvs123/p/4160374.html
Copyright © 2011-2022 走看看