用 rebar 来构建、编译、测试、发布 Erlang 应用程序
转自:http://dhq.me/build-compile-eunit-release-erlang-application-with-rebar
rebar 是一个遵循 Erlang/OTP 原则的 Erlang 项目构建工具,使用它可以减少构建标准 Erlang/OTP 项目架构配置的工作量,并且可以很容易的编译、测试、发布 Erlang 应用程序。更强大的是,rebar 提供一种依赖管理机制,它可以使开发者很方便地通过 Git、Hg 等方式重用常见的第三方 Erlang 模块或库。
安装 rebar
你可以从 https://github.com/rebar/rebar/wiki/rebar 下载编译好的版本,也可以自己下载 rebar 的源代码,自己编译一个:
1
2
3
|
git clone git: //github .com /rebar/rebar .git cd rebar . /bootstrap |
上面编译好之后,在当前目录下就会生成一个名为 "rebar" 独立的 erlang 脚本(escript),把它放在你想创建标准 Erlang/OTP 项目的目录路径下即可使用,或者把 rebar 放在系统目录的 Path 下,方便在终端使用:
1
|
sudo mv rebar /usr/local/bin |
在终端输入 "rebar -c" 将列出所有可执行的 rebar 命令。或者输入 "rebar -h" 查看更多的 rebar 参数信息。
用 rebar 构建项目
创建一个名为 rebarapp 的文件夹
1
2
|
mkdir rebarapp cd rebarapp |
创建名为 rebarapp 项目:
1
|
rebar create-app appid=rebarapp |
rebar 会根据默认模板(template)在当前目录下生成一个 src 文件夹,里面包含下面3个文件:
- rebarapp.app.src 应用的资源描述文件,影响后面编译生成的 rebarapp.app 里的内容
- rebarapp_app.erl 应用的 Application Behaviour 代码文件
- rebarapp_sup.erl 应用的 Supervisor Behaviour 代码文件
rebar 还内置了 gen_server、gen_fsm、application 等 Erlang/OTP 行为模式的模板,可以自动生成这些行为模式的框架代码。这里以 gen_server 为例,给应用添加一个名为 rebarapp_server 的 gen_server 行为模式。在应用根目录执行以下命令:
1
|
rebar create template=simplesrv srvid=rebarapp_server |
执 行完后自动会在 src 文件夹里生成一个 rebarapp_server.erl 的 gen_server 框架格式的文件,simplesrv 是 gen_server 模板的名称(gen_fsm、application对应的是simplefsm、simpleapp),srvid 则是该 gen_server 模板的ID(gen_fsm、application对应的是fsmid、appid)。
为了测试,这里对 rebarapp_server.erl 进行修改,export 一个 hello 方法,并添加一个 cast 的消息输出,修改后的 rebarapp_server.erl 文件内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
- module (rebarapp_server). -behaviour(gen_server). - define ( SERVER , ?MODULE ). %% ------------------------------------------------------------------ %% API Function Exports %% ------------------------------------------------------------------ - export ([start_link/0, hello/0]). %% ------------------------------------------------------------------ %% gen_server Function Exports %% ------------------------------------------------------------------ - export ([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% ------------------------------------------------------------------ %% API Function Definitions %% ------------------------------------------------------------------ start_link() -> gen_server:start_link ({local, ?SERVER }, ?MODULE , [], []). %% @doc just a test hello() -> gen_server:cast ( ?SERVER , 'HELLO' ). %% ------------------------------------------------------------------ %% gen_server Function Definitions %% ------------------------------------------------------------------ init( Args ) -> {ok, Args }. handle_call(_ Request , _ From , State ) -> {reply, ok, State }. handle_cast( 'HELLO' , State ) -> io:format ( "Hello World!~n" ), {noreply, State }; handle_cast(_ Msg , State ) -> {noreply, State }. handle_info(_ Info , State ) -> {noreply, State }. terminate(_ Reason , _ State ) -> ok. code_change(_ OldVsn , State , _ Extra ) -> {ok, State }. %% ------------------------------------------------------------------ %% Internal Function Definitions %% ------------------------------------------------------------------ |
修改 rebarapp_sup.erl 的 init 函数,把 rebarapp_server 作为应用管理者 rebarapp_sup 的工作进程启动,修改如下:
1
2
3
|
init([]) -> RebarappServer = ?CHILD (rebarapp_server, worker), {ok, { {one_for_one, 5, 10}, [ RebarappServer ]} }. |
编译应用
1
|
rebar compile |
编译完后,会在根目录下生成一个 ebin 的文件夹,里面存放的是该应用的资源文件 rebarapp.app 和应用的 beam 文件,也可以执行以下命令对编译生成的应用文件进行清理:
1
|
rebar clean |
使用 Edoc 生成应用文档
1
|
rebar doc |
命令执行完后,会在根目录生成一个 doc 的文件夹,打开里面的 index.html 就可以很直观地看到该应用的模块 API 概览。
eunit 测试
rebar 会根据一个名为 rebar.config 的文件里的 eunit 配置选项来对应用进行测试,rebar.config 详细地配置选项信息可以查看官方上的 rebar.config.sample。在应用的根目录下创建一个 rebar.config,填入以下内容:
1
2
3
4
5
6
7
8
9
10
|
%%-*- mode: erlang -*- %% Erlang compiler options {erl_opts, [debug_info, {i, "test"}, {src_dirs, ["src"]}]}. {eunit_opts, [verbose, {report, {eunit_surefire, [{dir, "."}]}}]}. {cover_enabled, true}. |
上面的配置将会加载根目录下的 test 文件夹里的文件,所以需要在根目录下创建一个 test 文件夹:
1
|
mkdir -p test |
这里 test 文件夹将存放 eunit 的测试用例,在 test 文件夹里新建一个名为 rebarapp_test.hrl 的测试用例文件,内容如下:
1
2
3
4
5
6
7
8
9
|
-include_lib( "eunit/include/eunit.hrl" ). my_test() -> ?assert (1 + 2 =:= 3). simple_test() -> ok = application:start (rebarapp), ?assertNot (undefined =:= whereis(rebarapp_sup)). |
然后在 rebarapp_server.erl 的文件末尾加上以下测试代码:
1
2
3
|
-ifdef( TEST ). -include( "rebarapp_test.hrl" ). -endif. |
当然,如果有必要的话也可以在每个模块文件上加上面测试代码。执行以下命令进行 eunit 测试:
1
|
rebar compile eunit |
如果应用文件没什么变化修改,也可以直接运行 "rebar eunit"。这时终端出现以下类似显示,则 eunit 测试完成:
1
2
3
4
5
6
7
8
9
10
11
|
==> rebarapp (eunit) ======================== EUnit ======================== module 'rebarapp_app' module 'rebarapp_server' rebarapp_server: my_test...ok rebarapp_server: simple_test...[0.014 s] ok [done in 0.019 s] module 'rebarapp_sup' ======================================================= All 2 tests passed. Cover analysis: /Users/dengjoe/erlang/rebarapp/.eunit/index.html |
可以打开根目录下的.eunit/index.html 查看测试报告。
发布应用
在应用根目录下创建一个名为 rel 的文件夹,用来作为应用发布的文件夹:
1
2
|
mkdir -p rel cd rel |
在当前 rel 文件夹里创建一个名为 rebarapp 的独立的 Erlang VM 节点:
1
|
rebar create-node nodeid=rebarapp |
修 改 rel/reltool.config 里的 lib_dirs 的值,默认是一个空列表 "[]",改为应用所在的目录路径 '["../../"]',不然到后面编译发布时会报 "Missing application directory" 的错误出来,修改后的 reltool.config 配置内容如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
{sys, [ {lib_dirs, ["../../"]}, {erts, [{mod_cond, derived}, {app_file, strip}]}, {app_file, strip}, {rel, "rebarapp", "1", [ kernel, stdlib, sasl, rebarapp ]}, {rel, "start_clean", "", [ kernel, stdlib ]}, {boot_rel, "rebarapp"}, {profile, embedded}, {incl_cond, derived}, {mod_cond, derived}, {excl_archive_filters, [".*"]}, %% Do not archive built libs {excl_sys_filters, ["^bin/.*", "^erts.*/bin/(dialyzer|typer)", "^erts.*/(doc|info|include|lib|man|src)"]}, {excl_app_filters, ["\.gitignore"]}, {app, rebarapp, [{mod_cond, app}, {incl_cond, include}]} ]}. {target_dir, "rebarapp"}. {overlay, [ {mkdir, "log/sasl"}, {copy, "files/erl", "\{\{erts_vsn\}\}/bin/erl"}, {copy, "files/nodetool", "\{\{erts_vsn\}\}/bin/nodetool"}, {copy, "files/rebarapp", "bin/rebarapp"}, {copy, "files/rebarapp.cmd", "bin/rebarapp.cmd"}, {copy, "files/start_erl.cmd", "bin/start_erl.cmd"}, {copy, "files/install_upgrade.escript", "bin/install_upgrade.escript"}, {copy, "files/sys.config", "releases/\{\{rel_vsn\}\}/sys.config"}, {copy, "files/vm.args", "releases/\{\{rel_vsn\}\}/vm.args"} ]}. |
返回应用的根目录,在 rebar.config 加上以下一行,把新建的 rel 文件夹放入到 rebar 可访问的子文件夹里,作为应用内容发布文件夹:
1
|
{sub_dirs, ["rel"]}. |
再重新编译下应用 rebarapp
1
|
rebar compile |
如果报什么错,应用 rebarapp 就可以发布了:
1
|
rebar generate |
在终端上看到 "==> rel (generate)" 且没报什么错,应用 rebarapp 发布成功,并在 rel/rebarapp/bin 目录下生成一个用来启动应用或停止应用等操控动作的 shell 文件 rebarapp。
操控文件 rel/rebarapp/bin/rebarapp 用法:
1
|
rebarapp {start|start_boot |foreground|stop|restart|reboot|ping|console|console_clean|console_boot |attach|remote_console|upgrade} |
例如:
启动应用 rebarapp
1
|
rel /rebarapp/bin/rebarapp start |
停止应用 rebarapp
1
|
rel /rebarapp/bin/rebarapp stop |
或者启动应用 rebarapp 后返回一个 erlang shell 的控制台
1
|
rel /rebarapp/bin/rebarapp console |
OK,在 erlang shell 的控制台上调用 rebarapp_server:hello() 输出一个 "Hello World!" 吧。
用 rebar 来构建、编译、测试、发布 Erlang 应用程序的更多相关文章
- [原]Jenkins(七)---jenkins项目编译测试发布由maven构建的web项目
/** * lihaibo * 文章内容都是根据自己工作情况实践得出. * 版权声明:本博客欢迎转发,但请保留原作者信息! http://www.cnblogs.com/horizonli/p/533 ...
- 在Windows用Rebar来构建,编译,测试,发布Erlang项目
rebar是一个遵循 Erlang/OTP 原则的 Erlang 项目构建工具,使用它可以减少构建标准 Erlang/OTP 项目架构配置的工作量,并且可以很容易的编译.测试.发布 Erlang 应用 ...
- Ubuntu18.04安装Docker并部署(编译、发布、构建镜像)Asp.NetCore项目全过程笔记
环境准备:阿里云Ubuntu18.04 全新安装 一.安装Docker 1.删除旧版本并更新包索引: sudo apt-get remove docker docker-engine dock ...
- Jenkins搭建.NET自动编译测试与发布环境
本文地址: http://blog.csdn.net/wangjia184/article/details/18365553 操作系统Windows, 确保需要的.NET Framework已经安装 ...
- ionic实战系列(一):ionic的开发环境配置和编译、发布
我的ionic实战系列是基于<<Ionic实战>>[美]Jeremy Wilken著-这本书的读书笔记,有诸多借鉴,不详细的地方请参考书籍本身的内容. 1.1技术栈模型 Ion ...
- 使用Bitbucket Pipeline进行.Net Core项目的自动构建、测试和部署
1. 引言 首先,Bitbucket提供支持Mercurial和Git版本控制系统的网络托管服务.简单来说,它类似于GitHub,不同之处在于它支持个人免费创建私有项目仓库.除此之外,Bitbucke ...
- 【.NetCore】基于jenkins以及gitlab的持续编译及发布
前沿 其实本来是想把标题叫做持续集成的,只是后来看看研究出的内容,就只有发布这一个动作,自动化测试等内容也未涉及到,所以改名叫持续编译及发布应该更加贴切吧? 问题背景 其实目前我们传统方式上的发布方式 ...
- 如何利用Azure DevOps快速实现自动化构建、测试、打包及部署
前两天有朋友问我,微软的Azure好用吗,适不适合国人的使用习惯,我就跟他讲了下,Azue很好用,这也是为什么微软云营收一直涨涨涨的原因,基本可以再1个小时内实现自动化构建.打包以及部署到Azure服 ...
- selenium结合docker构建分布式测试环境
selenium是目前web和app自动化测试的主要框架.对于web自动化测试而言,由于selenium2.0以后socker服务器由本地浏览器自己启动且直接通过浏览器原生API操作页面,故越来越多的 ...
随机推荐
- Python学习笔记——进阶篇【第八周】———进程、线程、协程篇(Socket编程进阶&多线程、多进程)
本节内容: 异常处理 Socket语法及相关 SocketServer实现多并发 进程.线程介绍 threading实例 线程锁.GIL.Event.信号量 生产者消费者模型 红绿灯.吃包子实例 mu ...
- Python学习笔记——基础篇【第七周】———类的静态方法 类方法及属性
新式类和经典类的区别 python2.7 新式类——广度优先 经典类——深度优先 python3.0 新式类——广度优先 经典类——广度优先 广度优先才是正常的思维,所以python 3.0中已经修复 ...
- Dubbo服务的搭建与使用
官方地址Dubbo.io Dubbo 主要功能 高并发的负载均衡,多系统的兼容合并(理解不深,不瞎掰了) Dubbo 主要组成有四部分 Zookeeper(服务注册中心) Consumer(服务消费方 ...
- spring+springmvc+maven+mybatis整合
jar包依赖:网址search.maven.org 1.spring :spring-core 2. myhabits:myhabits 3.整合spring和myhabits: ...
- 洛谷-统计数字-NOIP2007提高组复赛
题目描述 Description 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照 ...
- Delphi水晶横向竖向打印
最近做一个打印项目,本来报表已经设为横向打印了,可是运行程序,打印出来的是竖向的,非要在打印机里再设定为横向,郁闷了很久,看看UCrpe32的源码之后,由于我重新封装了TCrpe,在TCrpe的派生类 ...
- Python笔记4-20151029
一.切片 L = [''Michael','Sarah','Tracy','Bob','Jack'] 取前N个元素,也就是索引为0-(N-1)的元素,可以用循环: >>> r = [ ...
- python 学习 异常处理
异常处理实例 while True: num1 = input('num1:') num2 = input('num2:') try: num1 = int(num1) num2 = int(num2 ...
- Url有值怎么使用get传值
原来url有数据 test 我们可以$_GET可以获取出来 一般form表单头用get方式都可以满足大多需求 但有一种情况 url里已经有值的时候 用url就会覆盖原来的值 而数据就会丢失 : 数据又 ...
- Nis+Nfs+Autofs
Nis: NIS服务的应用结构中分为NIS服务器和NIS客户机两种角色 NIS服务器集中维护用户的帐号信息(数据库)供NIS客户机进行查询 用户登录任何一台NIS客户机都会从NIS服务器进行登录认证, ...