Erlang 使用escript打包多个模块构建一个可执行文件
概念
主模块:作为二进程程序(打包后的文件)的入口模块,需要定义main/1 函数并导出
打包函数(逻辑):示例代码中的hello:build/0
非rebar3 方式打包,直接源码操作。
简单说明
把 a.erl/b.erl 模块打包成一个 可执行文件a或b (只能是打包模块中的文件名)。
在linux可直接执行得到的二进制文件。
在windows下需要使用 escript a 执行 或者 使用bat脚本二次封装。
原理
利用escript提供的功能来完成,具体可看官方文档
主要是escript:create/2 函数。
注意事项
- 如果打包的模块在打包执行环境中没有beam文件,那就可以用代码编译,再获取beam code
- 如果打包的模块在打包执行环境中有beam文件,且能成功加载,可使用
code:get_object_code来获取
打包函数可以单独放一个escript脚本,也可以放在打包模块中去,特殊处理一下入口即可。
escript:create(Name)
Name是执行文件的主模块,需要有main函数,如果Name是字符串,则直接创建文件。
举例说明一下,比如Name是"hello",那么会生成 一个"hello"文件,并且打包的文件中要有hello模块,且有hello:main/1,导出。
其他方式
可使用rebar3 来构建可执行程序。
代码示例
escript 或 erl 脚本
hello.escript/hello.erl 都可以
-doc"""
构建一个可执行文件 直接执行
""".
-module(hello).
-mode(compile).
-export([main/1]).
main(_) ->
build().
build() ->
io:format("=======================================================~n"),
io:format("开始打包...~n"),
Self = escript:script_name(),
Name = ?MODULE_STRING,
F = fun
(?MODULE, Acc) ->
%% escript 脚本作为主模块,需要通过手动编译的方式拿到object code
{ok, _, CodeBin} = compile:file(Self, [binary]),
FileName = ?MODULE_STRING ++ ".beam",
io:format("pack ~p~n", [FileName]),
[{FileName, CodeBin} | Acc];
(Module, Acc) ->
{_, CodeBin, FileName} = code:get_object_code(Module),
io:format("pack ~p~n", [FileName]),
[{filename:basename(FileName), CodeBin} | Acc]
end,
Files = lists:foldl(F, [], [?MODULE, module_a,module_b]),
R = escript:create(Name, [
shebang,
{archive, Files, []}
]),
case R of
ok ->
{ok, CWD} = file:get_cwd(),
io:format("[OO] 打包完成:~p ~n", [filename:join([CWD, Name])]),
ok;
Error ->
io:format("[XX] 打包失败:~p ~n", [Error]),
Error
end,
ok.
浙公网安备 33010602011771号