- Copy scripts from the _build directory after
rebar3 escriptize - Create fully self-contained releases
- Set emulator flags (like
+pc unicode) forrebar3 shell
Copy scripts from the _build directory after rebar3 escriptize
seen in erlperf
Consider the default escript project:
$ rebar3 new escript posthook_example $ cd posthook_example/ $ rebar3 escriptize $ ./_build/default/bin/posthook_example some arguments Args: ["some","arguments"]
it's a bit of extra friction to ask people to run the script from that location, when they've only checked out your project to use your script. You can lower that friction with a posthook that copies the file, by adding this to the rebar.config:
{post_hooks, [
{"(linux|darwin|solaris|freebsd|netbsd|openbsd)", escriptize,
"cp \"$REBAR_BUILD_DIR/bin/posthook_example\" ./posthook_example"},
{"win32", escriptize,
"robocopy \"%REBAR_BUILD_DIR%/bin/\" ./ posthook_example* " "/njs /njh /nfl /ndl & exit /b 0"}
]}.
Create fully self-contained releases
You make a little app, build a release, go to run it ... and it's obviously incomplete and starting with your system's erlexec? How is that supposed to work?
$ rebar3 new release demo $ cd demo $ rebar3 release $_build/default/rel/demo/bin/demo foreground
That's supposed to work for development. The default relx section in your rebar.config looks like this:
{relx, [{release, {demo, "0.1.0"},
[demo,
sasl]},
{mode, dev},
%% automatically picked up if the files
%% exist but can be set manually, which
%% is required if the names aren't exactly
%% sys.config and vm.args
{sys_config, "./config/sys.config"},
{vm_args, "./config/vm.args"}
%% the .src form of the configuration files do
%% not require setting RELX_REPLACE_OS_VARS
%% {sys_config_src, "./config/sys.config.src"},
%% {vm_args_src, "./config/vm.args.src"}
]}.
And that {mode, dev} is why. From https://rebar3.org/docs/deployment/releases/#modes,
dev [{dev_mode, true}, {include_src, true}, {debug_info, keep}, {include_erts, false}]
prod [{include_src, false}, {debug_info, strip}, {include_erts, true}, {dev_mode, false}]
minimal [{include_src, false}, {debug_info, strip}, {include_erts, false}, {dev_mode, false}]
dev mode includes your source but excludes erts - the Erlang Runtime System.
To get the release that you expected, you want the production profile that's also in your rebar.config:
{profiles, [{prod, [{relx,
[%% prod is the default mode when prod
%% profile is used, so does not have
%% to be explicitly included like this
{mode, prod}
%% use minimal mode to exclude ERTS
%% {mode, minimal}
]
}]}]}.
To use that:
$ rebar3 as prod release # 'prod' here is the *profile* name $ _build/prod/rel/demo/bin/demo foreground
Now you'll see that it's using the release bundled erts, and you can tar this up and deploy it - to a sufficiently similar machine. You'll probably want an Alpine Linux docker to supply much more Linux-portable binaries.
Note also, erts is huge:
$ tar -C _build/prod/rel -Jcvf demo.tar.xz demo $ du -sh _build/prod demo.tar.xz 134M _build/prod 14M demo.tar.xz
This is 3-4 golang binaries, compressed!
Set emulator flags (like +pc unicode) for rebar3 shell
rebar3 is an escript and it reuses its own node for the shell, so there is no project configuration that can change the emulator flags for rebar3 shell, because the emulator's running before any such configuration can be read.
You'll have to change rebar3's own startup:
- Set
ERL_FLAGSin the environment:ERL_FLAGS="+pc unicode" rebar3 shell
- Rebuild rebar3 to have the wanted flags, with e.g. this edit to its rebar.config:
-{escript_emu_args, "%%! +sbtu +A1\n"}. +{escript_emu_args, "%%! +sbtu +A1 +pc unicode\n"}.