📜 ⬆️ ⬇️

Parallel generation of plt files for Dialyzer (with depes and buns)

Anyone who has ever used dialyzer for their applications knows that he should first prepare plt files for the main applications from the erlang delivery itself.

The generation goes on loading only one core and for quite a long time, in connection with which there was a great desire to launch the generation in parallel.

Update: added a patch (and sent a pull request, of course) to the dialyzer which adds a merge feature of several plt to one big-and-thick.

So, to assemble one large plt containing everything you need, you first need to patch and rebuild the dialyzer.
The patch can be taken here: github.com/datacompboy/otp/commit/bb5f53ed3e7bd28632fcf3d4a797d64c0e00f2c3
Since I'm lazy, I did not do a complete reassembly of everything-and-all, I just reassembled the one that already lies in the system:
mkdir dialyzer cd dialyzer cp -a /usr/lib/erlang/lib/dialyzer-2.4.3/* . wget https://github.com/datacompboy/otp/commit/bb5f53ed3e7bd28632fcf3d4a797d64c0e00f2c3.patch patch -p3 < bb5f53ed3e7bd28632fcf3d4a797d64c0e00f2c3.patch echo '-define(VSN,"v2.4.3").' >> src/dialyzer.hrl echo "{erl_opts, [debug_info]}." >> rebar.config rebar compile && sudo cp ebin/dialyzer_* /usr/lib/erlang/lib/dialyzer-2.4.3/ebin/ 

')
And now let's move on to the multithreaded creation of plt files.

We create a separate daddy (I have ~/work/erlang/plt ), inside we create the otp folder and the Makefile file with the contents (indents - tab!):

 OTP_LIB=/usr/lib/erlang/lib APPS=$(shell perl -e "\$$a='$(patsubst -1%,,$(patsubst $(OTP_LIB)/%/ebin,%,$(wildcard $(OTP_LIB)/*/ebin)))';\$$a=~s!-[0-9.]+!!g;print \$$a;") RELS=$(patsubst %,otp/%.plt,$(APPS)) all: all.plt all.plt: $(RELS) dialyzer --merge_plts --output_plt $@ --plts $^ -include $(RELS:.plt=.deps) IGNOREotp/%.plt: if [ -e $@ ]; then dialyzer --check_plt --plt $@ --output_plt $@ || rm $@; fi if [ ! -e $@ ]; then dialyzer --build_plt --output_plt $@ --apps $(patsubst otp/%.plt,%,$@); fi otp/%.plt: dialyzer --build_plt --output_plt $@ --apps $(patsubst otp/%.plt,%,$@) otp/%.deps: otp/%.plt dialyzer --plt_info --plt $< | (echo -n "$e:"; perl -ne 'print " $$1" if /^[[ ]"([^"]+)"/') > $@ 


Then we run
 make -j 8 
and observe the generation of one process per app, 8 in parallel.

In the final, we get in the otp / plt files one by one application from the otp delivery, and the file all.plt containing the total plt from all-and-all.

If you suddenly change something (for example, update erlang in the system) - just run make again and only the changed applications will be reassembled.

If the word IGNORE is transferred from the first case to the second, instead of regenerating the entire application, each time, --check will be called for this plt, which will update only the changed beam files, but if new files appeared in the application - they will not be automatically processed so I left this regeneration scheme off.
However, from here it is quite possible to pull useful features to your project for the regeneration of plt files to your application.

Source: https://habr.com/ru/post/124271/


All Articles