mruby Amalgamation 单文件构建完全指南:原理、生成与嵌入实践
编程语言语言运行时编译器解释器嵌入式【免费下载链接】mrubyLightweight Ruby项目地址https://gitcode.com/gh_mirrors/mr/mruby点击查看免费下载mruby 的 Amalgamation合并构建机制参照 SQLite 的分发模型把整个运行时压缩为mruby.c与mruby.h两个文件让宿主程序无需任何构建系统即可把 Ruby 解释器嵌入自己的 C 工程。本文从生成命令、嵌入编译、Gem 兼容性到MRB_AMALGAMATION宏与头部/源文件合并的底层原理逐层展开帮助你彻底掌握这一能力并在实际项目中直接落地。什么是 AmalgamationAmalgamation 将 mruby 的所有源文件合并为单一翻译单元中的两个文件见 amalgamation.mdmruby.h—— 按依赖顺序拼接的全部公共头文件mruby.c—— 按初始化顺序拼接的全部源码核心 Gem 编译后的 mrblib。这种分发方式与 SQLite 的 amalgamation 发行包思路一致使用者拿到两个文件复制进自己的工程即可不需要了解 mruby 内部的模块划分也不需要安装任何构建工具链。四大优势集成极简向项目添加的只有两个文件无需引入 mruby 的 Rake 构建体系。单一编译单元整个运行时在同一翻译单元内编译编译器可以在函数边界之间做跨文件优化如常量传播、内联这是多文件编译难以获得的优化空间。免构建系统任意符合 C 标准的编译器直接编译mruby.c即可不依赖 make、rake 或特定链接脚本。可移植核心运行时除标准 C 库外无外部依赖但注意下文「平台相关 Gem」一节中 HAL 引入的平台约束。生成 Amalgamation在仓库根目录执行rake amalgam任务定义位于 amalgam.rake它先为build/target/include下的 presym 头文件建立依赖:gensym再以MRuby::Amalgam生成头文件与源文件最后输出路径提示。生成物位于build/target/amalgam/ ├── mruby.h # 按依赖顺序拼接的全部头文件 └── mruby.c # 拼接的全部源码核心 gems mrblib使用自定义构建配置合并产物中包含构建配置里声明的 Gem。例如使用最小化配置MRUBY_CONFIGbuild_config/minimal.rb rake amalgamminimal.rb 是一个CrossBuild仅添加MRB_NO_STDIO宏产出体积明显更小。构建配置选定的 boxing 方式MRB_NAN_BOXING/MRB_WORD_BOXING/ 无 boxing、整数宽度如MRB_INT64等功能开关会一并决定mruby.h中mrb_value的布局因此生成 amalgamation 所用的配置与最终编译宿主程序时使用的头文件必须一致。在宿主程序中嵌入使用基本用法在你的 C 程序中包含唯一的头文件并调用标准 mruby API#include mruby.h int main(void) { mrb_state *mrb mrb_open(); mrb_load_string(mrb, puts Hello from mruby!); mrb_close(mrb); return 0; }mrb_load_string需要mruby-compilerGem见下文 Gem 兼容性。后续还可以使用mrb_load_file、mrb_funcall、mrb_vm_run等常规 API 扩展宿主能力。编译直接把mruby.c当作一个源文件参与编译并指向 amalgam 目录作为头文件搜索路径gcc -I./build/host/amalgam your_app.c ./build/host/amalgam/mruby.c -o your_app -lm-lm用于链接数学库mruby-math等 Gem 会用到。优化构建正式发布建议开启优化并关闭断言gcc -O2 -DNDEBUG -I./build/host/amalgam your_app.c ./build/host/amalgam/mruby.c -o your_app -lm-DNDEBUG与MRB_DEBUG的关系见下文「构建配置宏」一节amalgamation 刻意不把MRB_DEBUG写进mruby.h是否启用断言由编译者自己决定-DNDEBUG正是同一类选择。Gem 兼容性已知可用的 Gem以下 Gem 与 amalgamation 兼容在生成时被正确合并并保持功能mruby-compiler——mrb_load_string等加载/编译功能的前提mruby-eval——eval、Binding扩展类 Gemmruby-array-ext、mruby-string-ext、mruby-hash-ext、mruby-numeric-ext、mruby-range-ext、mruby-symbol-ext、mruby-proc-ext、mruby-kernel-ext、mruby-object-ext、mruby-class-ext、mruby-enum-ext、mruby-compar-ext功能类 Gemmruby-error、mruby-math、mruby-struct、mruby-bigint、mruby-rational、mruby-complexmruby-io配合当前激活的ports/name/HALmruby-task同样依赖ports/name/HAL。平台相关 GemHAL使用 HAL硬件抽象层的 Gem 会把平台相关代码合并进mruby.c。以mruby-io为例其 ports 目录 下提供posix/与win/两套端口若在 Linux 上构建生成物内嵌 POSIX 实现该mruby.c无法在 Windows 上编译。因此需要多平台产物的场景应当为每个目标平台或交叉构建配置分别生成一份 amalgamation。此外mruby-task的 mrbgem.rake 显示其端口还支持glib等后端并可通过conf.ports :glib选择——这类 Gem 的合并产物同样绑定所选端口。被排除的 Gem二进制 Gemmruby-bin-*会被自动排除它们各自带有main()入口如 mruby-bin-mruby 的入口而 amalgamation 产出的是库而非可执行程序。这也解释了 default.gembox 中为何将mruby-bin-mrbc、mruby-bin-debugger、mruby-bin-mirb、mruby-bin-mruby、mruby-bin-strip等命令与运行库分开管理。实现层面MRuby::Amalgam#library_gems正是以gem.name.start_with?(mruby-bin-)过滤掉这些 Gem见 amalgam.rb。示例配置为 amalgamation 定制一个最小可用配置原文档示例文件路径建议为build_config/amalgam.rb# build_config/amalgam.rb MRuby::Build.new do |conf| conf.toolchain :gcc conf.gem core: mruby-compiler conf.gem core: mruby-error conf.gem core: mruby-eval conf.gem core: mruby-array-ext conf.gem core: mruby-string-ext conf.gem core: mruby-hash-ext conf.gem core: mruby-io end生成MRUBY_CONFIGbuild_config/amalgam.rb rake amalgam输出体积典型体积随包含的 Gem 数量浮动mruby.h约 270–800 KBmruby.c约 1.4–6.9 MB。体积差异主要来自 Gem 的 C 源码、编译后的 mrblib如mrblib.c、gem_mrblib.c以及 X-macro 表的多次内联。追求极致体积时可参考build_config/minimal.rb的MRB_NO_STDIO思路关闭不需要的子系统。技术细节头文件处理合并mruby.h时实现见 amalgam.rb 的HEADER_ORDER与write_ordered_headers剥离 include guard去除每个头文件的#ifndef GUARD / #endif包裹使内容能直接拼接#define GUARD保留供后续#ifdef检查使用按依赖排序先基础类型mruby.h及其内联的value.h、object.h等再各功能头文件内部 include 注释化已被并入mruby.h的#include mruby/...被注释掉避免重复定义。boxing 头文件不直接平铺而是保留条件包含结构在 value.h 中按MRB_NAN_BOXING/MRB_WORD_BOXING/ 默认依次展开保证生成物与构建配置的mrb_value布局严格一致。Gem 自带头文件如mruby-compiler的mrc_*.h、vendored prism 头也会按依赖做 DFS 后序排序后并入无 include guard 的头文件被识别为 X-macro 表改为在每次 include 处内联而不是去重。源文件处理合并mruby.c时按初始化顺序拼接核心源码按CORE_SOURCE_ORDER排序allocf → readnum/readint → state → symbol → class → object → gc → …… → vm → load/dump → init保证函数定义与注册顺序正确X-macro 头内联如mruby/ops.h这类依赖调用点宏定义的头文件在每个 include 处整体内联而非注释掉局部文件内联#include xxx.cstub等局部文件如known_errors_def.cstub被读取后直接嵌入源码生成文件并入编译后的build/*/mrblib/mrblib.c与build/*/mrbgems/gem_init.cGem 注册表被写入源文件尾部。合并过程中还会处理两类冲突其一同一宏在不同源文件中语义不同如mrb_stat、CASE、NEXT等每个源文件结束后统一#undef清理见CONFLICTING_MACROS其二不同 Gem 的静态符号同名如mruby-bigint与mruby-regexp都有pool_alloc生成器会扫描各源文件的static定义对冲突符号用#define临时改名再在 Gem 源码段结束后#undef还原。MRB_AMALGAMATION宏的意义生成的mruby.c在一切内容之前定义MRB_AMALGAMATION其作用是标记当前翻译单元承载的是整个运行时而非单个源文件从而让那些按翻译单元规模请求编译器工作的源码保持与逐文件构建相同的优化边界。最典型的例子是 VM。mrb_vm_exec()携带__attribute__((flatten))该属性会把函数内部的所有调用递归内联到翻译单元允许的深度见 vm.c 中的 MRB_FLATTEN 定义在逐文件构建中内联在 VM 自身的静态操作码处理器处停止这正是该属性的设计意图在 amalgamation 中整个运行时处于同一翻译单元内联下探会触及分配 → 垃圾回收 → 异常抛出相互构成的调用环如mrb_realloc → mrb_realloc_simple → mrb_full_gc → sweep → mrb_realloc递归永不收敛——GCC 会在内联器中耗尽内存、连一个函数都发不出来因此 GCC 下 amalgamation 会丢弃该属性让mrb_vm_exec()像普通函数一样被优化Clang 能保持下探有界几秒内完成同样文件的编译且带属性比不带属性运行更快因此 Clang 保留该属性。这一取舍正是MRB_AMALGAMATION存在的原因它让 VM 源码知道现在是合并构建从而按平台差异调整优化策略。构建配置宏写进 mruby.h 的 defines生成mruby.h时构建所用的 defines 被写在首个#include之前见 amalgam.rb 的write_baked_defines/collect_build_defines这样宿主程序只要包含mruby.h就获得与生成时完全一致的mrb_value布局、整数宽度和功能集。写入内容包括构建配置显式声明的宏conf.cc.defines如MRB_NO_STDIO、MRB_INT64、boxing 选择Gem 贡献的宏spec.build.defines、spec.cc.defines如mruby-io声明的 HAVE_MRUBY_IO_GEM、mruby-task声明的MRB_USE_TASK_SCHEDULER。每个宏都用#ifndef包裹因此命令行重复传入同名宏不会产生重定义。但并非 Gem 声明的所有宏都会进入头文件MRB_*与MRBGEM_*被丢弃——前者改变mruby.h本身的解释方式如 value boxing属于整个构建的 ABI 决策不应由单个 Gem 决定后者是版本字符串不是合法 C 常量。Gem 若确有需要进入头文件的MRB_*宏应声明在spec.build.defines__STDC_*被丢弃由生成器自行为 amalgamation 写出所需的部分。位置安排在一切#include之前与普通构建中每个-D先于每个头文件的效果一致这保证了 libc feature test 宏的正确性。例如某 Gem 需要使用 GNU 扩展在mrbgem.rake中写spec.cc.defines _GNU_SOURCE该声明就能到达 amalgamation 使用者的普通编译器命令行反之若在 Gem 源码文件顶部直接写#define _GNU_SOURCE合并后该文件落在翻译单元中部、第一个 libc 头文件之后宏将完全失效。同时必须注意在合并后的翻译单元中Gem 的宏会作用于所有源文件而非像普通构建那样只作用于该 Gem 自己的对象。添加声明的宏_GNU_SOURCE、_DEFAULT_SOURCE是安全的而限制 libc 特性集的宏_POSIX_C_SOURCE、_XOPEN_SOURCE可能遮蔽其他源文件依赖的声明需要谨慎使用。有两类宏故意不写入mruby.h交由编译者自行决定MRB_DEBUG——它只决定mrb_assert是否生效与前面-DNDEBUG属于同类选择MRB_USE_CXX_EXCEPTION与MRB_USE_CXX_ABI——它们要求 C 编译器而mruby.c是纯 C写进头文件会导致生成物无法按原样编译。构建顺序mruby.c的拼接次序严格遵循初始化依赖与 amalgam.rake 中source_deps对mrblib.c、gem_init.c的依赖一致核心源码src/*.c按CORE_SOURCE_ORDERGem 源码mrbgems/*/src/*.c或core/*.c含所选端口源码与生成源码如mruby-compiler的 prism 生成物生成的 mrblibbuild/*/mrblib/mrblib.c即编译后的 Ruby 标准库字节码表Gem 初始化build/*/mrbgems/gem_init.c注册所有 Gem 的 init/final 函数。小结Amalgamation 让 mruby 的嵌入成本降到两个文件 一条编译命令rake amalgam生成产物宿主程序包含mruby.h并连同mruby.c一起编译即可。理解其背后的 include guard 剥离、依赖排序、X-macro 内联、静态符号改名、MRB_AMALGAMATION对 VM 内联策略的调节以及构建宏的烘焙规则能帮助你在定制配置、处理平台相关 Gem 和定位编译问题时做出正确的工程决策。进一步阅读可参考 doc/README.md 中的文档索引或在 amalgam.rb 中研读生成器的完整实现。赞分享编程语言语言运行时编译器解释器嵌入式【免费下载链接】mrubyLightweight Ruby项目地址https://gitcode.com/gh_mirrors/mr/mruby点击查看免费下载相关推荐mruby 编译与交叉编译完全指南从构建配置到嵌入集成nghttp2 内置 mruby 实战mruby 编译与交叉编译完全指南从构建配置到嵌入集成nghttp2 内置 mruby 实战 导读 mruby 是一套轻量级、可嵌入的 Ruby 实现其可观测性日志分析云原生流处理H2O 项目内嵌 mruby 的编译与构建配置完全指南H2O 项目内嵌 mruby 的编译与构建配置完全指南 mruby 是一套轻量级、可嵌入的 Ruby 实现其核心价值在于能编译成静态库 libmruby.a后端网络H2O 内置 mruby-json 完全指南在 mruby 处理器中解析与生成 JSONH2O 内置 mruby json 完全指南在 mruby 处理器中解析与生成 JSON mruby json 是面向 mruby轻量级嵌入式 Ruby的后端网络上一篇最前沿的方向awesome-harness-engineering 自进化Harness与元框架资源深度解析下一篇如何从零开发 Blockly 硬件扩展以 vk1633-display 为例的完整开发者指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

从零实现 C++ AI 大模型接入 SDK(五):DeepSeek 流式响应 sendMessageStream() 完整实现

从零实现 C++ AI 大模型接入 SDK(五):DeepSeek 流式响应 sendMessageStream() 完整实现

目录 前言 一、从全量响应到流式响应 1.1 为什么这里使用 SSE 二、sendMessageStream():从请求到流式接收 2.1 先告诉 DeepSeek:我要流式返回 2.2 为什么不再直接使用 client.Post() 2.3 response_handler:先判断 HTTP 层是否成功 2.…

2026/10/12 2:21:20 阅读更多 →
Spring Boot酒店预订系统开发实战:数据库设计与并发控制

Spring Boot酒店预订系统开发实战:数据库设计与并发控制

1. 为什么我选择Spring Boot来做酒店预订系统这个项目其实是我在服务某小型连锁酒店时接到的需求。他们原来的预订方式还是电话和表格登记,前台每天要花大量时间核对房态、手写订单、月底对账更是灾难。最开始我想过要不要用现成的SaaS平台,但对方有几个…

2026/10/12 2:21:20 阅读更多 →
Python后端中间件专题18:搜索不是只输入一个词——过滤、排序与高亮

Python后端中间件专题18:搜索不是只输入一个词——过滤、排序与高亮

Python后端中间件专题18:搜索不是只输入一个词——过滤、排序与高亮 第 17 课为标题和正文建了全文字段,为租户、状态和标签保留了精确字段。现在客服输入“VPN 登录”,只想看本租户的 open/high 工单。一个搜索框背后至少有五件事&#xff1…

2026/10/12 2:21:20 阅读更多 →

最新新闻

WinForms Chart 时间轴实战:DateTime 转 OADate 与滚动条控制

WinForms Chart 时间轴实战:DateTime 转 OADate 与滚动条控制

简介:这份资源围绕VS自带Chart控件展开,面向需要在WinForms项目中实现时间轴图表的.NET开发者,重点解决x轴按时间刻度显示并配合滚动条浏览长时数据的问题。示例采用从Excel读取数据的方式,x轴时间格式为MM-dd HH:mm:ss:fff&#…

2026/10/12 4:02:25 阅读更多 →
Java微信退款接口实战:从签名、证书到异步回调与对账的完整链路

Java微信退款接口实战:从签名、证书到异步回调与对账的完整链路

简介:这是一份面向Java后端开发者的微信退款接口实现示例资源,聚焦商户在用户发起退款时通过API与微信服务器完成安全交互的完整流程。内容围绕Java网络编程、HTTPS安全通信、PKCS12证书管理、RSA2048数字签名与JSON数据处理展开,适合需要对接…

2026/10/12 4:02:25 阅读更多 →
iOS PDF电子签章实战:PDFKit绘制、坐标系与防篡改校验

iOS PDF电子签章实战:PDFKit绘制、坐标系与防篡改校验

简介:面向iOS开发者的PDF电子签章库,原生渲染与加载,体积控制得较小,适用于合同签署、贷款协议、单据确认等需要电子签章的移动场景,适合有一定Objective-C/iOS原生开发基础的工程师。资源共7个文件,压缩包…

2026/10/12 4:02:25 阅读更多 →
Linux实战100例:故障域分层与高危操作避坑指南

Linux实战100例:故障域分层与高危操作避坑指南

简介:本资源是面向Linux初学者与中级运维人员的实战型学习包,聚焦命令行操作、系统配置与常见故障排查,通过100个经典实例覆盖网络调用、Apache服务配置、错误代码解析等核心场景,帮助读者在真实环境中理解原理、积累排错经验。压…

2026/10/12 4:02:25 阅读更多 →
GLM-4源码包实战:从推理到LoRA微调与部署全流程

GLM-4源码包实战:从推理到LoRA微调与部署全流程

简介:GLM-4代码仓库完整源码包,面向大模型开发者、算法工程师及对本地部署感兴趣的技术爱好者,提供智谱AI第四代GLM系列模型的参考实现与基础使用框架。压缩包内共78个文件,包含Python脚本、YAML部署配置、JSON数据、Markdown说明…

2026/10/12 4:02:25 阅读更多 →
分红时代已死,资本证明时代崛起

分红时代已死,资本证明时代崛起

《分红时代已死,资本证明时代崛起》——下一轮能源周期,市场奖励的不是“投得更多”,而是“证明每一笔钱为何值得花”过去五年,能源公司靠不花钱赢得投资者;未来五年,要靠会花钱。投下去的是资本&#xff0…

2026/10/12 4:01:25 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →