用 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 获取更多细节。