Basic Usage
Overview of using rebar3 for project building.
OTP Only
Rebar3 only handles OTP-structured projects, consisting of applications and/or a release. Previous versions of rebar would build any Erlang source files it encountered in subdirectories and not require a project adhere to OTP standards.
New App or Release
There are two main ways to organize code with rebar3 projects: either as a single application, or as an umbrella project.
Single application projects contain a lone top-level application at the root of the directory, with its Erlang source modules directly inside a src/
directory. This format is applicable to libraries to be published on github or in hex with the objective of making them shareable to the world, but can also be used with Releases, which allow to ship an Erlang runtime system that boots the application directly.
Umbrella projects' defining characteristic is that they can contain multiple top-level Erlang/OTP applications, usually within a top-level apps/
or lib/
directory. Each of these applications may contain its own rebar.config file. This format is only applicable for releases with one or more top-level applications.
Rebar3 comes with templates for creating either types of project, callable through the rebar3 new <template> <project-name>
command. The <template>
value can be any of:
app
: a stateful OTP application with a supervision tree, as a single application projectlib
: a library OTP application (without supervision trees), useful for grouping together various modules, as a single application projectrelease
: an umbrella project ready to be releasedescript
: a special form of single application project that can be built as a runnable scriptplugin
: structure for a rebar3 plugin.
For example:
$ 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
For more information on new
and available options check the docs on commands and to learn how to create and use custom templates go to the templates tutorial.
Adding Dependencies
Dependencies are listed in rebar.config
file under the deps
key:
{deps, [
{cowboy, "1.0.1"}, % package
{cowboy, {git, "git://github.com/ninenines/cowboy.git", {tag, "1.0.1"}}} % alternatively, source
]
}.
Version in SCM Dep Ignored
Note that while rebar3 supports the old format for a dependency to allow backwards compatibility, such as
{cowboy, ".*", {git, "git://github.com/ninenines/cowboy.git", {tag, "1.0.1"}}}
, the second element, in this case".*"
, is ignored.
Now you can add the dep to one of your project's application's .app.src file under applications so that Erlang knows the dependency is required for yours to work:
{application, <APPNAME>,
[{description, ""},
{vsn, "<APPVSN>"},
{registered, []},
{modules, []},
{applications, [
kernel
,stdlib
,cowboy
]},
{mod, {<APPNAME>_app, []}},
{env, []}
]}.
For more information on dependency handling view the dependency documentation
Building
Only one command, compile
, is required to fetch dependencies and compile all applications.
$ rebar3 compile
==> Verifying dependencies...
==> Fetching cowboy
==> Fetching ranch
==> Fetching cowlib
==> Compiling cowlib
==> Compiling ranch
==> Compiling cowboy
==> Compiling myapp
Dependencies Always Fetched
Unlike previous rebar releases with rebar3 the dependencies are fetched and compiled if they are not found when running a command like
compile
. This is achieved through provider dependencies you can read about in the plugin tutorial.
Output Format
Output for installing dependencies, building releases and any other output written to disk is found in the _build
directory at the root of the project.
_build/
└── default
└── lib
├── cowboy
├── cowlib
└── ranch
More about profiles and the _build
directory can be found in the profiles documentation page.
Testing
Tests by default are expected to be found under the test/
directory, aside from eunit
found within individual modules.
Dependencies that are only needed for running tests can be placed in the test
profile:
{profiles, [
{test, [
{deps, [
{meck, {git, "git://github.com/eproxus/meck.git", {tag, "0.8.2"}}}
]}
]}
]}.
Now the first time rebar3 ct
is run meck
will be installed to _build/test/lib/
. But it will not be added to rebar.lock
.
_build/
└── test
└── lib
└── meck
Releases and Target Systems
Releases are built using relx.
Relx and Not Reltool
Unlike previous rebar versions, reltool is not provided with a rebar3 interface at all. However, if you still want to use reltool you can access it since it comes with Erlang/OTP.
Creating a new project with a release structure and default relx
config in the rebar.config
file run:
$ 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
Looking in rebar.config
we find a couple elements that were not there in our application example.
{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}]}
]}
]}.
This configuration provides some nice defaults for building a release with relx for development (default profile) and for production (prod profile). When building a release for production we'll most likely want to create a target system (include erts) and definitely will not want the release to contain symlinks to apps (dev_mode false).
$ 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!
Relx dev_mode
Since the default profile's config for the release sets
dev_mode
totrue
the applications for the release found under_build/rel/myrel/lib
are symlinks to_build/lib
andapps/myrel
. So as you develop and recompile your app you do not need to recreate the release but simply restart the node or reload the modules.
With the default rebar.config
, creating a compressed archive of the release as a target system is as simple as setting the profile to prod
and running tar
:
$ rebar3 as prod tar
===> Verifying default dependencies...
===> Compiling myrel
===> Starting relx build process ...
===> Resolving OTP Applications from directories:
.../myrel/apps
/usr/lib/erlang/lib
===> Resolved myrel-0.1.0
===> Including Erts from /usr/lib/erlang
===> release successfully created!
===> tarball myrel/_build/rel/myrel/myrel-0.1.0.tar.gz successfully created!
For more details go to the release section.
Updated about 2 years ago