<div dir="ltr">I once wrote a custom erlc frontend for couchdb to see if I could speed up our compilation process. It made a bit of a difference but on a decent machine with -J the improvement wasn't enough to justify adding the complexity.<div>

<br></div><div style>Script is here:</div><div style><br></div><div style><a href="https://github.com/davisp/couchdb/blob/couch_erlc/bin/couch_erlc">https://github.com/davisp/couchdb/blob/couch_erlc/bin/couch_erlc</a><br>

</div><div style><br></div><div style>It was working well enough for me to run tests but I didn't spend much time testing it for general bugs and what not.</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">

On Thu, Jan 24, 2013 at 8:51 AM, Tim Watson <span dir="ltr"><<a href="mailto:watson.timothy@gmail.com" target="_blank">watson.timothy@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Take a look at the Rabbit Makefile - it doesn't recompile all the time *and* it works with -J and is generally really fast.<br>
<br>
<a href="http://hg.rabbitmq.com/rabbitmq-server/file/default/" target="_blank">http://hg.rabbitmq.com/rabbitmq-server/file/default/</a><br>
<br>
Cheers,<br>
Tim<br>
<div class="HOEnZb"><div class="h5"><br>
On 24 Jan 2013, at 14:48, Loïc Hoguin wrote:<br>
<br>
> On 01/24/2013 01:49 PM, Matthias Lang wrote:<br>
>> Hi,<br>
>><br>
>> I'm looking for tips and tricks to use speed up compiling a bunch of<br>
>> Erlang modules from within a build system that uses (gnu)Make.<br>
>><br>
>> The system uses Erlang, but most of it is actually C code, which is compiled<br>
>> under four different compilers, plus FPGA code. So ditching 'make'<br>
>> for something Erlang-centric like 'rebar' doesn't look very attractive.<br>
>><br>
>> Background<br>
>> ----------<br>
>><br>
>> Doing this on R14B03:<br>
>><br>
>>   erlc a.erl<br>
>>   erlc b.erl<br>
>>   erlc c.erl<br>
>>   ...<br>
>><br>
>> for 70 modules on my machine takes 39s. If I do this instead:<br>
>><br>
>>   erlc a.erl b.erl c.erl ...<br>
>><br>
>> it improves to 7s. If I split the job in two parts which run at the<br>
>> same time, it improves again to 4s wall time, with both cores<br>
>> busy.<br>
>><br>
>> So, a 10x improvement in compilation speed seems attainable, but how do<br>
>> I explain how to do it to 'make'?<br>
>><br>
>><br>
>> Ideas<br>
>> -----<br>
>><br>
>> I had a few simple ideas for fixing this, but none really work. See below.<br>
>><br>
>> The more complicated idea I have is to make a shell script replacement<br>
>> for 'erlc' which delegates the compilation work to an Erlang node<br>
>> which is already running. Seems workable, and it won't spring<br>
>> surprises on 'make', e.g. -j 4 will still do the right thing.<br>
>><br>
>> Anyone got a neat idea?<br>
>><br>
>> Rest of this mail is just a list of things that don't seem to work.<br>
>><br>
>> Matt<br>
>><br>
>> ======================================================================<br>
>><br>
>><br>
>> Bad Idea #1: straightforward 'make'<br>
>> -----------<br>
>><br>
>> Here's my minimal starting point for a system of three modules, a b c:<br>
>><br>
>>    beams=(addsuffix .beam, a b c)<br>
>>    %.beam: %.erl nasty_global_stuff.hrl<br>
>>         erlc $<<br>
>><br>
>> That causes 'make' to hand one module to erlc at a time, which is slow.<br>
>><br>
>><br>
>> Bad Idea #2: try and use just one rule for all .beams<br>
>> -----------<br>
>><br>
>> Like this:<br>
>><br>
>>   modules=a b c<br>
>>   beams=$(addsuffix .beam, $(modules))<br>
>>   erls=$(addsuffix .erl, $(modules))<br>
>>   all: $(beams)<br>
>><br>
>>   $(beams): $(erls) nasty_global_stuff.hrl<br>
>>         erlc $(filter %.erl, $@)<br>
>><br>
>> That does almost the right thing, but actually not at all. Change one<br>
>> .erl and it'll recompile every .beam, because I've told 'make' that<br>
>> each .beam depends on all .erl files.<br>
>><br>
>><br>
>> Bad Idea #3: use erl -make for all Erlang compilations<br>
>> -----------<br>
>><br>
>>   all:<br>
>>      erl -make<br>
>><br>
>> That sort-of works, but it only runs one process (Erlang's own 'make'<br>
>> doesn't seem to attempt running more than one compilation at a time),<br>
>> passing options is not straightforward (they're not even syntactically<br>
>> the same as for erlc) and it requires writing 'EMakefiles', so you<br>
>> sort-of have to understand Erlang in order to be able to fiddle with<br>
>> the build system.<br>
>><br>
>> It's also fiddly explaining dependencies between Erlang stuff and<br>
>> other stuff to a combination of ordinary 'make' and erlang's own make.<br>
>><br>
>> --end of bad ideas---<br>
><br>
> When removing rebar dependency in the Cowboy makefile to improve my workflow, I ran into the same issues you did. The normal way of doing things with make is too damn slow. I'm assuming here that each erlc call starts an Erlang VM, which isn't made to be fast.<br>


><br>
> I settled for this:<br>
>  <a href="https://github.com/extend/cowboy/blob/master/Makefile#L33" target="_blank">https://github.com/extend/cowboy/blob/master/Makefile#L33</a><br>
><br>
> This recompiles everything all the time, but that's not really an issue for me. I might steal your bad idea #2 to avoid recompiling deps all the time though.<br>
><br>
> --<br>
> Loïc Hoguin<br>
> Erlang Cowboy<br>
> Nine Nines<br>
> <a href="http://ninenines.eu" target="_blank">http://ninenines.eu</a><br>
> _______________________________________________<br>
> erlang-questions mailing list<br>
> <a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
> <a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</div></div></blockquote></div><br></div>