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

    Rebar:Erlang构建工具

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

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

    这里有一个例子演示怎样将一个已经存在的项目转化为使用rebar来构建。

    • 准备开始
    • Rebar的命令参数
    • 构建Rebar
    • Rebar和OTP约定
    • 模板支持
    • 处理发行版本
    • 扩展Rebar

    1.准备开始

    第一步:

    学习使用Rebar的最好的方法是使用一个简单的例子来演示如何用Rebar构建Erlang项目。首先,我们为这个例子项目创建一个文件夹:

    $ mkdir myapp; cd myapp

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

    $cd .. ;$git clone git://github.com/basho/rebar.git;

    $cd rebar;

    $./bootstrap;

    $cd ../myapp;

    $mv ../rebar/rebar ./

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

    $ ./rebar create-app appid=myapp

    这条指令的结果会产生一个子文件夹“src”,src包含三个文件夹:

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

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

    $ ./rebar compile

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

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

    $ ./rebar clean

    测试:

    Rebar为eunit和common_test两个测试框架都提供了支持,在下面这个例子中,我们使用eunit来为我们的应用程序写一个测试用例。

    打开文件src/myapp_app.erl,在-export()指令之后添加如下代码:

    -ifdef(TEST).-include_lib(“eunit/include/eunit.hrl”).

    -endif.

    在这个文件的最后添加:

    -ifdef(TEST).simple_test() ->

    ok = application:start(myapp),

    ?assertNot(undefined == whereis(myapp_sup)).

    -endif.

    通过使用ifdef保护我们的测试代码,我们可以保证最后的测试代码不会随着编译生成的代码进入ebin文件夹。下面我们来运行这个单元测试用例:

    $ ./rebar compile eunit

    你应该收到类似的输出:

    ==> myapp (compile)Compiled src/myapp_app.erl

    Compiled src/myapp_sup.erl

    ==> myapp (eunit)

    Compiled src/myapp_sup.erl

    Compiled src/myapp_app.erl

    Test passed.

    注意:rebar这次会编译myapp_app.erl文件两遍,第二遍编译会将输出放到一个特殊的文件夹下(.eunit)下,生成的文件会包含调试信息和其他有用的测试标记。

    如果你想检查我们单元测试的覆盖率,可以非常简单的通过在myapp/rebar.config添加一行:

    {cover_enabled, true}.

    然后重新运行我们的测试用例:

    $ ./rebar compile eunit==> myapp (compile)

    ==> myapp (eunit)

    Test passed.

    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.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

    $git clone git://github.com/basho/rebar.git;$cd rebar;

    $./bootstrap;

    Recompile: src/rebar_core

    ==> rebar (compile)

    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下,然后通过下列命令使用:

    $ rebar create template=mytemplate

    6.管理发行版本

    reltool.config简介:

    erlang通过配置文件reltool.config来帮助创建节点,配置文件中包含rebar和reltool(Erlang R13B引入的发布管理工具)创建节点需要的信息。

    创建应用如下:

    $ ./rebar create-app appid=exemplar

    注意:create-app和create-node选项能够在rebar_templater.erl中找到,其他的支持的参数都能在simpleapp.template和simplenode.template中找到。

    要创建一个节点,需要手动创建一个rel文件:

    $ mkdir rel$ cd rel

    创建节点:

    $ ../rebar create-node nodeid=exemplar$ ls -lR

    .:

    total 8

    drwxr-xr-x 2 haoze.zpx users 4096 Apr 11 11:08 files

    -rw-r–r– 1 haoze.zpx users 806 Apr 11 11:08 reltool.config

    ./files:

    total 28

    -rw-r–r– 1 haoze.zpx users 334 Apr 11 11:08 app.config

    -rwxr–r– 1 haoze.zpx users 1120 Apr 11 11:08 erl

    -rwxr–r– 1 haoze.zpx users 4370 Apr 11 11:08 exemplar

    -rwxr–r– 1 haoze.zpx users 4819 Apr 11 11:08 nodetool

    -rw-r–r– 1 haoze.zpx users 423 Apr 11 11:08 vm.args

    需要在rebar.config中添加:

    {sub_dirs, ["rel"]}.

    执行:

    $ ./rebar generate==> rel (generate)

    在rel目录中就会生成examplar系统:

    $ ls -l rel/exemplar/total 24

    drwxr-xr-x 2 haoze.zpx users 4096 Apr 11 11:09 bin

    drwxr-xr-x 8 haoze.zpx users 4096 Apr 11 11:09 erts-5.8

    drwxr-xr-x 2 haoze.zpx users 4096 Apr 11 11:09 etc

    drwxr-xr-x 18 haoze.zpx users 4096 Apr 11 11:09 lib

    drwxr-xr-x 3 haoze.zpx users 4096 Apr 11 11:09 log

    drwxr-xr-x 3 haoze.zpx users 4096 Apr 11 11:09 releases

    7.扩展Rebar

    (Tips:这章我没有实验过)

    在标准发布版本中,rebar能够支持大部分erlang开发者的需要。当你碰到需要扩展rebar的需求时,rebar提供一种简单的方法帮助加入新功能。

    Contexts:

    想要知道如何扩展rebar,一个关键的因素就是理解rebar的核心机制—–contexts。Contexts决定在项目目录结构中选择那些命令选项执行。

    对于哪个目录能够执行哪个选项,contexts没有限制,通过配置资源文件rebar.app,例如想要在项目的任何一个目录都执行any_dir_modules,需要在rebar.app中添加:

    {application, rebar,[{description, "Rebar: Erlang Build Tool"},

    %% ...

    {env, [

    %% ...

    %% any_dir processing modules

    {any_dir_modules, [

    %% ...

    rebar_exemplar

    ]},

    %% …

    ]}

    ]}.

    Module context:

    Module context允许rebar的选项与项目中的文件夹和发布文件夹都关联。

    你可以通过查看rebar.app了解这些,从中学习如何用modules配置参数来使用app_dir和rel_dir。

    Example: EDoc command修改rebar.app:

    {application, rebar,[{description, "Rebar: Erlang Build Tool"},

    {vsn, "2"},

    {modules, [ rebar,

    %% ...

    rebar_edoc,

    %% ...

    mustache ]},

    {registered, []},

    {applications, [kernel,

    stdlib,

    sasl]},

    {env, [

    %% ...

    %% Dir specific processing modules

    {modules, [

    {app_dir, [

    %% ...

    rebar_edoc,

    %% ...

    ]},

    {rel_dir, [

    rebar_reltool

    ]}

    ]}

    ]}

    ]}.

    引入rebar_edoc模块:

    -module(rebar_edoc).-export([doc/2, clean/2]).

    -include(“rebar.hrl”).

    %% @doc Generate Erlang program documentation.

    %% @spec doc(#config{}, string()) -> ok

    -spec(doc(Config::#config{}, File::string()) -> ok).

    doc(Config, File) ->

    {ok, AppName, _AppData} = rebar_app_utils:load_app_file(File),

    EDocOpts = rebar_config:get(Config, edoc_opts, []),

    ok = edoc:application(AppName, “.”, EDocOpts),

    ok.

    %% @doc Remove the generated Erlang program documentation.

    %% @spec clean(#config{}, string()) -> ok

    -spec(clean(Config::#config{}, File::string()) -> ok).

    clean(Config, _File) ->

    EDocOpts = rebar_config:get(Config, edoc_opts, []),

    DocDir = proplists:get_value(dir, EDocOpts, “doc”),

    rebar_file_utils:rm_rf(DocDir).

  • 相关阅读:
    1022. D进制的A+B (20)
    1032. 挖掘机技术哪家强(20)
    1001. 害死人不偿命的(3n+1)猜想 (15)
    结构-06. 复数四则运算(15)
    结构-05. 有理数均值(20)
    结构-04. 通讯录的录入与显示(10)
    结构-03. 平面向量加法(10)
    软考错题合集之13-05-AM
    软考笔记第八天之法律发规与标准化知识
    软考笔记第七天之程序设计语言与语言处理程序基础
  • 原文地址:https://www.cnblogs.com/xiayong123/p/3717040.html
Copyright © 2011-2022 走看看