使用rebar创建一个otp项目

本文介绍如何利用Rebar工具创建、编译Erlang OTP项目,并实现版本管理和热代码替换。涵盖创建项目、添加gen_server、编写单元测试、发布版本等步骤。
一、使用rebar创建一个otp项目
第1步:创建一个项目目录
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test$ mkdir myapp; cd myapp

第2步:将rebar文件复制到这个目录,也可以直接下载
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test$ wget http://cloud.github.com/downloads/basho/rebar/rebar && chmod u+x rebar
--2011-05-13 09:37:13--  http://cloud.github.com/downloads/basho/rebar/rebar
正在解析主机 cloud.github.com... 204.246.165.144, 204.246.165.231, 204.246.165.99, ...
正在连接 cloud.github.com|204.246.165.144|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度: 102570 (100K) [application/octet-stream]
正在保存至: “rebar”

100%[======================================>] 102,570     74.4K/s   in 1.3s    

2011-05-13 09:37:23 (74.4 KB/s) - 已保存 “rebar” [102570/102570])

注:rebar项目地址git地址:https://github.com/basho/rebar.git ($ git clone https://github....),git下载后make生成一个rebar文件也是可以的。

第3步:创建一个OTP项目
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ ./rebar create-app appid=myapp
==> myapp (create-app)
Writing src/myapp.app.src
Writing src/myapp_app.erl
Writing src/myapp_sup.erl

第4步:增加一个gen_server,可以设置状态值和得到状态,具体代码看文件,并修改myapp_sup.erl
init([]) ->
    Server1 = {myapp_server,
             {myapp_server, start_link, []},
             permanent, 5000, worker, [myapp_server]},

    {ok, {{one_for_one, 5, 10}, [Server1]}}.
    
第5步:修改myapp.app.src
增加配置项:
  {modules, [
             myapp_app,
             myapp_sup,
             myapp_server
            ]},

第4步:编译
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ ./rebar compile
==> myapp (compile)
Compiled src/myapp_app.erl
Compiled src/myapp_sup.erl
Compiled src/myapp_server.erl

第5步:测试
rebar同时支持 eunit 和 common_test两种测试框架,下面例子将使用eunit方式进行一个简单测试
1)打开 src/myapp_app.erl文件,在 -export() 后加入如下代码:
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.

同时在文件中加入测试函数(注:所有的测试函数都需要被包含在-ifdef(TEST)和-endif中):
-ifdef(TEST).

%%测试函数
simple_test() ->
    ok = application:start(myapp),
    ?assertNot(undefined == whereis(myapp_sup)).

-endif.
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ cat src/myapp_app.erl
-module(myapp_app).

-behaviour(application).

%% Application callbacks
-export([start/2, stop/1]).

-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.

%% ===================================================================
%% Application callbacks
%% ===================================================================

start(_StartType, _StartArgs) ->
    myapp_sup:start_link().

stop(_State) ->
    ok.
    
-ifdef(TEST).
%%测试函数
simple_test() ->
    ok = application:start(myapp),
    ?assertNot(undefined == whereis(myapp_sup)).
-endif.
2)进行单元测试
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ ./rebar compile eunit
==> myapp (compile)
Compiled src/myapp_app.erl
Compiled src/myapp_sup.erl
==> myapp (eunit)
Compiled src/myapp_app.erl
  Test passed.

二、发布版本
第1步:创建apps目录
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ mkdir apps

第2步:在apps目录下创建myapp
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ mkdir apps/myapp

第3步:将src文件移动到apps/myapp目录下
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ mv src apps/myapp/src
      
第4步:创建rel目录
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ mkdir rel
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ cd rel
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel$

第5步:create the node
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel$ ../rebar create-node nodeid=myapp
==> rel (create-node)
Writing reltool.config
Writing files/erl
Writing files/nodetool
Writing files/myapp
Writing files/app.config
Writing files/vm.args

bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel$ ls -lR
.:
总用量 8
drwxr-xr-x 2 bland bland 4096 2011-05-13 09:55 files
-rw-r--r-- 1 bland bland  783 2011-05-13 09:55 reltool.config

./files:
总用量 28
-rw-r--r-- 1 bland bland  334 2011-05-13 09:55 app.config
-rwxr--r-- 1 bland bland 1120 2011-05-13 09:55 erl
-rwxr--r-- 1 bland bland 4370 2011-05-13 09:55 myapp
-rwxr--r-- 1 bland bland 4819 2011-05-13 09:55 nodetool
-rw-r--r-- 1 bland bland  417 2011-05-13 09:55 vm.args

第6步:创建一个rebar.config文件,并增加如下信息:
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel$ cd ..
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ cat << EOF > rebar.config 【回车】
> {sub_dirs, ["apps/myapp","rel"]}. 【回车】
> {cover_enabled, true}. 【回车】
> EOF 【回车】
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ cat rebar.config
{sub_dirs, ["apps/myapp","rel"]}.
{cover_enabled, true}.

第7步:修改rel/reltool.config 文件
找到 {lib_dirs, []},...
      修改为:{lib_dirs, ["../apps"]},
找到 {rel, "myapp", "1",
        [
         kernel,
         stdlib,
         sasl
        ]},...
      修改为:
      {rel, "myapp", "1",
        [
         kernel,
         stdlib,
         sasl,
         myapp
        ]},
        
找到 {excl_sys_filters, ["^bin/.*",
                           "^erts.*/bin/(dialyzer|typer)"]},
      {app, sasl, [{incl_cond, include}]} .....
      修改为:
       {excl_sys_filters, ["^bin/.*",
                           "^erts.*/bin/(dialyzer|typer)"]},
       {excl_archive_filters, [".*"]},
       {app, myapp, [{incl_cond, include}]},
       {app, sasl, [{incl_cond, include}]}......
      
第8步:编译
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$./rebar compile
==> myapp (compile)
==> rel (compile)
==> myapp (compile)
       
第9步:生成release
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$./rebar generate
==> rel (generate)
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ ls rel/myapp/
bin  erts-5.8.1  etc  lib  log  releases

bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ ls rel/myapp/lib/
compiler-4.7.1  hipe-3.7.7        public_key-0.8         tools-2.6.6.1
crypto-2.0.1    inets-5.5         runtime_tools-1.8.4.1  webtool-0.8.7
edoc-0.7.6.7    kernel-2.14.1     sasl-2.1.9.2           wx-0.98.7
erts-5.8.1      mnesia-4.4.15     ssl-4.0.1              xmerl-1.2.6
et-1.4.1        myapp-0.1         stdlib-1.17.1
gs-1.5.13       observer-0.9.8.3  syntax_tools-1.6.6

三、进行热代码替换
第1步:构建0.1版本并启动应用
1)修改目录名称,按照版本号命名
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ mv rel/myapp rel/myapp_0.1
2)进入rel/myapp_0.1
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ cd rel/myapp_0.1/
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel/myapp_0.1$ ls
bin  erts-5.8.1  etc  lib  log  releases

3)启动应用
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel/myapp_0
.1$ ./bin/myapp console
Exec: /home/bland/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel/myapp_0.1/erts-5.8.1/bin/erlexec -boot /home/bland/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel/myapp_0.1/releases/1/myapp -embedded -config /home/bland/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel/myapp_0.1/etc/app.config -args_file /home/bland/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel/myapp_0.1/etc/vm.args -- console
Root: /home/bland/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp/rel/myapp_0.1
Erlang R14B (erts-5.8.1) [source] [smp:2:2] [rq:2] [async-threads:5] [hipe] [kernel-poll:true]

Eshell V5.8.1  (abort with ^G)
(myapp@127.0.0.1)1> application:which_applications().%%浏览当前节点启动的应用
[{sasl,"SASL  CXC 138 11","2.1.9.2"},
 {myapp,"my first app","0.1"},
 {stdlib,"ERTS  CXC 138 10","1.17.1"},
 {kernel,"ERTS  CXC 138 10","2.14.1"}]
(myapp@127.0.0.1)3> myapp_server:get_state().
0
(myapp@127.0.0.1)4> myapp_server:set_state(123).
{ok,123}
(myapp@127.0.0.1)5> myapp_server:get_state().   
123
(myapp@127.0.0.1)5> release_handler:which_releases(). %%查看当前版本
[{"myapp","0.1",[],permanent}]
(myapp@127.0.0.1)6>

第3步:构建0.2版本
1)将release版本号从0.1改为0.2
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ vim apps/myapp/src/myapp.app.src
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ vim rel/reltool.config
2)编译并且打包
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ ./rebar compile
==> myapp (compile)
==> rel (compile)
==> myapp (compile)
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ ./rebar generate
==> rel (generate)
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ ./rebar generate-appups previous_release=myapp_0.1
==> rel (generate-appups)
Generated appup for myapp
Appup generation complete
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ ./rebar generate-upgrade previous_release=myapp_0.1
==> rel (generate-upgrade)
myapp_0.2 upgrade package created
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$

3)检查升级包内容
bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ tar -zvtf rel/myapp_0.2.tar.gz

第4步:使用RELEASE_HANDLER进行部署
1)bland@thinkpad:~/workspace/黑米/研发/项目/SiteLyst3/rebar_test/myapp$ mv rel/myapp_0.2.tar.gz rel/myapp_0.1/releases/
2)使用release_handler在运行应用的erlang shell中进行部署
(myapp@127.0.0.1)> release_handler:unpack_release("myapp_0.2").
{ok,"0.2"}
(myapp@127.0.0.1)> release_handler:install_release("0.2").
{ok,"0.1",[]}
(myapp@127.0.0.1)> release_handler:make_permanent("0.2").
ok
(myapp@127.0.0.1)> release_handler:which_releases().
[{"myapp","0.2",
  ["kernel-2.14.1","stdlib-1.17.1","myapp-0.2","sasl-2.1.9.2",
   "compiler-4.7.1","crypto-2.0.1","syntax_tools-1.6.6",
   "edoc-0.7.6.7","et-1.4.1","gs-1.5.13","hipe-3.7.7",
   "inets-5.5","mnesia-4.4.15","observer-0.9.8.3",
   "public_key-0.8","runtime_tools-1.8.4.1","ssl-4.0.1",
   "tools-2.6.6.1","webtool-0.8.7","wx-0.98.7","xmerl-1.2.6"],
  permanent},
 {"myapp","0.1",[],old}]
(myapp@127.0.0.1)> myapp_server:get_state().
123
Gen Server的状态值仍然为123。

好了,关于rebar就这些了,rebar的细节请查看附件资料。

李存刚(bland.li@heimi360.com & licungang@gmail.com)


注:这是以前和同事分享的一个学习总结,没有进行进一步的整理,以上操作系统都为ubuntu10.04 x86 erlang版本:R14A

在执行: ./bin/myapp console  报错:{"init terminating in do_boot",{'cannot load',hipe,get_file}}

reltool.config 添加:

{app, hipe, [{incl_cond, exclude}]}  

本课题设计了一种利用Matlab平台开发的植物叶片健康状态识别方案,重点融合了色彩与纹理双重特征以实现对叶片病害的自动化判别。该系统构建了直观的图形操作界面,便于用户提交叶片影像并快速获得分析结论。Matlab作为具备高效数值计算与数据处理能力的工具,在图像分析与模式分类领域应用广泛,本项目正是借助其功能解决农业病害监测的实际问题。 在色彩特征分析方面,叶片影像的颜色分布常与其生理状态密切相关。通常,健康的叶片呈现绿色,而出现黄化、褐变等异常色彩往往指示病害或虫害的发生。Matlab提供了一系列图像处理函数,例如可通过色彩空间转换与直方图统计来量化颜色属性。通过计算各颜色通道的统计参数(如均值、标准差及主成分等),能够提取具有判别力的色彩特征,从而为不同病害类别的区分提供依据。 纹理特征则用于描述叶片表面的微观结构与形态变化,如病斑、皱缩或裂纹等。Matlab中的灰度共生矩阵计算函数可用于提取对比度、均匀性、相关性等纹理指标。此外,局部二值模式与Gabor滤波等方法也能从多尺度刻画纹理细节,进一步增强病害识别的鲁棒性。 系统的人机交互界面基于Matlab的图形用户界面开发环境实现。用户可通过该界面上传待检图像,系统将自动执行图像预处理、特征抽取与分类判断。采用的分类模型包括支持向量机、决策树等机器学习方法,通过对已标注样本的训练,模型能够依据新图像的特征向量预测其所属的病害类别。 此类课题设计有助于深化对Matlab编程、图像处理技术与模式识别原理的理解。通过完整实现从特征提取到分类决策的流程,学生能够将理论知识与实际应用相结合,提升解决复杂工程问题的能力。总体而言,该叶片病害检测系统涵盖了图像分析、特征融合、分类算法及界面开发等多个技术环节,为学习与掌握基于Matlab的智能检测技术提供了综合性实践案例。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值