A user of the GNU Autotools (Autoconf and Automake) with Erlang/OTP has recently asked me about a way to automatically generate the .app
(application resource) files and .rel
(release resource) files for an Erlang/OTP application.
As for now, Automake provides no help to generate those files. This is Autoconf’s job. What Autoconf can do is help you avoid the manual duplication of information between several files, and help you synchronize the content of the .app
and .rel
files with the state of your system and your Erlang/OTP installation. The trick is to let Autoconf generate parts of the .app
and .rel
files for you.
To let Autoconf substitute parts of those files, first add their names into the AC_CONFIG_FILES
macro call, in your configure.ac
file:
AC_CONFIG_FILES([... sample.app sample.rel])
Then, name your files with extensions .app.in
and .rel.in
, e.g. sample.app.in
and sample.rel.in
, as the configure
script will generate sample.app
fromsample.app.in
and sample.rel
from sample.rel.in
. Your .app.in
and .rel.in
files should contain variables to substitute enclosed with @...@
.
For instance, a sample.app.in
file could be:
{application, @PACKAGE@, [{description, "Sample Erlang server"}, {vsn, "@VERSION@"}, {modules, [sample_app, sample_sup, sample_server]}, {registered, [sample_sup, sample_server]}, {applications, [kernel, stdlib]}, {mod, {sample_app, []}} ]}.
The @PACKAGE@
and @VERSION@
parts are substituted with the information supplied in the AC_INIT
macro call in configure.ac
.
Likewise, a sample.rel.in
file could be:
{release, {"@PACKAGE@", "@VERSION@"}, {erts, "5.6.1"}, [{kernel, "@ERLANG_LIB_VER_kernel@"}, {stdlib, "@ERLANG_LIB_VER_stdlib@"}, {@PACKAGE@, "@VERSION@"}]}.
The variables ERLANG_LIB_VER_kernel
and ERLANG_LIB_VER_stdlib
contain the version numbers of the installed libraries named kernel
and stdlib
. To define such variables automatically with the versions of the libraries actually installed in your system, you just have to call the standard AC_ERLANG_CHECK_LIB
Autoconf macro in your configure.ac
file, e.g.:
AC_ERLANG_CHECK_LIB([kernel]) AC_ERLANG_CHECK_LIB([stdlib])
Note also that the ERTS version is not yet automatically determined by the standard Autoconf macros. However, Ruslan also proposed a new macro,AC_ERLANG_SUBST_ERTS_VER
, to do that:
# AC_ERLANG_SUBST_ERTS_VER # ------------------------------------------------------------------- AC_DEFUN([AC_ERLANG_SUBST_ERTS_VER], [AC_REQUIRE([AC_ERLANG_NEED_ERLC])[]dnl AC_REQUIRE([AC_ERLANG_NEED_ERL])[]dnl AC_CACHE_CHECK([for Erlang/OTP ERTS version], [erlang_cv_erts_ver], [AC_LANG_PUSH(Erlang)[]dnl AC_RUN_IFELSE( [AC_LANG_PROGRAM([], [dnl Version = erlang:system_info(version), file:write_file("conftest.out", Version), halt(0)])], [erlang_cv_erts_ver=`cat conftest.out`], [AC_MSG_FAILURE([test Erlang program execution failed])]) AC_LANG_POP(Erlang)[]dnl ]) AC_SUBST([ERLANG_ERTS_VER], [$erlang_cv_erts_ver]) ])# AC_ERLANG_SUBST_ERTS_VER
You only have to put the code of that macro for instance in a acinclude.m4
file, placed in the same directory as the configure.ac
file, and to call it in configure.ac
:
AC_ERLANG_SUBST_ERTS_VER
That way, the ERLANG_ERTS_VER
variable gets automatically defined with the detected installed ERTS version, and can be substituted in your .rel.in
file, e.g. insample.rel.in
: {release, {"@PACKAGE@", "@VERSION@"}, {erts, "@ERLANG_ERTS_VER@"}, [{kernel, "@ERLANG_LIB_VER_kernel@"}, {stdlib, "@ERLANG_LIB_VER_stdlib@"}, {@PACKAGE@, "@VERSION@"}]}.
Note to myself: I should really really take a little time to submit the definition of Ruslan’s AC_ERLANG_SUBST_ERTS_VER
macro to the GNU Autotools team for inclusion into the standard Autoconf…