Building an OTP release including Lager with rebar and reltool
September 2014.
Building an OTP release including Lager with rebar and reltool.
Create your app the usual way:
rebar create-app appid=testapplager
Add the following to
rebar.config
:
{lib_dirs,["deps"]}.
{sub_dirs, ["rel"]}.
{deps, [
{lager, ".*", {
git, "git://github.com/basho/lager.git", "master"}
}
]}.
{erl_opts, [{parse_transform, lager_transform}]}.
Add some code to your app, get the dependencies and compile.
rebar get-deps
rebar compile
Create a node configuration
mkdir rel && cd rel
rebar create-node nodeid=testapplager
Set the different paths to the dependencies and your app in
reltool.config
:
{sys, [
{lib_dirs, ["../deps"]},
{erts, [{mod_cond, derived}, {app_file, strip}]},
{app_file, strip},
{rel, "testapplager", "1",
[
kernel,
stdlib,
sasl,
lager,
testapplager
]},
{rel, "start_clean", "",
[
kernel,
stdlib
]},
{boot_rel, "testapplager"},
{profile, embedded},
{incl_cond, exclude},
{excl_archive_filters, [".*"]}, %% Do not archive built libs
{excl_sys_filters, ["^bin/.*", "^erts.*/bin/(dialyzer|typer)",
"^erts.*/(doc|info|include|lib|man|src)"]},
{excl_app_filters, ["\.gitignore"]},
{app, sasl, [{incl_cond, include}]},
{app, stdlib, [{incl_cond, include}]},
{app, kernel, [{incl_cond, include}]},
{app, lager, [{incl_cond, include}]},
{app, testapplager, [{mod_cond, app}, {incl_cond, include}, {lib_dir, ".."}]}
]}.
{target_dir, "testapplager"}.
{overlay, [
{mkdir, "log/sasl"},
{copy, "files/erl", "\{\{erts_vsn\}\}/bin/erl"},
{copy, "files/nodetool", "\{\{erts_vsn\}\}/bin/nodetool"},
{copy, "files/testapplager", "bin/testapplager"},
{copy, "files/testapplager.cmd", "bin/testapplager.cmd"},
{copy, "files/start_erl.cmd", "bin/start_erl.cmd"},
{copy, "files/install_upgrade.escript", "bin/install_upgrade.escript"},
{copy, "files/sys.config", "releases/\{\{rel_vsn\}\}/sys.config"},
{copy, "files/vm.args", "releases/\{\{rel_vsn\}\}/vm.args"}
]}.
Try to build the release:
rebar generate
Failure!
ERROR: generate failed while processing /root/some-sub-folder/testapplager/rel: {'EXIT',{{badmatch,{error,"Application compiler is used in release \"testapplager\" and cannot be excluded"}},
[{rebar_reltool,generate,2,
[{file,"src/rebar_reltool.erl"},{line,50}]},
{rebar_core,run_modules,4,[{file,"src/rebar_core.erl"},{line,425}]},
{rebar_core,execute,5,[{file,"src/rebar_core.erl"},{line,359}]},
{rebar_core,process_dir0,6,[{file,"src/rebar_core.erl"},{line,223}]},
{rebar_core,process_dir,4,[{file,"src/rebar_core.erl"},{line,130}]},
{rebar_core,process_each,5,[{file,"src/rebar_core.erl"},{line,296}]},
{rebar_core,process_dir0,6,[{file,"src/rebar_core.erl"},{line,199}]},
{rebar_core,process_dir,4,
[{file,"src/rebar_core.erl"},{line,130}]}]}}
The problem is that reltool won't include any package by default. This means that lager can't get its dependencies built into the release.
To solve this problem, either change the include condition to:
{incl_cond, derived},
Or manually include the dependencies:
{app, goldrush, [{incl_cond, include}]},
{app, syntax_tools, [{incl_cond, include}]},
{app, compiler, [{incl_cond, include}]},
Then rebuild your release.