背景:
在学习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的源码如图所示。
运行make run的作用.png
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生成app元数据.png
erlang.mk github上对这部分有进行分离出来。除了表明erlang.mk是如何编译erl文件的同时,该文件上面部分也展示了如何导入依赖问题和解决依赖冲突问题。
https://github.com/ninenines/erlang.mk/blob/master/core/erlc.mk
erlang.mk导入依赖的源码2.png
erlang.mk导入依赖的源码3.png
依赖树的前序遍历来解决冲突.png
PS:
- 附上erlang.mk 编译运行example后的内容。
image.png
image.png
image.png
自己手动执行release的效果是和run的效果等同.png
- 附上relx构建release的过程:
先将各app放入lib文件夹下.png
根据生成rel.png
ec_file:write_term(ReleaseFile,Meta).png 根据rel去生成script和boot.png rel文件内容信息的由来1.png
rel文件内容信息的由来2.png
传统方法构建release流程:
- 确定需要包含的application,将其放入lib。
- 编写rel文件(内容包括镜像名称,erts版本以及release中所有应用名称和版本)
- 将所有准备纳入release的application加入代码路径,使用systools去生成script和boot。
- 编写sys.config(可选,比如里面可以声明sasl日志的输出位置)。
- 这时候就可以使用该release了,只是需要在启动时指定boot和sys.conf
erlang.mk和relx构建release流程:
- erl->beam (编译,依赖导入,依赖冲突处理),这部分是erlang.mk去处理,它将依赖下载后放入deps文件夹,并编译src的代码,生成app,一并放入ebin
- erlang.mk把构建release工作委托给relx。
- relx只要有beam和relx.conf就可以去构建release。
a. 把各app放入lib。
b. 产生rel文件。
c. 通过rel来使用systools去生成script和boot。bin/安装脚本。bin/启动脚本
网友评论