MeteorCat / Erlang开发|打包|部署

Created Sun, 14 Jul 2024 11:12:59 +0800 Modified Wed, 29 Oct 2025 23:24:53 +0800
1443 Words

Erlang开发|打包|部署

对于 Erlang 开发环境早期都是采用以下进行编译部署:

裸写启动程序

早期直接 shell 脚本启动就行, 简单暴力没什么需要说的, 只能适合简单初级的项目

# 直接命令行唤起 erlang 调用文件
# 设置模块搜索目录(-pa), 设置启动和退出回调(-s 初始化回调 退出回调 ), 同时不需要直接启动 shell 
erl -pa /data/game/prod -pa /data/game -eval app:main(). -s init stop -noshell

EMakefile编译

这是 erlang 内置的类似于 Makefile 编译部件, 执行命令:

# 搜索项目目录下的 Emakefile 文件并且执行编译打包
erl -make

项目打包资源 Emakefile 文件内容如下:

{
	["src/*"],
	[{outdir, "./_build/dev/beam"}, {i, "include"}]
}.
{
	["src/utils/*"],
	[{outdir, "./_build/dev/beam"}, {i, "include"}]
}.
{
	["src/lib/*"],
	[{outdir, "./_build/dev/beam"}, {i, "include"}]
}.
{
	["src/mod/*"],
	[{outdir, "./_build/dev/beam"}, {i, "include"}]
}.
{
	["src/sys/*"],
	[{outdir, "./_build/dev/beam"}, {i, "include"}]
}.

这里简单说下配置说明:

% 编译项目块采用 `{Module,Options}.` 单个配置项, 如果多模块需要追加配置
% 这里采用多个配置项, `["src/*"]` 代表源代码导入目录, 也就是需要打包的源代码
% 注意配置第一个目录不会递归到子目录下面编译, 所以需要手动进行子目录打包引入
% 
% 之后第二个配置项 `[{outdir, "./_build/dev/beam"}, {i, "include"}]`
% 这里其实就是 erlang 自己内部配置项目:
%   `outdir` 就是打包之后导出的目录
%   `i` 就是检索项目的头文件目录
{
	["src/*"],
	[{outdir, "./_build/dev/beam"}, {i, "include"}]
}.

具体配置 官方打包配置

注意: 这里的输出目录 必须手动创建好 才会开始编译进去, 如果不存在运行 erl -make 会直接报错:

# beam 没有创建的时候编译错误
./_build/dev/beam: error writing file: no such file or directory

如果你的项目 不依赖第三方库, 那么直接采用 Emakefile 是最高效的打包方式, 可以避免陷入复杂项目依赖.

太过复杂的项目包管理反而在初期就被难住, 我们需要做得是erlang开发功能而不要浪费时间在编译管理上

这里假定已经打包好了, 那么启动只需要 ‘*.beam’ 的目录:

# -s 启动模块 启动名
# -pa 为模块路径
erl -pa ./_build/dev/beam -s init stop -noshell

rebar编译

Emakefile 虽然已经满足打包开发要求, 但是现代的打包需要依赖代码仓库下载/测试单元等, 其中最具有代表性的就是 Golang 的模块打包.

所以第三方出了 rebar 打包工具, 这里分 rebar2rebar3 版本, 两者编译命令是不同的(需要注意).

官方手册网站

这个包管理器虽然第三方但是官方目前对其支持挺多的, 但是配置实际上挺麻烦( 实际上我也太想用, 但是支持远程包管理确实太方便了 ), 这里区别 windowlinux 区别.

注意: 必须优先安装配置好 erlang 二进制, 因为本质是 Erlang 安装目录的 bin/escript 调用 rebar3

这里先处理 linux/mac 环境搭建:

# 进入自己二进制的配置目录
cd /data/current

# 下载亚马逊官方提供的下载包
curl -O https://s3.amazonaws.com/rebar3/rebar3

# 追加 rebar3 执行权限
chmod +x rebar3 

# 配置执行目录
export PATH=$PATH:/data/current

# 查看版本
rebar3 --version
# rebar 3.23.0 on Erlang/OTP 27 Erts 15.0

window 就则比较麻烦点, 下载 rebar 文件需要放入 Erlang 当中并在 bin 目录追加脚本:

:: Window启动脚本: bin/rebar3.cmd
@echo off
setlocal
set rebarscript=%~f0
escript.exe "%rebarscript:.cmd=%" %*

另外还需要主要 Rebar3 版本对应不同 Erlang 版本支持, 所以需要查看官方 changelog 确定支持

这里以 rebar3 做基础版本, 内部其实集成很多命令:

# 这里能看到多数的执行命令
rebar3 new
# 以下是初始化项目命令
# app: 创建出 `behaviour(application)` 启动模板模板, 会配置启动应用入口
# cmake: 创建出 C/C++ 交互的项目模板, 原生代码在 c_src 目录内编写 
# escript: 创建带 escript 脚本功能模板, 这脚本就是直接调用 bin/escript 脚本命令
# lib: 编写 OTP 库文件模板, 不含应用启动
# plugin: 创建 Rebar3 插件项目模板
# release: 创建多应用的 OTP 模板, 和单应用 app 区别是这个是多 apps 多项目入口启动
# umbrella: 这里和 release 差不多, 约等于别名


# 如果构建游戏服务一般都是直接单应用启动, 这个是很常用的指令
rebar3 new app game

另外 rebar3 可以在根目录进行配置( ./rebar3.config ):

%% Rebar 打包信息
{escript_name, rebar3}.
{mininum_otp_vsn, "27.0"}. % OTP最低版本
{root_dir, "."}. % 项目根目录
{base_dir, "_build"}. % 打包目录
{deps_dir, "lib"}. % 依赖库目录
{project_app_dirs, ["apps/*", "lib/*", "."]}. % 扫描的OTP引用目录
{src_dirs, ["src"]}. % OTP应用源码目录
{extra_src_dirs, []}. % 需要排除的源码目录
{erl_opts, [debug_info]}. %% Erlang的编译配置

%$ 引入第三方包, 支持大量 github 工程打包引入
{deps, []}.


% 调用 shell 指令的参数
{shell, [
  % {sys_config, "./config/sys.config"},
  % {vm_args, "./config/vm.args"},
  {apps, [game]}
]}.

Rebar3 编译参数比较复杂, 常见 OTP 模板工具使用 Emakefile 就足够了.

而且目前来说开源 Erlang 实际上不如单独自己编写工具类好用.