用 rebar3 项目组织代码有两种主要方式:作为单应用程序,或作为伞形项目。
单应用程序项目在目录的根包含单独的顶级应用程序,其 Erlang 源模块直接位于 src/
目录中。该格式适用于在 GitHub 上或以 Hex 格式发布的库,其目的是与全世界共享它们,但也可用于发行版,其允许发布直接引导应用程序的 Erlang 运行时系统。
伞形项目的定义特点是它们可以包含多个顶级 Erlang/OTP 应用程序,通常在顶级的 apps/
或 lib/
目录中。每个应用程序可能包含自己的 rebar.config
文件。此格式仅适用于包含一或多个顶级应用程序的发行版。
Rebar3 提供用于创建任意类型项目的模版,可以通过 rebar3 new <template> <project-name>
命令调用。<template>
的值可以是下面的任意一个:
app
:带有监督树的有状态 OTP 应用程序,作为单应用程序项目lib
:不带监督树的库 OTP 应用程序,用于将各种模块组织在一起,作为单应用程序项目release
:准备发布的伞型项目umbrella
:release
的别名escript
:单应用程序项目的一种特殊形式,可被构建为可运行脚本plugin
:用于 rebar3 插件的结构cmake
:生成用于构建 C/C++ 代码的 c_src
目录和 Makefile
比如:
x
$ rebar3 new app myapp
===> Writing myapp/src/myapp_app.erl
===> Writing myapp/src/myapp_sup.erl
===> Writing myapp/src/myapp.app.src
===> Writing myapp/rebar.config
===> Writing myapp/.gitignore
===> Writing myapp/LICENSE
===> Writing myapp/README.md
如果想了解关于 new
和可用选项的更多信息,请查看 commands 文档,以及访问 templates tutorial 学习如何创建和使用自定义模版。
在 rebar.config
文件中的 deps
键下列出依赖:
xxxxxxxxxx
{deps, [
{elli, "~> 3.3.0"}, % package
{elli, {git, "git://github.com/elli-lib/elli.git", {tag, "3.3.0"}}} % alternatively, source
]
}.
现在可以将依赖添加到项目的应用程序的 .app.src 文件中,以便 Erlang 知道依赖是必须的:
xxxxxxxxxx
{application, <APPNAME>,
[{description, ""},
{vsn, <APPVSN>},
{registered, []},
{modules, []},
{applications, [kernel,
stdlib,
elli]},
{mod, {<APPNAME>_app, []}},
{env, []}
]}.
<APPVSN>
的值可以是下面的任意一个:
版本类型 | 结果 |
---|---|
string() | 使用字符串作为版本。比如 "0.1.0" |
git | semver | 使用存储库上最新的 git 标签构造版本 |
{cmd, string()} | 使用在 Shell 中执行 string() 的内容的结果。比如使用文件 VERSION :{cmd, "cat VERSION | tr -d '[:space:]'"} |
{git, short | long} | 使用当前提交的简短的(8 个字符)或完整的 Git 引用 |
{file, File} | 使用文件的内容。比如,比使用 cmd 更好的使用 VERSION 文件的方式是:{file, "VERSION"} |
关于依赖处理的更多信息,请查看 dependency documentation。
获取依赖以及编译所有应用程序仅需一条命令,compile
。
xxxxxxxxxx
$ rebar3 compile
===> Verifying dependencies...
===> Fetching elli v3.3.0
===> Analyzing applications...
===> Compiling elli
===> Analyzing applications...
===> Compiling custom_hex_repos
可以在项目根目录下的 _build
目录中找到安装依赖、构建发行版的输出,以及任何其它被写到磁盘的输出。
xxxxxxxxxx
_build/
└── default
└── lib
└── elli
可以在 profiles documentation page 中找到关于 profile 和 _build
目录的更多信息。
默认情况下,除单独的模块中的 eunit
外,测试都在 test/
目录中。
仅运行测试所需的依赖可以被放置在 test
profile 中:
xxxxxxxxxx
{profiles, [
{test, [
{deps, [
{meck, "0.9.0"}
]}
]}
]}.
第一次运行 rebar3 ct
时,meck
将被安装到 _build/test/lib/
。但它不会被添加到 rebar.lock
。
xxxxxxxxxx
_build/
└── test
└── lib
└── meck
使用 relx 构建发行版。
在 rebar 中,创建具有发行版结构和默认 relx 配置(在 rebar.config
文件中)的新项目,运行:
xxxxxxxxxx
$ rebar3 new release myrel
===> Writing myrel/apps/myrel/src/myrel_app.erl
===> Writing myrel/apps/myrel/src/myrel_sup.erl
===> Writing myrel/apps/myrel/src/myrel.app.src
===> Writing myrel/rebar.config
===> Writing myrel/config/sys.config
===> Writing myrel/config/vm.args
===> Writing myrel/.gitignore
===> Writing myrel/LICENSE
===> Writing myrel/README.md
在 rebar.config
中,我们发现一些应用程序示例中没有的元素。
{relx, [{release, {myrel, "0.0.1"},
[myrel]},
{dev_mode, true},
{include_erts, false},
{extended_start_script, true}
]
}.
{profiles, [
{prod, [{relx, [{dev_mode, false},
{include_erts, true}]}
]}
]}.
此配置为使用 Relx 构建用于开发(默认 profile)和用于生产(生产 profile)的发行版提供一些不错的默认值。当构建生产版本时,我们很可能希望创建目标系统(包括 ERTS),并且肯定不希望该发行版包含到应用程序的符号连接(dev_mode
false
)。
xxxxxxxxxx
$ rebar3 release
===> Verifying default dependencies...
===> Compiling myrel
===> Starting relx build process ...
===> Resolving OTP Applications from directories:
_build/default/lib
/usr/lib/erlang/lib
===> Resolved myrel-0.1.0
===> Dev mode enabled, release will be symlinked
===> release successfully created!
使用默认的 rebar.config
,创建发行版的压缩归档作为目标系统就像将 profile 设置为 prod
,并且运行 tar
一样简单:
$ rebar3 as prod tar
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling relx_overlays
===> Assembling release myrel-0.1.0...
===> Release successfully assembled: _build/prod/rel/myrel
===> Building release tarball myrel-0.1.0.tar.gz...
===> Tarball successfully created: _build/prod/rel/myrel/myrel-0.1.0.tar.gz
访问 release section 获取更多细节。