Skip to content

Instantly share code, notes, and snippets.

@erszcz
Last active April 15, 2021 11:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erszcz/516f8caec842262ffa3e325fa3db4de8 to your computer and use it in GitHub Desktop.
Save erszcz/516f8caec842262ffa3e325fa3db4de8 to your computer and use it in GitHub Desktop.
Rebar3 inconsistency between compiling and recompiling source files under src/ subdirs

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.

$ r3 --version
rebar 3.14.4+build.4978.ref942a9fa8 on Erlang/OTP 23 Erts 11.1.3
$ r3 report
Rebar3 report
 version 3.14.4+build.4978.ref942a9fa8
 generated at 2021-04-15T11:32:09+00:00
=================
Please submit this along with your issue at https://github.com/erlang/rebar3/issues (and feel free to edit out private information, if any)
-----------------
Task:
Entered as:

-----------------
Operating System: x86_64-apple-darwin19.6.0
ERTS: Erlang/OTP 23 [erts-11.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Root Directory: /Users/erszcz/.asdf/installs/erlang/23.1.4
Library directory: /Users/erszcz/.asdf/installs/erlang/23.1.4/lib
-----------------
Loaded Applications:
bbmustache: 1.10.0
certifi: 2.5.3
cf: 0.3.1
common_test: 1.19
compiler: 7.6.5
crypto: 4.8
cth_readable: 1.5.1
dialyzer: 4.2.1
edoc: 0.12
erlware_commons: 1.4.0
eunit: 2.6
eunit_formatters: 0.5.0
getopt: 1.0.1
hipe: 4.0.1
inets: 7.3
kernel: 7.1
providers: 1.8.1
public_key: 1.9.1
relx: 4.4.0
sasl: 4.0.1
snmp: 5.6.1
ssl_verify_fun: 1.1.6
stdlib: 3.13.2
syntax_tools: 2.3.1
tools: 3.4.1

-----------------
Escript path: /Users/erszcz/bin/rebar3
Providers:
  app_discovery as clean compile compile cover ct deps dialyzer do edoc escriptize eunit get-deps help install install_deps list lock new path pkgs release relup report repos shell state tar tree unlock update upgrade upgrade upgrade version xref
$ tree
.
|-- LICENSE
|-- README.md
|-- log
|-- log2
|-- rebar.config
|-- rebar.lock
`-- src
    |-- header.hrl
    |-- src_not_recompiled.app.src
    |-- src_not_recompiled.erl
    `-- subdir
        `-- m.erl

2 directories, 10 files
$ 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, t6).
$ 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().
t6
2>
$ rg -C1 MACRO src/
src/subdir/m.erl
7-f() ->
8:    ?MACRO.

src/header.hrl
1:-define(MACRO, t7).
$ 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().
t6
2>
$
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment