在编写 Erlang 代码之前,必须先安装 Erlang,因此本章介绍的第一个也是最简单的步骤是,了解在大多数主流平台上安装 Erlang/OTP 的基本步骤。这些说明旨在为大多数平台提供基本的设置,但您会发现,真实的 Erlang 开发很少仅仅依靠这些基本说明。
事实上,随着团队的壮大和项目的积累,并非所有服务、库或代码片段都支持完全相同的 Erlang 版本,并且不会同时升级。如果您与专业使用 Erlang 的开发人员交谈,大多数人(Windows 用户除外)会告诉您,他们只是使用自己需要的选项编译自己的副本,并使用允许他们在多个版本之间切换的工具。所以我们将逐步介绍这个过程。
您还将了解如何安装 Rebar3(Erlang 社区的官方构建工具)以及各种文本编辑器的基本配置。在后面的章节中,我们还将讨论其他不特定于 Erlang 的工具,例如 Kubernetes 或 Prometheus,但现在让我们先从 Erlang 开始。
安装 Erlang/OTP
第一步是在系统中安装合适的 Erlang/OTP。这在所有平台上的体验并不统一,但至少我们会确保遵循这些步骤的每个人都可以在任何工作环境中拥有一个完全正常运行的设置。
选择版本
Erlang/OTP 按照相当稳定且可预测的计划发布,并且对向后不兼容的更改有明确的标准。
Erlang 版本根据<主版本>.<次版本>.<修订版本>
方案进行编号,如 Erlang/OTP 系统原则 中所述。在某些罕见情况下,会添加其他数字作为“分支”版本,您可能无需关心这些版本。
以下是一些可能的版本示例
- 22.0
- 22.0-rc3
- 21.3
- 21.2.3
- 21.1
- 19.3
- 17.0
- R16B03(这是一种遗留版本格式,自 2014 年以来未再使用)
如您所见,当不需要修订版本时,不会提及修订版本
。Erlang 的发布计划大致如下
- 每年大约 2 月或 3 月,都会发布下一个主版本的候选版本(后缀为
-rc1
或-rc2
)。此候选版本可供希望从源代码构建的用户使用,以便测试其应用程序和系统是否能够很好地与之配合使用。 - 几个月后(4 月至 6 月),主版本会被发布并公开。主版本包含需要较大虚拟机更改的大型新功能,并且也允许引入向后不兼容的更改。
- 每三个或四个月发布一次次版本,通常包括各个库的稳定性修复和次要功能添加。
- 如果在某些情况下发现了严重错误(出于安全或稳定性原因),则可能会发布修订版本。
信息
向后不兼容的更改通常会在被移除之前经历一个弃用周期,这往往会留出充足的时间进行调整。该策略在爱立信 OTP 团队发布的 支持、兼容性、弃用和移除 文档中进行了描述。
在某些罕见情况下,会发生强制弃用(大多是意外),社区可能需要几周时间才能找到解决方法。
因此,采用 Erlang 的团队可能希望采用适合主版本的维护计划,以避免落后太多。虽然偶尔升级也是可能的,但您会发现,经常进行少量维护通常比一次性进行大量维护更容易。
请注意,修订版本通常仅在 邮件列表 上发布并在 GitHub 上的主 Git 存储库 中进行标记,否则不会在主网站上打包。
Windows
如果您是 Windows 用户,建议您在进行任何 Erlang 开发时都使用 Windows 10。较早的版本也可以工作,但例如,Rebar3 等社区工具仅在 Windows 10 上进行了测试。
从源代码构建 Windows 版本一直以来都非常困难,因此建议您坚持使用预构建的副本。
如果您是 Chocolatey 的用户,您可以获取 Erlang 软件包,并根据需要安装它们,例如使用以下命令
choco install erlang # for the latest
choco install erlang --version 21.2 -m # allow many versions
choco install erlang --version 20.1 -m # and one more versions
这会将您想要的版本添加到您的PATH
环境变量中,然后您需要以正确的顺序维护这些版本。
如果没有 Chocolatey,请使用 www.erlang.org/downloads 上分发的二进制文件,或者使用 Erlang Solutions Ltd. 构建的二进制文件。
这些版本的安装程序附带一个向导,将引导您完成所有必要的步骤。
不要忘记将 Erlang/OTP 添加到您的PATH
环境变量中,以包含您的 Erlang/OTP 安装,因为这将允许您从命令行调用它。
- 在开始菜单中,搜索“系统环境变量”,然后选择“编辑系统环境变量(控制面板)”选项。
- 在刚刚打开的“系统属性”窗口底部,按“环境变量…”按钮。
- 选择
Path
变量(如果不存在则创建它),然后单击“编辑”按钮。 - 添加一个与安装路径匹配的 Erlang/OTP 条目,通常类似于
C:\Program Files\erl10.2\bin
。列表中较早的条目将首先加载。 - 保存选项。
- 关闭并重新启动您正在运行的任何终端。
如果您长期进行开发,则可以通过这种方式安装多个版本。您可以通过更改和修改PATH
变量中路径的优先级来控制使用哪个版本。
如果您在 Windows 开发方面是纯粹主义者,那么您可能对 Visual Studio 等环境非常满意,在这些环境中,几乎所有操作都可以在 IDE 内完成。Erlang 来自不同的环境,本书中使用的许多说明都侧重于使用命令行构建所有内容。
如果您正在寻找一个在 Windows 上运行命令行的终端,有多种选择可用
- 使用 PowerShell 作为终端。本书中的大多数命令都应该可以很好地与之配合使用,但可能存在一些极端情况。
- 下载并安装 适用于 Windows 的 git,它将带有一个
git-bash
shell,该 shell 将与本书中的所有工具和大多数命令配合良好。 - 尝试使用 ConEmu 作为更友好的终端模拟器。
- 使用 Cmder,它是一个 Windows 控制台模拟器,可以很好地打包上述大多数选项。
- 自行承担风险使用 Cygwin;您需要从源代码重新构建软件才能使其正常工作,并且像 Rebar3 这样的工具会动态地确定它们在 Windows 上,这在历史上导致了一些与 Cygwin 交互时的路径问题。
然后,您可以使用您选择的编辑器或 IDE 来处理 Erlang 组件。
OSX
虽然 OSX 可以使用 Homebrew 或 Erlang Solutions Ltd. 软件包 来安装预构建版本的 Erlang/OTP,但您只应在第一次尝试时这样做。如果您计划长期进行实际开发,则需要能够同时处理多个版本。
最常用的支持工具是 kerl。Kerl 是一个围绕下载、编译和加载单个系统上的各种 Erlang/OTP 版本的包装器,它将抽象化大多数烦人的操作。
您可以通过调用$ brew install kerl
从 homebrew 安装 Kerl,或者按照其 README 文件 中的说明进行操作。
在安装 Erlang 之前,我们需要安装和更新一些依赖项,主要的是确保您已安装 XCode,然后安装 OpenSSL(因为 OSX 默认情况下包含过时的 SSL 副本)。
$ brew install openssl
...
$ ls /usr/local/Cellar/openssl/
1.0.2q
请注意这为您提供的本地 openssl 安装的完整路径,此处为/usr/local/Cellar/openssl/1.0.2q/
。
您可以在环境中设置以下选项
SSL_PATH=/usr/local/Cellar/openssl/1.0.2q/
export KERL_BUILD_BACKEND="git"
export KERL_CONFIGURE_OPTIONS="--without-javac \
--with-dynamic-trace=dtrace \
--with-ssl=${SSL_PATH}"
并确保它处于活动状态(例如,调用source ~/.bashrc
)。这些选项指定构建工具接受或期望的内容。此处的选项禁用 Java 绑定,并使用我们新安装的 SSL。您可以查看 构建说明 以获取更多配置选项。
如果您想添加更多内容,例如Wx
(允许您使用和构建 GUI),则 OSX 的构建说明 包含更多详细信息以指导您。
从那时起,您可以下载并安装您自己的 Erlang/OTP 版本。
$ kerl update releases
...
# kerl build <release> <build name>
$ kerl build 21.3 21.3
...
# kerl install <build name> <target path>
$ kerl install 21.3 ~/bin/erls/21.3/
...
# make that version active
$ . ~/bin/erls/21.3/activate
# or alternatively
$ source ~/bin/erls/21.3/activate
然后可以根据需要激活任何已安装的版本。如果您想设置默认版本,可以将激活命令放在您的.bashrc
配置文件(或您可能拥有的任何 shell 配置文件)中。
如果您计划在开发机器上同时使用 Erlang 和 Elixir,您可能需要查看 asdf
。它是一个基于插件的多种编程语言安装程序,可以同时处理 Elixir 和 Erlang。您可能需要安装autoconf
软件包才能使其工作。
要将其与 Erlang 一起使用,请通过调用asdf plugin-add erlang https://github.com/asdf-vm/asdf-erlang.git
安装 Erlang 插件。此插件包装了kerl
并重用了其所有选项,但将构建转移到asdf
的控制下。因此,之前的配置说明保持不变。您只需要更改以下调用的顺序
# asdf install erlang <version>
$ asdf install erlang 21.3
...
# asdf global <name> <version> [<version>...]
# asdf local <name> <version> [<version>...]
# export ASDF_ERLANG_VERSION=<version>
从那里开始,kerl
和asdf
之间的主要区别在于,kerl
将使用环境变量来了解要运行哪个版本,而asdf
将可选地使用.tool-versions
文件来按目录触发更改。
Linux
Linux 发行版几乎都具有允许您安装 Erlang 预构建副本的包管理器,或者您仍然可以使用 Erlang Solutions Ltd. 软件包。不过,就像 OSX 一样,您只应在第一次尝试时这样做。如果您计划长期进行实际开发,则需要能够同时处理多个版本。
最常用的支持工具是 kerl。Kerl 是一个围绕下载、编译和加载单个系统上的各种 Erlang/OTP 版本的包装器,它将抽象化大多数烦人的操作。
您可以通过调用以下命令安装 kerl:
$ curl -O https://raw.githubusercontent.com/kerl/kerl/master/kerl
$ chmod a+x kerl
然后将 kerl 移动到您的路径中。Kerl 会自动检查并警告您在构建库时可能需要的缺失依赖项,因此您可以继续运行以下命令,并在操作过程中注意其指示。
首先,您可以在环境中设置以下选项
export KERL_BUILD_BACKEND="git"
export KERL_CONFIGURE_OPTIONS="--without-javac \
--with-dynamic-trace=systemtap"
并确保它处于活动状态(例如,调用source ~/.bashrc
)。这些选项指定构建工具接受或期望的内容。此处的选项禁用 Java 绑定,但无论如何它们都会被自动跳过。您可以查看 构建说明 以获取更多配置选项。
如果您想添加更多内容,例如Wx
(允许您使用和构建 GUI),则 Wx 的构建说明 包含更多详细信息以指导您。
从那时起,您可以下载并安装您自己的 Erlang/OTP 版本。
$ kerl update releases
...
# kerl build <release> <build name>
$ kerl build 21.3 21.3
...
# kerl install <build name> <target path>
$ kerl install 21.3 ~/bin/erls/21.3/
...
# make that version active
$ . ~/bin/erls/21.3/activate
# or alternatively
$ source ~/bin/erls/21.3/activate
然后可以根据需要激活任何已安装的版本。如果您想设置默认版本,可以将激活命令放在您的.bashrc
配置文件(或您可能拥有的任何 shell 配置文件)中。
如果您计划在开发机器上同时使用 Erlang 和 Elixir,您可能需要查看 asdf
。它是一个基于插件的多种编程语言安装程序,可以同时处理 Elixir 和 Erlang。您可能需要安装autoconf
软件包才能使其工作。
要将其与 Erlang 一起使用,请通过调用asdf plugin-add erlang https://github.com/asdf-vm/asdf-erlang.git
安装 Erlang 插件。此插件包装了kerl
并重用了其所有选项,但将构建转移到asdf
的控制下。因此,之前的配置说明保持不变。您只需要更改以下调用的顺序
# asdf install erlang <version>
$ asdf install erlang 21.3
...
# asdf global <name> <version> [<version>...]
# asdf local <name> <version> [<version>...]
# export ASDF_ERLANG_VERSION=<version>
从那里开始,kerl
和asdf
之间的主要区别在于,kerl
将使用环境变量来了解要运行哪个版本,而asdf
将可选地使用.tool-versions
文件来按目录触发更改。
FreeBSD
在 FreeBSD 上,使用 kerl
(如其他章节所述)的体验参差不齐。有时需要一些补丁才能使其像其他平台一样平稳运行。好消息是,如果您使用 BSD 的 ports 或 packages,它将开箱即用。
这是最简单的方法,但它使得在版本之间切换变得有点棘手,因为您无法免费获得 Erlang 版本管理器。但是,BSD ports 和 packages 确实允许您根据需要构建任何受支持的版本。
例如,您可以调用以下任何一个
# pkg install erlang # default copy
# pkg install erlang-runtime20 # OTP-20.x
# ls /usr/ports/lang/erlang* # source install: pick the version directory
erlang/
...
erlang-runtime20/
erlang-runtime21/
erlang-wx/
# cd /usr/ports/lang/erlang-runtime21/
# make config-recursive # configure all the deps
# make install
FreeBSD 维护者通常很擅长确保在主要支持的架构上一切正常运行,因此,如果您坚持使用 x86 并避免 ARM,则应该不会遇到任何重大问题。
优化环境
在完成操作之前,您应该转到您的 shell 或终端配置文件,并添加一些环境变量。具体来说,您可以使用 ERL_AFLAGS
或 ERL_ZFLAGS
在任何时候向 erl
可执行文件添加配置开关。
我们将使用 ERL_AFLAGS
来开启两个不错的功能:默认情况下输出支持 Unicode 的字符串,以及启用 shell 历史记录,以便 Erlang shell 在调用之间记住您的命令。将以下内容添加到您的环境中
export ERL_AFLAGS="+pc unicode -kernel shell_history enabled"
这样会感觉更现代一些。
安装 Rebar3
Rebar3 是 Erlang 社区中的标准构建工具。它基本上将 Erlang 附带的所有其他工具以及一些开源工具捆绑在一起,并使它们都在统一的项目结构下工作。
有几种方法可以安装 Rebar3:从预构建的二进制文件安装,或从源代码安装,然后是用于更快运行的本地安装的最后一种变体。请注意,在所有情况下,都需要先安装 Erlang。
预构建二进制文件
预构建的二进制文件可以在 www.rebar3.org 上找到。有一个大的“下载”按钮,其中包含最新稳定版本,但如果您喜欢冒险,也可以获取 最新的 夜间构建 版本。
通常会创建一个 ~/bin/
目录来放置像 rebar3
这样的命令行实用程序,您可能希望将刚刚下载的版本放在这里。调用 chmod +x rebar3
以确保它可以运行,并在您的 ~/.bashrc
、~/.zshrc
或等效文件中使用 export PATH=~/bin/:$PATH
将其添加到您的路径中。
希望使用 PowerShell 或 cmd.exe(而不是终端模拟器)的 Windows 用户必须确保添加了 rebar3.cmd
文件
@echo off
setlocal
set rebarscript=%~f0
escript.exe "%rebarscript:.cmd=%" %*
从源代码构建
首先确保您已安装 git,然后签出存储库以构建它
$ git clone https://github.com/erlang/rebar3.git
$ cd rebar3
$ ./bootstrap
这将创建一个 rebar3
脚本文件(以及 Windows 上的 rebar3.cmd
文件)。
本地安装
本地安装形式允许您获取任何先前构建的 Rebar3 版本,并将它们解压缩到一个本地目录,该工具以后可以从该目录进行自我更新
$ ./rebar3 local install # starting from a rebar3 not in PATH
===> Extracting rebar3 libs to ~/.cache/rebar3/lib...
===> Writing rebar3 run script ~/.cache/rebar3/bin/rebar3...
===> Add to $PATH for use: export PATH=$PATH:~/.cache/rebar3/bin
$ export PATH=$PATH:~/.cache/rebar3/bin
$ rebar3 local upgrade # this can be used to update to the latest stable copy
...
配置编辑器
与编辑器无关(通过语言服务器)
一个 语言服务器 是一种与编辑器无关的解决方案,它提供语言功能,例如代码完成、跳转到定义和内联诊断。Erlang LS 语言服务器为 Erlang 编程语言实现了这些功能。它与 Emacs、VS Code、Sublime Text 3、Vim 以及可能更多遵循 LSP 协议 的文本编辑器和 IDE 集成。
要开始使用特定文本编辑器的 Erlang LS,请参阅 文档 的“编辑器”部分。
Visual Studio Code
推荐使用 Pierrick Gourlain 的 Erlang 扩展。
要配置扩展,请转到“首选项”,然后转到“设置”菜单。在 VS Code 窗口中,展开“扩展”菜单,直到“erlang 配置”部分。确保所有值都正确,特别是 Erlang 路径和 Rebar3 路径。有了这些,您可以混合搭配您想要的其他所有扩展,一切就绪。
代码格式化程序可能会感觉有点笨拙;它遵守 Erlang 官方存储库中混合制表符和空格的旧规则,并期望每个制表符为 8 个空格宽。这在其他任何地方都不常用,如果您的 Visual Studio Code 未按此方式配置(例如使用 4 个空格),它看起来就会很奇怪。
否则,该扩展涵盖了所有主要功能:在代码定义之间跳转、构建工具支持(尽管命令面板中仅支持 compile
、eunit
和 dialyzer
,您仍然可以从终端直接调用 rebar3
)、智能感知、键入时的警告和 CodeLens 功能。如果您查看扩展的文档,您还会找到调试器支持说明。
然后,您只需根据自己的喜好配置主题和更通用的扩展。
Emacs
Erlang/OTP 在 tools
应用程序(lib/tools/emacs/
)中带有一个 Emacs 模式。本书中使用 Emacs 的作者坚持使用此模式,让 Emacs 直接从安装的最新 Erlang 版本加载。对于在 erlang-mode
中使用更高级支持的替代模式和插件,有很多选择,这里我们只讨论 Ivy 代码补全和 Flycheck 语法检查。但首先我们需要 use-package,它是一个用于隔离包配置的工具。自动安装 use-package
的代码可以 在这里找到。将该代码包含在您的 ~/.emacs.d/init.el
中,以便在启动时安装 use-package
。或者使用 use-package
网站上提供的 安装说明。
以下 elisp
代码可用于设置仅 erlang-mode
,不涉及 Ivy 或 Flycheck,并使其加载 Rebar3、Relx 和其他 Erlang 配置文件
(use-package erlang
:load-path ("<PATH TO OTP>/lib/erlang/lib/tools-3.0/emacs/")
:mode (("\\.erl?$" . erlang-mode)
("rebar\\.config$" . erlang-mode)
("relx\\.config$" . erlang-mode)
("sys\\.config\\.src$" . erlang-mode)
("sys\\.config$" . erlang-mode)
("\\.config\\.src?$" . erlang-mode)
("\\.config\\.script?$" . erlang-mode)
("\\.hrl?$" . erlang-mode)
("\\.app?$" . erlang-mode)
("\\.app.src?$" . erlang-mode)
("\\Emakefile" . erlang-mode)))
要使用 Ivy 获取代码补全支持,请添加 ivy-erlang-complete
包,为其设置自定义 Erlang 根目录并配置 Erlang 模式时运行其 init
(use-package ivy-erlang-complete
:ensure t)
(use-package erlang
:load-path ("<PATH TO OTP>/lib/erlang/lib/tools-3.0/emacs/")
:hook (after-save . ivy-erlang-complete-reparse)
:custom (ivy-erlang-complete-erlang-root "<PATH TO OTP>/lib/erlang/")
:config (ivy-erlang-complete-init)
:mode (("\\.erl?$" . erlang-mode)
("rebar\\.config$" . erlang-mode)
("relx\\.config$" . erlang-mode)
("sys\\.config\\.src$" . erlang-mode)
("sys\\.config$" . erlang-mode)
("\\.config\\.src?$" . erlang-mode)
("\\.config\\.script?$" . erlang-mode)
("\\.hrl?$" . erlang-mode)
("\\.app?$" . erlang-mode)
("\\.app.src?$" . erlang-mode)
("\\Emakefile" . erlang-mode)))
Flycheck 带有 Rebar3 支持,并且可以自动检测 Rebar3 项目,因此只需要 flycheck
包
(use-package delight
:ensure t)
(use-package flycheck
:ensure t
:delight
:config (global-flycheck-mode))
use-package
的 :config (global-flycheck-mode)
参数将在您在 Emacs 中编辑的所有代码中启用 Flycheck,使用 :config
给出的表达式在加载包后运行。:delight
参数告诉 use-package
使用 delight
实用程序禁用在模式行中显示 Flycheck。将其保留在模式行之外可以节省空间,尤其是在全局启用它时,我们不需要在模式行中将其称为当前启用的。
如果您喜欢使用 Flycheck,那么 hydra 值得一试,用于逐步执行和查看完整的错误列表。Hydra 宏设置了仅在运行初始 Hydra 绑定后才起作用的简短键绑定。以下代码将在调用 C-c f
时设置用于查看 Flycheck 错误的基本绑定
(use-package hydra
:defer 2
:bind ("C-c f" . hydra-flycheck/body))
(defhydra hydra-flycheck (:color blue)
"
^
^Errors^
^──────^
_<_ previous
_>_ next
_l_ list
_q_ quit
^^
"
("q" nil)
("<" flycheck-previous-error :color pink)
(">" flycheck-next-error :color pink)
("l" flycheck-list-errors))
最后,一些不是 Erlang 专用但开发项目时非常有用的包
- magit:Git 的 Emacs 接口。Magit 不仅允许从 Emacs 调用 Git,还为从暂存更改到交互式变基的所有操作提供了简化的界面。
counsel-rg
:counsel 是一个利用 Ivy 的命令集合,我们之前将其用于 Erlang 代码补全。counsel-rg
使用 ripgrep 在项目的各个文件中搜索字符串——在 Git 项目中,它们的作用类似于git grep
,仅搜索 Git 存储库中的文件并遵循.gitignore
。由于 ripgrep 是一个外部命令,因此必须单独安装,例如在 Ubuntu 或 Debian 上运行sudo apt-get install ripgrep
。安装ripgrep
后,ivy-erlang-complete
也将使用它来加快搜索速度。- swiper:使用 Ivy 在缓冲区中搜索的
isearch
的替代方案。 - company-mode:通过 company-erlang 与
ivy-erlang-complete
结合使用时,此模式将自动提供一个代码补全弹出窗口,而无需使用C-:
在 minibuffer 中显示代码补全。 - flycheck-inline、flycheck-pos-tip 或 flycheck-popup-tip:这些包提供了不同的选项,用于在错误位置而不是在 minibuffer 中显示 Flycheck 错误。
Vim
尽管 Vim 中完全可以实现对 Erlang 的高级支持——正如 Github 上的 vim-erlang 组 所允许的那样——本书中使用 Vim 的作者倾向于坚持尽可能最小的配置。
只需在您的 .vimrc
文件中使用默认的语法高亮显示,并确保它在所有正确的文件类型中使用
"also erlang
autocmd BufRead,BufNewFile *.erl,*.es.*.hrl,*.xrl,*.config setlocal expandtab noautoindent
au BufNewFile,BufRead *.erl,*.es,*.hrl,*.xrl,*.config setf erlang
这只是非常基本的东西,显然。更高级的集成是可能的,但使用 vim 的一位作者主要只使用这些,并依赖终端中的 Rebar3 来处理语言的其余部分。