Let's set the stage - we have a project with a source file under a subdir of src/
.
When we compile it the first time, everything looks good - the code returns the value
defined by the macro:
$ cd /tmp
$ git clone https://github.com/erszcz/rebar_src_not_recompiled.git src_not_recompiled
$ cd src_not_recompiled
$ rg -C1 MACRO src/
src/subdir/m.erl
7-f() ->
8: ?MACRO.
src/header.hrl
1:-define(MACRO, t2).
$ r3 shell
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling src_not_recompiled
Erlang/OTP 23 [erts-11.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Eshell V11.1.3 (abort with ^G)
1> m:f().
t2
2>
However, on the macro definition change, the code still returns the old value:
$ rg -C1 MACRO src/
src/header.hrl
1:-define(MACRO, t3).
src/subdir/m.erl
7-f() ->
8: ?MACRO.
$ r3 shell
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling src_not_recompiled
Erlang/OTP 23 [erts-11.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Eshell V11.1.3 (abort with ^G)
1> m:f().
t2
2>
If we move the source file directly under src/
, though, things start working as expected:
$ mv src/subdir/m.erl src/
$ r3 shell
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling src_not_recompiled
Erlang/OTP 23 [erts-11.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Eshell V11.1.3 (abort with ^G)
1> m:f().
t3
2>
So, this is an inconsistency, since Rebar3 compiles source files found under subdirectories of src/
, but does not recompile them if the header files they include change.
We can fix that by modifying the src_dirs
option in rebar.config
:
$ mv src/m.erl src/subdir/
$ cat rebar.config
{erl_opts, [debug_info]}.
{deps, []}.
{src_dirs, ["src", "src/subdir"]}.
$ rg -C1 MACRO src/
src/subdir/m.erl
7-f() ->
8: ?MACRO.
src/header.hrl
1:-define(MACRO, t4).
$ r3 shell
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling src_not_recompiled
Erlang/OTP 23 [erts-11.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Eshell V11.1.3 (abort with ^G)
1> m:f().
t4
2>
Now changing the header file leads to the source file depending on it to be recompiled.