美文网首页
erlang.mk浅析

erlang.mk浅析

作者: 竹羔 | 来源:发表于2018-05-09 15:00 被阅读575次

    背景:

    在学习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构建release源码.png erlang.mk源码对于rel-deps的实现.png relx描述.png erlang.mk对erl进行编译的源码.png
    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导入依赖的源码2.png
    erlang.mk导入依赖的源码3.png
    依赖树的前序遍历来解决冲突.png

    PS:

    • 附上erlang.mk 编译运行example后的内容。
    image.png
    image.png
    image.png
    image.png
    自己手动执行release的效果是和run的效果等同.png
    • 附上relx构建release的过程:
    relx构建release的入口.png
    先将各app放入lib文件夹下.png
    根据生成rel.png
    ec_file:write_term(ReleaseFile,Meta).png 根据rel去生成script和boot.png rel文件内容信息的由来1.png
    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浅析

          本文链接:https://www.haomeiwen.com/subject/ukqjqxtx.html