lfe-rebar3/compile updates
Eric Bailey
    
    
    
      Written on 11 February, 2016
      
      Updated on 18 December, 2023
      
      Tags: lfe, lisp, erlang, beam, rebar3, tooling, open-source
    
  
Since much of my time these days is spent (or 'writing 'developing 'evangelizing) LFE, it should come as no surprise that I use the rebar3
compiler plugin extensively. In doing so, I noticed it always recompiles every
.lfe file it finds, irrespective of the staleness of the corresponding .beam
file. Having compiled a fair amount of vanilla Erlang via rebar3, I knew it
didn't have to be that way.
Replacing run/4 with run/7
To further my quest, Tristan pointed me to run/7, specifically its use of
[check_last_mod]. Before I forked lfe-rebar3/compile, it was using
run/4, which does NOT make use of [check_last_mod], hence the
unnecessary recompilation.
lfe-rebar3/compile/src/lr3_comp.erl:74
rebar_base_compiler:run(Opts, [], Files, DoCompile).
After some experimentation, and _checkouts symlinking tricks, I came up with an
appropriate run/7 incantation and made a pull request.
quasiquoting/lfe-compile/src/lr3_comp.erl:37-39
rebar_base_compiler:run(Config, FirstFiles, SourceDir, ".lfe", TargetDir, ".beam", fun compile/3).
With those changes, rebar3 lfe compile will now skip unmodified .lfe
files. Not only is this The Right Thing™ to do, but it should be time saver in
the long run.
Examples of time saving
Here's an example of the difference when compiling Lodox…
… using run/4 via 0.2.1:
$ time rebar3 lfe compile
 ~~>    Compiling ./src/lodox-html-writer.lfe ...
 ~~>    Compiling ./src/lodox-p.lfe ...
 ~~>    Compiling ./src/lodox-parse.lfe ...
 ~~>    Compiling ./src/lodox-util.lfe ...
 ~~>    Compiling ./src/lodox.lfe ...
 ~~>    Compiling ./src/pandoc.lfe ...
 ~~>    Compiling ./test/unit-lodox-tests.lfe ...
        1.39 real         1.14 user         0.24 sys
… using run/7 via 0.3.0:
$ time rebar3 lfe compile
        0.94 real         0.73 user         0.20 sys
A little more 🐄💩 microbenchmarking on a proprietary work project:
# run/4 3.58 real 3.02 user 0.58 sys
# run/7 1.83 real 1.46 user 0.35 sys