资讯详情

Erlang/OTP 24 源码编译:otp_src 安装指南与避坑

📅 2026/10/15 11:47:42 | 华诺云谱 👁 阅读
Erlang/OTP 24 源码编译:otp_src 安装指南与避坑
简介源码包 otp_src_24.0.tar.gz 提供 Erlang/OTP 24.0 的完整源代码核心面向 RabbitMQ 二次开发者、Erlang 分布式系统学习者以及需要排查消息中间件底层行为的技术人员。压缩包约 96.51MB采用 tar.gz 格式打包解压后包含 otp_src_24.0 主目录发布页未出示文件总数与类型明细但典型结构会有 ertsErlang 虚拟机与运行时、libMnesia 等库模块、docAPI 文档、src源码和 test测试用例并带有 make、rebar3 等构建脚本方便分区查阅和编译研究。已有 645 人浏览学习适合作为深入 Erlang 并发模型、容错机制和分布式通信的参考代码。通过研读这套源码读者能理解 RabbitMQ 为何选择 OTP 作为运行基石掌握监督树、错误恢复、进程管理等核心设计进而学会针对消息队列进行定制改造与性能调优为构建可靠的后端服务提供扎实支撑。此外OTP 源码中附带的文档与示例也能帮助初学者更快上手 Erlang 开发并为后续阅读 RabbitMQ 的 Erlang 实现提供良好铺垫。1. otp_src_24.0.tar.gz 到底是什么从文件后缀到你的第一个 Erlang 虚拟机看到otp_src_24.0.tar.gz这个文件名第一反应是这是一个 Erlang/OTP 24.0 的源码压缩包不是安装包。下载它的人大概率不是想用预编译的二进制而是想在特定操作系统、特定硬件、特定依赖库组合下编译出一个自己可控的 Erlang 运行时。它能解决什么问题一句话当你需要定制 OpenSSL 版本、需要精简某些 OTP 应用、需要把 Erlang 装到没有官方包的服务器上时只有源码编译这条路走得通。适合谁适合那些对 Erlang 虚拟机原理有点兴趣、想自己掌控编译选项的后端工程师也适合运维同学在离线环境里搭一套 OTP 运行时。这篇文章从解压讲到验证把 configure、make、安装后检查的每一步和容易翻车的点都过一遍。2. 把 otp_src_24.0.tar.gz 变成可执行文件环境准备、校验与解压2.1 编译 Erlang/OTP 24.0 之前先把系统依赖补齐编译 OTP 源码依赖项不算多但每个都不能缺。以常见的 Linux 发行版为例我一般会先把这几类装好C 编译器gcc 或 clang、make 工具、Perl用来生成文档和部分配置、OpenSSL 开发头文件、ncurses 开发包终端交互要用以及 m4、autoconf 等自动构建工具。如果缺了 OpenSSL 头文件configure 会在最后阶段给你一个让人摸不着头脑的错误说 crypto 应用无法编译。这里有一个选型理由OTP 24 的 crypto 应用默认依赖 OpenSSL如果系统里有多个 OpenSSL 版本最好用--with-ssl显式指定一个。我用的是系统自带的 OpenSSL 1.1.1因为 OTP 24 的官方测试主要覆盖这一代。如果你非要编译进 OpenSSL 3.0也能跑但要注意可能触发一些新版本才有的告警。在 Debian 系发行版上常见做法是执行下面这组命令。这里我写成一个脚本块方便你检查# 检查基础编译工具是否已经可用 gcc --version make --version perl --version # 安装常见依赖 sudo apt-get update sudo apt-get install -y build-essential autoconf m4 libncurses5-dev \ libssl-dev unixodbc-dev libwxgtk3.0-gtk3-dev # 如果系统提示找不到 libwxgtk就把最后一项去掉 # wx 库只用于图形界面工具 observer无头服务器可以不装这段命令先验证 gcc、make、perl 三个基础工具存在再安装构建依赖。libssl-dev提供的是 OpenSSL 的开发头文件和链接库缺了它 crypto 应用编译必挂。unixodbc-dev是给 ODBC 接口用的如果你明确不碰数据库接口可以忽略。libwxgtk 是可选的装了能在本地起 observer 图形观察器不装也不影响虚拟机运行。执行完可以用dpkg -l | grep libssl-dev确认头文件路径。2.2 拿到压缩包后先做完整性校验再解压从网上拖下来的 tar.gz第一件事不是解压而是看校验值。发布页会给出对应的 sha256 值。我一般用sha256sum对比避免因为网络传输损坏导致编译中途出现诡异错误。这一步看着无关紧要实际能省下至少一小时的排查时间。# 计算当前文件的 sha256 值 sha256sum otp_src_24.0.tar.gz # 十六进制查看开头内容确认是 gzip 压缩格式 file otp_src_24.0.tar.gzfile命令输出里应该包含 gzip compressed data 字样这能排除你下到的是一个 HTML 错误页。sha256sum 算出来的值要和发布页公布的比对差别大就重新下载。这个步骤看起来多余但能帮你避开一类很浪费时间的坑文件不完整解压能成功configure 也能过编译到一半突然报一个莫名其妙的语法错误。校验就是给后面的三个小时上保险。2.3 解压到独立目录保留源码目录不被污染强烈建议不要把解压出来的目录直接放在你打算构建的目录里。我习惯的做法是建一个~/build目录把源码解压进去然后在源码目录外单独建一个 build 目录做编译。其实 OTP 源码支持在源码目录内直接 configure但这样源码目录会被生成的文件弄脏下次想重新编译比较麻烦。更干净的做法是在源码目录外建一个空目录用源码目录里的 configure 脚本去配置具体细节下一章说。mkdir -p ~/build cd ~/build tar -xzf otp_src_24.0.tar.gz cd otp_src_24.0 # 看看顶层目录结构的关键部分 ls -F | head -20解压后顶层目录里你会看到configure、Makefile.in、erts、lib这些关键对象。erts是 Erlang Run-Time System也就是虚拟机本体的源码lib里是按应用分模块的库代码比如lib/crypto、lib/ssl。这个结构也能解释为什么 OTP 编译时间很长它不只是编译一个 VM还要把 OTP 内置的几十个应用全部编译一遍。如果只是想要一个精简的运行时后面可以通过配置裁剪但第一步还是要完整编译。用head -20只列前 20 个条目防止文件太多刷屏。确认configure文件存在且可执行就可以进入下一步了。如果ls -l configure显示没有 x 权限可以用chmod x configure修复。3. 用 configure 定制你的 OTP 24常用参数与选型逻辑3.1 configure 最小可用命令先跑通再谈优化源码编译 OTP 的第一步是执行configure脚本。它会检查系统环境生成Makefile和若干头文件。最小可用命令其实就一行什么都不加cd ~/build/otp_src_24.0 ./configure跑完后留意输出的最后几行它会生成一个config.status并打印出正在构建的 OTP 版本和应用列表。如果这一步失败错误信息通常会直接告诉你缺哪个库或哪个工具。不要跳过这个输出很多问题在 configure 阶段就暴露了比编译到一半才发现要省时间得多。默认行为是启用所有可以启用的应用包括 crypto、ssl、ssh、wx、odbc 等。如果你的机器上恰好缺少某些库configure 通常会自动降级也就是把对应的应用标记为 not built并在最后的 summary 里列出来。这意味着即使你没有显式禁用缺依赖的应用也不会被打包进最终安装。所以我更建议先跑一次全默认配置看 summary 里有哪些应用因为缺依赖没被编进去再决定要不要重新配置来安装那些依赖。这样能避免你一开始就裁剪结果要用了才发现裁剪错了。3.2 指定安装前缀--prefix 的取舍默认安装路径是/usr/local可执行文件会在/usr/local/bin/erl。对于自己编译的 OTP我通常不喜欢污染系统路径而是装到一个独立目录比如/opt/otp/24.0。这样以后想卸载直接删目录就行不会有那个关于包管理器的后悔药问题。cd ~/build/otp_src_24.0 ./configure --prefix/opt/otp/24.0--prefix的作用是设定安装根目录。之后编译出的主程序会放到/opt/otp/24.0/bin/erl库文件放到/opt/otp/24.0/lib。如果你需要多个 OTP 版本共存比如为了测试升级兼容性就可以分别用/opt/otp/24.0、/opt/otp/25.0。这种方式比用系统包管理器更可控。设置完 prefix 后别忘了把对应 bin 目录加入PATH否则你敲erl调到的可能还是系统里旧版本的 Erlang。3.3 控制 OpenSSL 与模块裁剪--with-ssl 和 --without-wxOTP 24 的 crypto 和 ssl 应用都依赖 OpenSSL 头文件和运行库。configure 默认会用pkg-config去查找 OpenSSL。如果系统有多个版本或者 OpenSSL 装在非标准位置你就需要显式指定。我处理过的一台老机器上系统自带的是 OpenSSL 1.0.2但项目强制要求链接到 1.1.1所以加了如下参数./configure --prefix/opt/otp/24.0 \ --with-ssl/usr/local/ssl \ --enable-dirty-schedulers--with-ssl/usr/local/ssl告诉 configure 到指定目录去找 OpenSSL 的include和lib。--enable-dirty-schedulers是 OTP 的一个特性它允许某些长时间运行的系统调用在专门调度器上执行避免阻塞普通调度器。这个参数在 OTP 24 上是默认启用的如果你想要的其实是默认行为写不写无所谓。但如果你查文档看到某个版本默认关闭就需要显式开启。还有一个参数值得注意--without-wx。如果你确定不需要图形化的 observer 应用可以显式禁用它减少编译时间和安装体积。我通常在无头服务器上不加 wx 相关依赖直接用这个参数。./configure --prefix/opt/otp/24.0 --without-wx在 configure 的输出里你会看到类似wx: no这样的摘要这代表它没有被编进去。如果后续想要 observer 的图形界面再回去重新编译 wx 模块就行不必重编整个系统。3.4 并行编译参数make 的 -j 怎么用才不翻车configure 完成后进入核心编译阶段。OTP 的编译非常耗时单线程跑完整套在一个四核机器上可能要 30 分钟以上并行编译能大幅缩短。我一般会根据 CPU 核心数来定-j的值但不是盲目用-j$(nproc)。# 编译全部使用 4 个并行任务 make -j4 # 如果中途编译失败可以不带 -j 重新执行方便定位错误 make-j4的意思是让 make 同时运行 4 个编译任务。为什么不建议直接用最大核数因为在某些版本上OTP 的依赖文件之间存在竞态并行度过高容易触发一个看起来很玄学的 Undefined symbol 错误。如果你一定要用高并行度比如-j8遇到失败时先串行重跑往往就通过了。注意并行编译失败后不要急着清理保留.o文件和Makefile串行 make 会从失败点继续节省大量时间。我还会在 make 之前设置环境变量MAKEFLAGS比如export MAKEFLAGS-j4这样后续子 make 也会继承并行设置。但要注意某些生成文档的步骤需要串行所以更稳妥的做法是只在主编译时指定-j4。4. OTP 24 编译安装避坑指南五个高频问题和排查方法4.1 configure 提示找不到 opensslconf.h现象在执行./configure时输出里出现 crypto 应用无法构建具体错误指向opensslconf.h找不到。原因系统里 OpenSSL 头文件没安装或者安装的是 3.0 版本而头文件路径与 configure 预期不同。解决先确认头文件位置。dpkg -l | grep libssl-dev find /usr/include -name opensslconf.h 2/dev/null如果头文件存在但路径特殊用--with-ssl/usr或--with-ssl/usr/local指定。如果不存在安装libssl-dev。记住光有libssl是不够的开发包里的头文件才有opensslconf.h。4.2 make 过程中出现与 odbc 相关的错误现象编译到某些库时报错说找不到到odbc或数据库驱动的链接。原因ODBC 应用默认依赖unixodbc-dev包如果系统没有它configure 阶段应该会跳过但某些版本会在 make 阶段出错。解决安装unixodbc-dev后重新 configure 并 make。这不是 OTP 的问题而是系统环境缺依赖。如果你根本不用 ODBC直接 configure 时加上--without-odbc。4.3 编译完成但 erl 启动后显示版本不对现象安装完 OTP 24运行erl看到版本是 22 或者某个旧版本。原因系统 PATH 里旧版本的 erl 排在/opt/otp/24.0/bin前面。解决显式使用完整路径或调整 PATH。/opt/otp/24.0/bin/erl -version export PATH/opt/otp/24.0/bin:$PATH不要把新版本 bin 追加到 PATH 末尾那样永远调不到。在使用erl之前用which erl确认指向。4.4 编译时内存不足进程被系统杀掉现象make 运行到一半终端显示 Killed系统日志里能看到 OOM 事件。原因并行编译任务过多每个 Erlang 编译器进程都占用大量内存。解决降低-j数值例如从-j8降到-j2。如果仍然不够临时增加 swap或者配置时用ERL_TOP环境变量指向源码目录减少一些无谓的路径处理。4.5 安装后 crypto 模块加载报错现象启动 erl 后调用crypto:start()失败提示nif库加载异常。原因OTP 编译时 crypto 链接的 OpenSSL 库路径在运行时找不到或者 OpenSSL 版本冲突。解决用ldd检查 crypto NIF 库的依赖。ldd /opt/otp/24.0/lib/erlang/lib/crypto-*/priv/lib/crypto.so如果输出里有not found说明你需要设置LD_LIBRARY_PATH或者把 OpenSSL 安装路径加入动态链接器配置。另一种更常见的做法是重新 configure用--with-ssl指定与运行时一致的路径。5. 验证安装结果与三个进阶使用技巧5.1 用 erl 和 erl 的内置命令做安装验证编译安装完成后不要急着跑业务代码先用几个简单命令验证虚拟机和核心模块正常。打开终端进入新安装的 bin 目录执行/opt/otp/24.0/bin/erl -version如果输出类似Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 12.0说明主虚拟机安装成功。然后进入交互 shell测试 crypto 和 ssl 是否加载application:ensure_all_started(crypto). application:ensure_all_started(ssl).如果返回{ok, [...]}并且没有错误说明 crypto 和 ssl 依赖的 NIF 都正确加载了。对于离线环境你还可以用erl -eval一行跑完不需要进入交互erl -eval io:format(~s~n, [erlang:system_info(otp_release)]), halt().5.2 用 erlc 编译一个 demo 模块确认编译器链完整otp_src 包含了完整的编译工具链比如erlc和erl。安装后手动写一个极小的模块编译并运行能同时验证编译器和运行时。cat /tmp/demo.erl EOF -module(demo). -export([hello/0]). hello() - io:format(OTP 24 source build works~n). EOF cd /tmp /opt/otp/24.0/bin/erlc demo.erl /opt/otp/24.0/bin/erl -noshell -s demo hello -s init stop看到输出OTP 24 source build works说明编译器、字节码加载器和运行时全部正常。这个小 demo 也可以当作后续测试最小环境是否完整。5.3 进阶用 make install DESTDIR 做打包分发如果你要在多台机器上部署同一份编译结果不需要每台都重新编译。在编译机上用 DESTDIR 把安装目录重定向到临时打包目录配合 tar 可以快速分发cd ~/build/otp_src_24.0 make install DESTDIR/tmp/otp24-package tar -czf otp24-package.tar.gz -C /tmp/otp24-package .DESTDIR 的实际效果是把安装根目录重定向所有文件会装到/tmp/otp24-package/opt/otp/24.0下。这个方式特别适合没有 gcc 的生产机前提是系统架构完全一致且动态库版本兼容。打包机上的 glibc 版本不能比目标机新否则到目标机跑不起来。我自己的保留习惯是编译完顺手做一个erl -noshell -eval erlang:system_info(system_version)输出记录到文件里下次排查某个杀不掉的进程是哪个版本编出来的就不用再猜了。调试的时候这些看似多余的证据往往比现场日志更有用。希望这些步骤和坑能帮你把otp_src_24.0.tar.gz这堆源码变成一套稳定的 Erlang 运行时落地的过程中少走点弯路。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑