Base Config
Nearly all of Rebar3’s configuration is done by modifying a rebar.config
file at the root of your project or OTP application’s main directory. The values defined at the root of a project will apply to all applications declared there, and specific configuration files within an OTP application’s main directory will apply only to that application. The few exceptions to that rule are global configuration used for plugins and environment variables for changes to overall Rebar3 behaviour.
This page documents all of the standard options that can go in a rebar.config
file, and the environment variables that can impact Rebar3’s behaviour.
Environment configuration
Rebar3 supports some options that will impact the behaviour of the tool wholesale. Those are defined as OS environment variables, as follows:
Alias
Aliases allow for creating new commands out of existing ones, as if they were run one after the other:
Arguments (as with a command line) can be passed by replacing Provider
with {Provider, Args}
.
Artifacts
Artifacts are a list of files that are required to exist after a successful compilation (including any compile hooks) other than Erlang modules. This is useful to let rebar3
figure out if a dependency with some non-Erlang artifacts was successfully built or not. Examples where this can be useful include identifying C code built for shared libraries, rendered templates, or that an escript was properly generated.
If a dependency is found to already be built (meaning its .app
file’s list of modules matches its .beam
files and all its artifacts exist) it will not have the compilation provider or its hooks called on it during a subsequent run of rebar3
.
What the paths are relative to depends on if it is defined at the top level of an umbrella project or not. For example, let’s say we have a project my_project
that contains an application my_app
under apps/my_app/
that we build an escript
from. Then we want to tell rebar3
to not consider the configuration in my_project/rebar.config
, since it is the top level rebar.config
of an umbrella. The artifact
will be relative to the profile_dir
, which by default is _build/default/
:
If instead it isn’t an umbrella but with my_app
being the top level directory the artifact defined in rebar.config
is relative to the application’s output directory, in this case _build/default/lib/my_app/
but we can use a template to define it from profile_dir
as well:
All available template key are listed in the table below.
Template Key | Description |
---|---|
profile_dir | The base output directory with the profile string appended, default: _build/default/ . |
base_dir | The base output directory, default: _build or value of REBAR_BASE_DIR env var. |
out_dir | The application’s output directory, default: _build/default/lib// . |
One more example would be using artifacts within an override, in this case for eleveldb
:
The artifact is define on the application eleveldb
so it is relative to the output directory, meaning the path used above is the same as if we used "{{out_dir}}/priv/eleveldb.so"
.
Compilation
Compiler options can be set with erl_opts
, available options are listed in the Erlang compile module’s documentation.
Additionally it is possible to set platform specific options. The options run a regular expression against the OTP version joined with the OS details.
The version string might look like "22.0-x86_64-apple-darwin18.5.0-64"
so if you want to check for a specific OTP version (and avoid matching against an OS version), remember to prefix your regular expression with ^
.
A separate compile option is one to declare modules to compile before all others:
And some other general options exist:
Other Erlang-related compilers are supported with their own configuration options:
- Leex compiler with
{xrl_opts, [...]}
- SNMP MIB Compiler with
{mib_opts, [...]}
- Yecc compiler with
{yrl_opts, [...]}
Rebar3 compiler options
Rebar3 ships with some compiler options specific to it.
Enable/Disable recursive compiling
Disable or enable recursive compiling globally:
Disable or enable recursive compiling on src_dirs
:
Disable or enable recursive compiling on for extra_src_dirs
:
Examples
All three options can be combined for granularity which should provide enough flexibility for any project. Below are some examples.
Disable recursive compiling globally, but enable it for a few dirs:
Disable recursive compiling on test and other dirs:
Completion
Options mirror those specified in Commands arguments.
Common Test
Reference of common test options for ct_opts
: https://www.erlang.org/doc/man/ct.html#run_test-1
A special option allows to load a default sys.config
set of entries using {ct_opts, [{sys_config, ["name.of.config"]}]}
. From the command line, it is however specified as --sys_config name.of.config
.
Options often exist mirroring those that can be specified in Commands arguments.
Cover
Enable code coverage in tests with {cover_enabled, true}
. Then the cover
provider can be run after tests to show reports. The option {cover_opts, [verbose]}
can be used to force coverage reports be printed to the terminal rather than just in files. Specific modules can be blacklisted from code coverage by adding {cover_excl_mods, [Modules]}
to the config file. Applications can be blacklisted as a whole with the {cover_excl_apps, [AppNames]}
option.
Dialyzer
To find all possible dialyzer:warn_option()
use dialyzer documentation.
For information on suppressing warnings in modules see the Requesting or Suppressing Warnings in Source Files section of the Dialyzer documentation.
Distribution
Multiple providers and plugins may demand to support distributed Erlang. Generally, the configuration for all such commands (such as ct
and shell
) respect the following configuration values:
Directories
The following options exist for directories; the value chosen below is the default value
Furthermore, Rebar3 stores some of its configuration data in ~/.config/rebar3
and cache some data in ~/.cache/rebar3
. Both can be overridden by specifying {global_rebar_dir, "./some/path"}.
EDoc
All options supported by EDoc can be put in {edoc_opts, [...]}
.
Escript
Full details at the escriptize command. Example configuration values below.
Because of the structure of escript building, options at the top-level rebar.config
file only are used to build an escript.
EUnit
A special option allows to load a default sys.config
set of entries using {eunit_opts, [{sys_config, ["name.of.config"]}]}
. From the command line, it is however specified as --sys_config name.of.config
.
Eunit Options reference: https://www.erlang.org/doc/man/eunit.html#test-2
Hex Repos and Indexes
Starting with Rebar3 version 3.7.0, multiple Hex repositories (or indexes) can be used at the same time. Repositories are declared in an ordered list, from highest priority to lowest priority.
When looking for a package, repositories are going to be traversed in order. As soon as one of the packages fits the description, it is downloaded. The hashes for each found packages are kept in the project’s lockfile, so that if the order of repositories changes and some of them end up containing conflicting packages definitions for the same name and version pairs, only the expected one will be downloaded.
This allows the same mechanism to be used for both mirrors, private repositories (as provided by hex.pm), and self-hosted indexes.
For publishing or using a private repository you must use the rebar3_hex plugin to authenticate, rebar3 hex auth
. This creates a separate config file ~/.config/rebar3/hex.config
storing the keys.
Minimum OTP Version
A minimum version of Erlang/OTP can be specified which causes a build to fail if an earlier version is being used to build the application.
Overrides
Overrides allow for modifying the configuration of a dependency from a higher level application. They are meant to allow quick fixes and workarounds, although we do recommend working on permanent fixes that make it to the target app’s configuration when possible.
Overrides come in 3 flavours: add, override on app, and override on all.
These are applied to dependencies, and dependencies can have their own overrides as well that are applied in the following order: overrides on all, per app overrides, per app additions.
As an example, this can be used to force all the dependencies to be compiled with debug_info
by default, and to force no_debug_info
in case the production profile is used.
Another example could be to remove warnings_as_errors
as a compiler option for all applications:
Do note that overrides don’t work on the finalized flattened option, but on the configuration as you see it in the project’s rebar.config
file. This means that if you want to replace the value of some configuration that is changed in a profile, you must override that profile’s entry.
🚧
Overrides For All Apps in Umbrella Projects
In an umbrella project, overrides that are specified in the top-level rebar.config file will also apply to applications within the `apps/` or `lib/` directory. By comparison, overrides specified in the `rebar.config` file at the application level will only apply to their dependencies.
Hooks
There are two types of hooks: shell hooks and provider hooks. They both apply to the same type of providers.
Shell Hooks
Hooks provide a way to run arbitrary shell commands before or after hookable providers, optionally first matching on the type of system to choose which hook to run. Shell hooks are run after provider hooks.
An example for building merl with Rebar3 by using pre_hooks
:
🚧
Behaviour of post_hooks
A
post_hooks
entry will only be called if its hookable provider was successful. This means that if you add apost_hooks
entry foreunit
, it will only be called if your EUnit tests are able to finish successfully.
In shell hooks, environment variables from the host OS and those defined by the shell_hooks_env
entry are available.
Starting with v3.23.0
, additional environment variables exported by rebar3
are documented and can be used in shell hooks. The variables are described in the table below (all paths except REBAR_APP_DIRS
and REBAR_SRC_DIRS
are absolute):
Name | Description | Default |
---|---|---|
REBAR_ROOT_DIR |
Root of the project | |
REBAR_BUILD_DIR |
Build directory of a profile | $REBAR_ROOT_DIR/_build/$REBAR_PROFILE |
REBAR_DEPS_DIR |
Directory where dependencies are stored | $REBAR_BUILD_DIR/lib |
REBAR_CHECKOUTS_DIR |
Directory which is searched for checkout dependencies | $REBAR_ROOT_DIR/_checkouts |
REBAR_CHECKOUTS_OUT_DIR |
Directory where checkout dependencies are stored | $REBAR_BUILD_DIR/checkouts |
REBAR_PLUGINS_DIR |
Directory where plugins are stored | $REBAR_BUILD_DIR/plugins |
REBAR_GLOBAL_CONFIG_DIR |
Directory which is searched for global rebar.config |
$HOME/.config/rebar3 |
REBAR_GLOBAL_CACHE_DIR |
Cache directory | $HOME/.cache/rebar3 |
REBAR_TEMPLATE_DIR |
Directory which is searched for templates | $REBAR_GLOBAL_CONFIG_DIR/templates |
REBAR_APP_DIRS |
Colon-separated list of relative paths which can contain applications | apps/*:lib/*:. |
REBAR_SRC_DIRS |
Colon-separated list of relative paths which can contain source code (including extra_src_dirs) - recursive option is ignored, paths are returned as is |
src |
ERLANG_ARCH |
Wordsize of the system | Return value of rebar_api:wordsize() |
ERLANG_TARGET |
Description of the system | Return value of rebar_api:get_arch() |
ERLANG_ROOT_DIR |
Root directory of Erlang installation | Return value of code:root_dir() |
ERLANG_ERTS_VER |
Version of the erts |
Return value of erlang:system_info(version) |
ERL |
Path to erl executable |
$ERLANG_ROOT_DIR/bin/erl |
ERLC |
Path to erlc executable |
$ERLANG_ROOT_DIR/bin/erlc |
ERLANG_LIB_DIR_erl_interface |
Path to the erl_interface application (if it’s missing, variable is not defined!) |
$ERLANG_ROOT_DIR/lib/erl_interface |
ERLANG_LIB_VER_erl_interface |
Version of the erl_interface application (if it’s missing, variable is not defined!) |
Provider Hooks
Providers are also able to be used as hooks. The following hook runs clean
before compile
runs. To execute commands in a namespace a tuple is used as second argument. Provider hooks are run before shell hooks.
Hookable Points in Providers
Only specific built-in providers support hooks attached to them. Control depends on whether the provider operates on the project’s applications (each application and dependency) or if it’s expected to only run on the project at large.
Provider hooks are run before shell hooks.
Hook | before and after |
---|---|
clean | each application and dependency, and/or before and after all top-level applications are compiled* |
ct | the entire run |
compile | each application and dependency, and/or before and after all top-level applications are compiled* |
edoc | the entire run |
escriptize | the entire run |
eunit | the entire run |
release | the entire run |
tar | the entire run |
erlc_compile | compilation of the beam files for an app |
app_compile | building of the .app file from .app.src for an app |
* These hooks are, by default, running for every application, because dependencies may specify their own hook in their own context. The distinction is that in some cases (umbrella apps), hooks can be defined on many levels (omitting overrides):
- the rebar.config file at the application root
- each top-level app’s (in
apps/
orlibs/
) rebar.config - each dependency’s rebar.config
By default, when there is no umbrella app, the hook defined in the top-level rebar.config is attributed to be part of the top-level app. This allows the hook to keep working for a dependency when the library is later published.
If however the hook is defined in rebar.config at the root of a project with umbrella applications, the hooks will be run before/after the task runs for all of the top-level applications.
To preserve the per-app behaviour in an umbrella project, hooks must instead be defined within each application’s rebar.config.
Relx
See Releases
Plugins
See Plugins. Use {plugins, [Dep]}
for plugins required to make the project build when used as a dependency, and {project_plugins, [...]}
for plugins that provide utilities that aren’t required for the project to build when used as a dependency.
Shell
The rebar3 shell
REPL will automatically boot applications if a relx
entry is found, but apps to be started by the shell can be specified explicitly with {shell, [{apps, [App]}]}
.
Other options include:
Option | Value | Description |
---|---|---|
apps | [app1, app2, …] | Applications to be booted by the shell. Overtakes the relx entry values |
config | “path/to/a/file.config” | Loads a .config file (such as sys.config ) for the applications to be booted by the shell. |
script_file | “path/to/a/file.escript” | Evaluates a given escript before booting the applications for a node. |
app_reload_blacklist | [app1, app2, …] | Applications that should not be reloaded when calling commands such as r3:compile() . Useful when working with applications such as ranch , which crash after two reloads. |
XRef
You can also ignore xref
warnings for certain modules or functions by using the -ignore_xref(_).
attribute in your modules.
This is useful for ignoring functions that give you undesired warnings such as undefined_function_calls
and exports_not_used
, like so: