erlang应用发布

http://blog.csdn.net/zhangxinrun/article/details/6993892

参考“转载1”和“转载2”就可以了,但需要注意以下两点:

1.如果用rebar - create-app appid=abc 创建 “应用abc”,当前的目录名必须是abc,举例:在abc目录下执行rebar - create-app appid=abc,否则在应用发布的配置文件reltool.config中,配置lib_dirs, ["../../"]项时,找不到应用abc。
2.用rebar生成的abc应用的erlang源码文件为:abc_app.erl abc_sup.erl,如果需要添加新的erlang源代码,新的源代码文件的命名必须是"abc_"开头,例如:abc_server.erl ,否则在执行发布命令rebar generate时,不能将新添加的erlang源代码编译成功的abc_server.beam文件打包进“abc-1.ez”发布包。


转载1:http://www.linezing.com/blog/?p=351

Zfor项目的Rebar改造

本文档用于描述如何使用rebar erlang构建工具,将github上的zfor项目(https://github.com/chaoslawful/zfor)进行改造。
关于改造过程,我们约定:首先建立一个公共的工作目录(本文档中假定为work目录),作为zfor项目改造的主目录,改造过程中的所有操作均在此目录下完成。

1.    准备工作

1.1 下载zfor

1.       首先,在公共目录(work目录)下使用git命令下载zfor:

cd workgit clone https://github.com/chaoslawful/zfor.git

2.       然后,进入zfor目录,切换到zfor 1.0.10旧版本(目前,github上的master版本是已经rebar改造后的版本,因此我们需要重新下载1.0.10历史版本):

cd zforgit checkout 1.0.10

3.       Zfor项目的原始项目目录格式如下:

${PROJECT}├── bin├── cfg├── Changelog

├── COPYING

├── doc

├── examples

├── Makefile

├── pkg

├── README

├── src

└── THANKS

└── TODO

1.2 下载rebar

1.       首先,在公共目录(work目录)下使用git命令下载rebar:

cd workgit clone https://github.com/basho/rebar.git

2.       然后,进入rebar目录,编译rebar:

cd rebar./bootstrap

3.       编译后在该目录下生成rebar二进制执行文件:

1.3 项目规范

Rebar按照OTP设计原则组织项目,在此基础上,zfor项目的rebar改造过程遵循以下项目规范:

${PROJECT}├── c_src├── doc├── ebin

├── include

├── priv

├── src

└── test

其中:

  • c_src/ – 保存 Port Driver 相关的 C 代码
  • doc/ – 保存文档文件
  • ebin/ – 保存 Erlang 目标文件(即 *.beam),OTP 应用的描述文件 *.app 也放置在此
  • include/ – 保存 Erlang 头文件(即 *.hrl)
  • priv/ – 保存应用特有的文件,例如独立的 C 应用代码、脚本文件、rpm spec 等
  • src/ – 保存 Erlang 源代码文件(即 *.erl)
  • test/ – 保存项目相关的测试文件及数据,测试本身可以是 EUnit 风格或 common-test 风格的

2.    改造过程

2.1 创建rebar项目

首先,在公共目录(work目录)下,创建zfor的rebar改造项目目录:zfor_rebar,将1.2节生成的rebar二进制执行文件拷贝到该目录,并在该目录下创建rebar项目:

$ mkdir zfor_rebar$ cd zfor_rebar$ cp ../rebar/rebar ./$ ./rebar create-app appid=zfor

==> zfor_rebar (create-app)

Writing src/zfor.app.src

Writing src/zfor_app.erl

Writing src/zfor_sup.erl

2.2 创建必要的子目录

在zfor_rebar目录下,按照1.3节中的项目规范,建立必要的项目子目录:

$ cd zfor_rebar$ mkdir c_src$ mkdir doc$ mkdir ebin

$ mkdir include

$ mkdir priv

$ mkdir test

备注:src目录已经在创建rebar项目时自动生成。

2.3 迁移zfor项目文件

按照1.3节中的项目规范,进行zfor项目文件的迁移:

1.       c_src部分:

暂无。

2.       doc部分:

$ cd zfor$ mv ./doc/* ../zfor_rebar/doc/

3.       ebin部分:

暂无。

4.       include部分:

$ cd zfor$ cd src/zfor/$ mv ./include/* ../../../zfor_rebar/include/

5.       priv部分:

$ cd zfor$ cd src$ mv ./erlang_zfor/ ../../zfor_rebar/priv/$ mv ./java_zfor/ ../../zfor_rebar/priv/

$ mv ./libzfor/ ../../zfor_rebar/priv/

$ mv ./php_zfor/ ../../zfor_rebar/priv/

$ mv ./python_zfor/ ../../zfor_rebar/priv/

$ cd ..

$ mv ./bin ./scripts

$ mv ./scripts/ ../zfor_rebar/priv/

$ mv ./cfg/ ../zfor_rebar/priv/

$ mv ./examples/ ../zfor_rebar/priv/

$ mv ./pkg/ ../zfor_rebar/priv/

6.       src部分:

$ cd zfor$ cd src/zfor/$ mv ./src/* ../../../zfor_rebar/src/

7.       test部分:

$ cd zfor$ cd src/zfor/$ mv ./test/* ../../../zfor_rebar/test/

8.       其他部分

$ cd zfor$ mv Changelog ../zfor_rebar/$ mv COPYING ../zfor_rebar/$ mv README ../zfor_rebar/

$ mv THANKS ../zfor_rebar/

$ mv TODO ../zfor_rebar/

至此,已经将zfor项目迁移到了zfor_rebar目录下,最终的目录结构如下:

2.4 修改zfor.app.in配置文件

1. 进入zfor_rebar目录下的src目录,根据项目名,将zfor.app.in重命名为zfor_rebar.app.src:

$ cd zfor_rebar/src$ mv zfor.app.in zfor.app.src

2. 编辑zfor.app.src,将“{vsn, “%VSN%”}”改为“{vsn, “1.0.5″}”,将“{conf_path, “%CONFPATH%”}”改为“{conf_path, “/usr/local/etc/zfor”}”。

$ cd zfor_rebar/src$ vim zfor.app.src

2.5 编译项目

使用rebar compile命令编译zfor:

$ cd zfor_rebar$ ./rebar compile
==> zfor_rebar (compile)
Compiled src/zfor_app.erl
src/zfor_hostlist.erl:80: Warning: http:request/4 is deprecated and will be removed in R15B; use httpc:request/4
Compiled src/zfor_hostlist.erl
Compiled src/zfor_sup.erl
Compiled src/zfor_caretaker.erl
src/zfor_server.erl:50: Warning: NOT OPTIMIZED: called function handle_req/3 does not begin with a suitable binary matching instruction
src/zfor_server.erl:99: Warning: NOT OPTIMIZED: sub binary used by erlang:binary_to_list/1
Compiled src/zfor_server.erl
Compiled src/zfor_httpclient.erl
Compiled src/zfor_util.erl
Compiled src/zfor_main.erl
src/zfor_config.erl:240: Warning: http:request/4 is deprecated and will be removed in R15B; use httpc:request/4
src/zfor_config.erl:461: Warning: http:request/4 is deprecated and will be removed in R15B; use httpc:request/4
Compiled src/zfor_config.erl

2.6 发布项目

1. 在项目根目录下,创建rel发布目录,然后创建一个node用于发布:
$ mkdir rel
$ cd rel
$ ../rebar create-node nodeid=zfor
==> rel (create-node)
==> rel (create-node)
Writing reltool.config
Writing files/erl
Writing files/nodetool
Writing files/zfor
Writing files/app.config
Writing files/vm.args
$ cd -
2. 修改rel/reltool.config文件(其中**之间是需要修改的地方): 
{sys, [
       *{lib_dirs, ["../../"]}*,
       {rel, "zfor", "1",
        [
         kernel,
         stdlib,
         sasl,
         *zfor*
        ]},
       {rel, "start_clean", "",
        [
         kernel,
         stdlib
        ]},
       {boot_rel, "zfor"},
       {profile, embedded},
       {excl_sys_filters, ["^bin/.*",
                           "^erts.*/bin/(dialyzer|typer)"]},
       *{app, zfor, [{incl_cond, include}]}*,
       {app, sasl, [{incl_cond, include}]}
      ]}.
 
{rebar, [
         {empty_dirs, [
                       "log/sasl"
                      ]},
 
         {overlay, "overlay"}
         ]}.

3.       为了使rel目录对rebar可见,需要在项目根目录下,创建rebar.config配置文件:

{sub_dirs, ["rel"]}.

4.       配置完成后,生成发布版本:

./rebar generate
==> rel (generate)

5.       发布完成后,可以运行发布的服务:

$ chmod u+x rel/zfor/bin/zfor
./zfor start    #开启服务
./zfor stop    #停止服务



转载2:http://alancastro.org/2010/05/01/erlang-application-management-with-rebar.html

Erlang App. Management with Rebar

Introduction

Rebar is a build and packaging tool for Erlang applications. It is implemented in Erlang and the only dependency is the Erlang Virtual Machine, so it can work as a stand-alone escript in your project. Rebar was created byDave Smith from Basho, creators of Riak. In this tutorial I’ll be creating a sample application, building it and generating a release for it, all of this with Rebar.

Application Requirements

Rebar expects that your applications follows the OTP Design Principles. The application directory must have the following sub-directories:

  • src – Contains the Erlang source code.
  • ebin – Contains the Erlang object code, the beam files. The .app file is also placed here.
  • priv – Used for application specific files. For example, C executables are placed here. The function code:priv_dir/1 should be used to access this directory.
  • include – Used for include files.

Don’t worry about this, Rebar can create applications with this kind of directory structure automatically.

Installation

To install Rebar is very easy, just download it at: http://hg.basho.com/rebar/downloads/rebar. After getting it just run a chmod u+x rebar. Rebar depends on Erlang R13B03 (or later), so I advise you to get ErlangOTP source code em build it. There is a tutorial here: http://wiki.github.com/erlang/otp/installation.

Rebar’s Features

To see what Rebar offers just execute ./rebar -c and you’ll be able to see all of Rebar’s commands.

$ ./rebar -c
analyze                              Analyze with Dialyzer
build_plt                            Build Dialyzer PLT
check_plt                            Check Dialyzer PLT

clean                                Clean
compile                              Compile sources

create      template= [var=foo,...]  Create skel based on template 
                                      and vars
create-app                           Create simple app skel
create-node                          Create simple node skel

check-deps                           Display to be fetched dependencies
get-deps                             Fetch dependencies
delete-deps                          Delete fetched dependencies

generate    [dump_spec=0/1]          Build release with reltool
install     [target=]                Install build into target

eunit       [suite=foo]              Run eunit [test/foo_tests.erl] 
                                      tests

int_test    [suite=] [case=]         Run ct suites in ./int_test
perf_test   [suite=] [case=]         Run ct suites in ./perf_test
test        [suite=] [case=]         Run ct suites in ./test

I won’t be using all of the commands listed above for the sample application, so if you get more interested in it take a look at thesource code.

Getting Started

To get started off I’ll go step by step on creating a new project with rebar.

$ mkdir mysample
$ cd mysample
$ wget http://hg.basho.com/rebar/downloads/rebar
$ chmod u+x rebar
$ ./rebar create-app appid=mysample
==> mysample (create-app)
Writing ebin/mysample.app
Writing src/mysample_app.erl
Writing src/mysample_sup.erl

This was pretty easy to follow. Rebar creates this directory structure based on a previous created template. If you want to add new templates or change the ones that exists take a look at Rebar’s source code:http://bitbucket.org/basho/rebar/src and navigate topriv/templates/simpleapp.template.

Well, for now we’ve had Rebar create our initial application directories and files. Let’s take a look at the source code we’ve got so far:

ebin/mysample.app – Application descriptor

{application, mysample,
 [
  {description, ""},
  {vsn, "1"},
  {modules, [
             mysample_app,
             mysample_sup
            ]},
  {registered, []},
  {applications, [
                  kernel,
                  stdlib
                 ]},
  {mod, { mysample_app, []}},
  {env, []}
 ]}.

src/mysample_app.erl – Application callback module

-module(mysample_app).

-behaviour(application).

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

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

stop(_State) ->
    ok.

src/mysample_sup.erl – Supervisor callback module

-module(mysample_sup).

-behaviour(supervisor).

-export([start_link/0]).
-export([init/1]).

-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, 
[I]}).

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

init([]) ->
    {ok, { {one_for_one, 5, 10}, []} }.

The generated code is almost a fully working simple application, but there is one thing missing, aGeneric Server! So the next step is to create one. I’ll create a generic server calledmysample_server.erl.

Place this code in src/mysample_server.erl:

-module(mysample_server).

-behaviour(gen_server).

-export([start_link/0, say_hello/0]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

init([]) ->
    {ok, []}.

say_hello() ->
    gen_server:call(?MODULE, hello).

%% callbacks
handle_call(hello, _From, State) ->
    io:format("Hello from server!~n", []),
    {reply, ok, State};

handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

The next step is make the generic server part of the application, this is done by doing the following steps:

  • Add mysample_server into ebin/mysample.app under the modules tuple.
  • Make mysample_server a child of mysample supervisor.

So by making this changes we have the following new codes:

ebin/mysample.app:

{application, mysample,
 [
  {description, ""},
  {vsn, "1"},
  {modules, [
             mysample_app,
             mysample_sup,
             mysample_server
            ]},
  {registered, []},
  {applications, [
                  kernel,
                  stdlib
                 ]},
  {mod, { mysample_app, []}},
  {env, []}
 ]}.

src/mysample_sup.erl:

-module(mysample_sup).

-behaviour(supervisor).

-export([start_link/0]).
-export([init/1]).

-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, 
[I]}).

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

init([]) ->
    MySampleServer = ?CHILD(mysample_server, worker),
    {ok, { {one_for_one, 5, 10}, [MySampleServer]} }.

Now that we’ve made every change, let’s compile the project:

$ ./rebar compile
==> mysample (compile)
Compiled src/mysample_app.erl
Compiled src/mysample_sup.erl
Compiled src/mysample_server.erl

Now take a look at your ebin directory and check if each module has a beam file placed there.

What about now? We’ve got an application module, a supervisor, and a simple generic server, but what do we do with it? Well, wouldn’t be great to make your application work as a service that you can start, stop, and restart whenever you want? You can create this using some Erlang tools, but with Rebar you can do this in avery very easy way. Summarizing what I’ve just said: “Rebar can help you create anErlang Release”.

To create a release we have to create a new directory in the root of our project calledrel and create a node in it. A node is kind of a standalone Erlang VM for our application to run on.

$ mkdir rel
$ cd rel
$ ../rebar create-node nodeid=mysample
==> rel (create-node)
Writing reltool.config
Writing overlay/erts-vsn/bin/erl
Writing overlay/erts-vsn/bin/nodetool
Writing overlay/bin/mysample
Writing overlay/etc/app.config
Writing overlay/etc/vm.args
$ cd -

We’ve just created a node for our application to run on, this node is created using a template just like the one used in the application creation. You can see it at Rebar’s source code:http://bitbucket.org/basho/rebar/src/ and then head topriv/templates/simplenode.template.

Now we’re almost done. We only need to make some changes to the rel/reltool.config, file that contains the release configuration, so it can be compatible with our application’s modules.

Here is the changed version of the generated file, I will put * around the lines I changed, notice that they don’t belong to the real code.

{sys, [
       *{lib_dirs, ["../../"]}*,
       {rel, "mysample", "1",
        [
         kernel,
         stdlib,
         sasl,
         *mysample*
        ]},
       {rel, "start_clean", "",
        [
         kernel,
         stdlib
        ]},
       {boot_rel, "mysample"},
       {profile, embedded},
       {excl_sys_filters, ["^bin/.*",
                           "^erts.*/bin/(dialyzer|typer)"]},
       *{app, mysample, [{incl_cond, include}]}*,
       {app, sasl, [{incl_cond, include}]}
      ]}.

{rebar, [
         {empty_dirs, [
                       "log/sasl"
                      ]},

         {overlay, "overlay"}
         ]}.

If you want to know the meaning of each of this tuple’s options, look at Reltool Manual.

Now lets make this directory visible for rebar, for that we create rebar.config file in the root directory of our project.

rebar.config:

{sub_dirs, ["rel"]}.

Configuration is now over! Lets generate our release:

$ ./rebar generate

This command creates a release of your application. Take a look at yours rel/mysample folder and you’ll be able to see something like this:

$ ls rel/mysample
bin  erts-5.7.4  etc  lib  log  releases

Now let’s run our release service, see the step by step below:

$ chmod u+x rel/mysample/bin/mysample
$ ./rel/mysample/bin/mysample
Usage: mysample {start|stop|restart|reboot|ping|console|attach}

Seems that everything is alright. To make sure your application was packed in the release, run your service with console./rel/mysample/bin/mysample console and execute application:which_applications().. Check if you got something like this:

(mysample@127.0.0.1)1> application:which_applications().
[{mysample,[],"1"},
 {sasl,"SASL  CXC 138 11","2.1.8"},
 {stdlib,"ERTS  CXC 138 10","1.16.4"},
 {kernel,"ERTS  CXC 138 10","2.13.4"}]
(mysample@127.0.0.1)2> mysample_server:say_hello().
Hello from server!

If yes, you’ve done it! If not, make sure you’ve followed everything correctly.

Conclusions

The purpose of this tutorial was to give an introduction to a tool that helps we manage our Erlang applications. I think Rebar has a long way to go from here, but it is on the right track. It’s a great tool and if there were more documentation available there would have more people using it. I’ve talked about some of it’s most important features here, but in the beggining I showed that there is a lot more to it than just thancompile and generatefunctions. So get Rebar and start using it on your next project.


转载3(问题解决):http://lists.basho.com/pipermail/rebar_lists.basho.com/2011-March/000661.html

Hi Ken,I am fairly new to rebar, and I had a similar problem the other day. Theproblem is that your application must reside in a directory whose name isthe same as the application's name. This means that your application'jaus_core' must be in ~/Desktop/work/1_jaus/jaus_coreand not ~/Desktop/work/1_jaus/erljausHope this helps!-- DominiqueDominique Boucher* *| CTO*Nu Echo Inc.***1435, Saint-Alexandre Street, Suite 200, Montreal (Qc), Canada, H3A 2G4Tel: (514) 861-3246 ext 4231 | FAX: (514) 861-1676Dominique.Boucher at nuecho.com | www.nuecho.com | blog.nuecho.com*Because performance matters.***On Fri, Mar 11, 2011 at 12:36 AM, Ken Robinson <kenrobinsonster at gmail.com>wrote:> Hi All,>> I was trying to generate a release using the howtos:> https://github.com/basho/rebar/wiki/Release-handling>> http://alancastro.org/2010/05/01/erlang-application-management-with-rebar.html>> Below is my workflow and my reltool.config. What I'm trying to> understand is whether I need populate all the reltool config values> myself or does rebar do this for me? Any help would be greatly> appreciated.> Ken.>> Workflow> ========>kenrobinsonster at ubuntu-dev-01:~/Desktop/work/1_jaus/erljaus$ mkdir rel>kenrobinsonster at ubuntu-dev-01:~/Desktop/work/1_jaus/erljaus$ cd rel/>kenrobinsonster at ubuntu-dev-01:~/Desktop/work/1_jaus/erljaus/rel$ rebar> create-node nodeid=jaus> ==> rel (create-node)> Writing reltool.config> Writing files/erl> Writing files/nodetool> Writing files/jaus> Writing files/app.config> Writing files/vm.args>kenrobinsonster at ubuntu-dev-01:~/Desktop/work/1_jaus/erljaus/rel$ rebar> generate> ==> rel (generate)> {"init terminating in do_boot","Release jaus uses non existing> application jaus_core"}>> Crash dump was written to: erl_crash.dump> init terminating in do_boot (Release jaus uses non existing> application jaus_core)>>kenrobinsonster at ubuntu-dev-01:~/Desktop/work/1_jaus/erljaus/rel$ ls> ../ebin/> jaus_core.app jaus_core_transport_receiverec.beam> jaus_core_app.beam jaus_core_transport_records.beam> ...>> ReltoolConfig> ===========> {sys, [> {lib_dirs, ["../..", "../ebin"]},> {rel, "jaus", "1",> [> kernel,> stdlib,> sasl,> mnesia,> jaus_core> ]},> {rel, "start_clean", "",> [> kernel,> stdlib> ]},> {boot_rel, "jaus"},> {profile, embedded},> {excl_sys_filters, ["^bin/.*",> "^erts.*/bin/(dialyzer|typer)"]},> {app, sasl, [{incl_cond, include}]}> ]}.>> {target_dir, "jaus"}.>> {overlay, [> {mkdir, "log/sasl"},> {copy, "files/erl", "{{erts_vsn}}/bin/erl"},> {copy, "files/nodetool", "{{erts_vsn}}/bin/nodetool"},> {copy, "files/jaus", "bin/jaus"},> {copy, "files/app.config", "etc/app.config"},> {copy, "files/vm.args", "etc/vm.args"}> ]}.>>> --> regards,> Ken Robinson> Mob +61438681120> Home +61738523767>> _______________________________________________> rebar mailing list>rebar at lists.basho.com>http://lists.basho.com/mailman/listinfo/rebar_lists.basho.com>

原文地址:https://www.cnblogs.com/fvsfvs123/p/4172312.html