Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- [mruby homepage](#mruby-homepage)
- [Mailing list](#mailing-list)
- [How to compile, test, and install (mruby and gems)](#how-to-compile-test-and-install-mruby-and-gems)
- [Amalgamation (single-file build)](#amalgamation-single-file-build)
- [Building documentation](#building-documentation)
- [How to customize mruby (mrbgems)](#how-to-customize-mruby-mrbgems)
- [Index of Document](#index-of-document)
Expand Down Expand Up @@ -77,6 +78,21 @@ rake all test

See the [compile.md](doc/guides/compile.md) file for the detail.

## Amalgamation (single-file build)

mruby supports amalgamation, which combines all source files into a single
`mruby.c` and `mruby.h` for easy embedding (similar to SQLite).

```console
rake amalgam
```

Output files are generated in `build/host/amalgam/`. To use:

```console
gcc -I./build/host/amalgam your_app.c ./build/host/amalgam/mruby.c -o your_app -lm
```

## Building documentation

There are two sets of documentation in mruby: the mruby API (generated by YARD) and C API (Doxygen and Graphviz)
Expand Down Expand Up @@ -111,6 +127,7 @@ extensions in C and/or Ruby. For a guide on how to use mrbgems, consult the
<!-- BEGIN OF MRUBY DOCUMENT INDEX -->

- [About the Limitations of mruby](doc/limitations.md)
- [About Amalgamation (Single-File Build)](doc/guides/amalgamation.md)
- [About the Compile](doc/guides/compile.md)
- [About the Debugger with the `mrdb` Command](doc/guides/debugger.md)
- [About GC Arena](doc/guides/gc-arena-howto.md)
Expand Down
1 change: 1 addition & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ load "#{MRUBY_ROOT}/tasks/test.rake"
load "#{MRUBY_ROOT}/tasks/benchmark.rake"
load "#{MRUBY_ROOT}/tasks/doc.rake"
load "#{MRUBY_ROOT}/tasks/install.rake"
load "#{MRUBY_ROOT}/tasks/amalgam.rake"

##############################
# generic build targets, rules
Expand Down
1 change: 0 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
- configurable memory pools (per-object-type, memory-constrained devices)
- suspend/resume VM state (serialize/deserialize for power cycling)
- CMake build support (better IDE integration, standard C tooling)
- amalgamation (single-file distribution like SQLite)

# Things to do (Things we need to consider)

Expand Down
142 changes: 142 additions & 0 deletions doc/guides/amalgamation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<!-- summary: About Amalgamation (Single-File Build) -->

# Amalgamation

Amalgamation combines all mruby source files into a single `mruby.c` and
`mruby.h` for easy embedding, similar to SQLite's distribution model.

## Benefits

- **Simple integration**: Just two files to add to your project
- **Single compilation unit**: Enables better compiler optimization
- **No build system required**: Compile directly with any C compiler
- **Portable**: No external dependencies beyond standard C library

## Generating Amalgamation

```console
rake amalgam
```

Output files are generated in `build/<target>/amalgam/`:

- `mruby.h` - All headers concatenated in dependency order
- `mruby.c` - All sources concatenated (core + gems + mrblib)

### With Custom Configuration

The amalgamation includes gems specified in your build configuration:

```console
MRUBY_CONFIG=build_config/minimal.rb rake amalgam
```

## Using the Amalgamation

### Basic Usage

```c
#include "mruby.h"

int main(void) {
mrb_state *mrb = mrb_open();
mrb_load_string(mrb, "puts 'Hello from mruby!'");
mrb_close(mrb);
return 0;
}
```

### Compiling

```console
gcc -I./build/host/amalgam your_app.c ./build/host/amalgam/mruby.c -o your_app -lm
```

For optimized builds:

```console
gcc -O2 -DNDEBUG -I./build/host/amalgam your_app.c ./build/host/amalgam/mruby.c -o your_app -lm
```

## Gem Compatibility

### Known Working Gems

The following gems work with amalgamation:

- `mruby-compiler` - Required for `mrb_load_string`
- `mruby-eval` - `eval`, `Binding`
- `mruby-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`
- `mruby-error`, `mruby-math`, `mruby-struct`
- `mruby-bigint`, `mruby-rational`, `mruby-complex`
- `mruby-io` (with `hal-posix-io`)
- `mruby-task` (with `hal-posix-task`)

### Excluded Gems

Binary gems (`mruby-bin-*`) are automatically excluded as they contain
their own `main()` function. The amalgamation produces a library, not
an executable.

## Example Configuration

A minimal configuration for amalgamation:

```ruby
# 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
```

Generate with:

```console
MRUBY_CONFIG=build_config/amalgam.rb rake amalgam
```

## Output Sizes

Typical sizes depend on included gems:

- `mruby.h`: 200-500 KB
- `mruby.c`: 2-4 MB

## Technical Details

### Header Processing

- Include guards are stripped to allow concatenation
- Headers are ordered by dependency (foundation types first)
- Internal includes are commented out (already in `mruby.h`)

### Source Processing

- Sources are concatenated in proper initialization order
- X-macro headers (like `mruby/ops.h`) are inlined at each use
- Local includes (`.cstub` files) are automatically inlined
- Generated files (`mrblib.c`, `gem_init.c`) are included

### Gem Defines

Gems that add preprocessor defines affecting core structures are
automatically detected and included at the top of `mruby.h`.
Supported patterns: `MRB_USE_*`, `MRB_UTF8_*`, `HAVE_MRUBY_*`.

### Build Order

1. Core sources (`src/*.c`)
2. Gem sources (`mrbgems/*/src/*.c` or `core/*.c`)
3. Generated mrblib (`build/*/mrblib/mrblib.c`)
4. Gem initialization (`build/*/mrbgems/gem_init.c`)
Loading
Loading