erlang.mk浅析

背景:

在学习ranch的时候,肯定是先去跑下官方给的demo了。跟着官方给的指示,在centos上只需要make run即可将这个demo运行起来。而我去看该demo的makefile文件,只是简短的几行,除了项目名和依赖外,就是他有include一个erlang.mk的东西。


makefile内容.png

而erlang.mk这个文件有200k的大小,也是和ranch同一个团队做出来的一个构建工具。
我一开始只是想要在不依赖这个构建工具的情况下去导入ranch依赖并且将自己写的ranch demo跑起来,但是遇到了一个ranch前置依赖ssl没有start的问题,在请教思强之后,我知道了原来是要将这些erlang内置的application都start起来,然后再start ranch,再start自己的ranch demo。就此,也是将自己项目在不使用erlang.mk的情况下跑起来了。

问题:

当然也是有一个问题,为什么erlang.mk 可以直接make run就可以将系统跑起来,还不需要将ranch的依赖启动,再启动ranch,再启动自己的项目,erlang.mk是做了哪些操作才让项目的运行如此方便的呢?(其实是思强的疑问,然后引导我去做的。)抱着这个疑问,我阅读了相关资料,如传统方式去构建发布安装release,erlang.mk官方文档,erlang.mk源码。

解决:

首先从官网文档上有这样的描述:erlang.mk在你执行make run时会编译项目和构建一个release,然后再去启动已发布的release。而其中的启动release是对应Exec:xxxxx这行,并且erlang.mk对于启动release的源码如图所示。


erlang.mk浅析_第1张图片
运行make run的作用.png

erlang.mk浅析_第2张图片
erlang.mk对于启动release的源码.png

这时候我们知道他之所以不需要自己去手动一个一个start application是因为在run的时候是直接启动一个已发布的release。那么以erlang/otp提供给我们的方式去构建运行一个release的情况是怎么实现的呢?这部分内容在erlang man上可以看到 http://erlang.org/doc/man/rel.html
但是官网man上对其的描述很少,我也有去参考了一些erlang的书籍,可得到结论如下:release的rel文件和script文件描述了系统的启动过程,其中script文件内包含一个完整的规范,所有应用的内容明细都全部罗列在内,包括应用的路径,需要加载的模块以及其他各种必要的信息。而boot文件是script文件的二进制形式。可供erts在启动时直接读取。这就是为什么直接make run(即直接启动一个release)可以将项目跑起来而不需要一个一个的去start application的原因。

PS:在otp design_principles上面有对其release详细的内容。http://erlang.org/doc/design_principles/release_structure.html

而在erlang.mk文档中可知,erlang.mk对于构建release的工作不是在erlang.mk实现的,而是去委托给relx去做这个构建工作。
https://github.com/erlware/relx

erlang.mk浅析_第3张图片
erlang.mk构建release源码.png
erlang.mk浅析_第4张图片
erlang.mk源码对于rel-deps的实现.png
erlang.mk浅析_第5张图片
relx描述.png
erlang.mk浅析_第6张图片
erlang.mk对erl进行编译的源码.png

erlang.mk浅析_第7张图片
erlang.mk生成app元数据.png

erlang.mk github上对这部分有进行分离出来。除了表明erlang.mk是如何编译erl文件的同时,该文件上面部分也展示了如何导入依赖问题和解决依赖冲突问题。
https://github.com/ninenines/erlang.mk/blob/master/core/erlc.mk

erlang.mk导入依赖的源码1.png

erlang.mk浅析_第8张图片
erlang.mk导入依赖的源码2.png

erlang.mk浅析_第9张图片
erlang.mk导入依赖的源码3.png

erlang.mk浅析_第10张图片
依赖树的前序遍历来解决冲突.png

PS:

  • 附上erlang.mk 编译运行example后的内容。
erlang.mk浅析_第11张图片
image.png

erlang.mk浅析_第12张图片
image.png

erlang.mk浅析_第13张图片
image.png

erlang.mk浅析_第14张图片
image.png

erlang.mk浅析_第15张图片
自己手动执行release的效果是和run的效果等同.png
  • 附上relx构建release的过程:
erlang.mk浅析_第16张图片
relx构建release的入口.png

erlang.mk浅析_第17张图片
先将各app放入lib文件夹下.png

erlang.mk浅析_第18张图片
根据生成rel.png

erlang.mk浅析_第19张图片
ec_file:write_term(ReleaseFile,Meta).png
erlang.mk浅析_第20张图片
根据rel去生成script和boot.png
erlang.mk浅析_第21张图片
rel文件内容信息的由来1.png

erlang.mk浅析_第22张图片
rel文件内容信息的由来2.png

传统方法构建release流程:

  1. 确定需要包含的application,将其放入lib。
  2. 编写rel文件(内容包括镜像名称,erts版本以及release中所有应用名称和版本)
  3. 将所有准备纳入release的application加入代码路径,使用systools去生成script和boot。
  4. 编写sys.config(可选,比如里面可以声明sasl日志的输出位置)。
  5. 这时候就可以使用该release了,只是需要在启动时指定boot和sys.conf

erlang.mk和relx构建release流程:

  1. erl->beam (编译,依赖导入,依赖冲突处理),这部分是erlang.mk去处理,它将依赖下载后放入deps文件夹,并编译src的代码,生成app,一并放入ebin
  2. erlang.mk把构建release工作委托给relx。
  3. relx只要有beam和relx.conf就可以去构建release。
    a. 把各app放入lib。
    b. 产生rel文件。
    c. 通过rel来使用systools去生成script和boot。bin/安装脚本。bin/启动脚本

你可能感兴趣的:(erlang.mk浅析)