67f137e201 introduced spec.hal_pattern on the target gem to
declare its expected HAL provider names. But the decision to
override is naturally an opt-in choice belonging to the external
HAL gem (or build_config), not the target. Drop hal_pattern and
hardcode the naming rule in resolve_external_hal!: a gem named
`hal-<short>-<conf>` overrides the gem whose last `-`-separated
segment is <short>. No spec attribute on the target gem; no flag
on add_dependency; the convention does all the work.
The pre-be6413f0d8 convention was `hal-<platform>-<gem>` (e.g.,
hal-posix-task) for platform sort across gems. Now that the
common platforms live under ports/, sorting by which target gem
a HAL is for is more useful, so the order is reversed:
`hal-<gem>-<conf>` (e.g., hal-task-glib).
ref #6825
Co-authored-by: Claude <noreply@anthropic.com>
A gem can declare
spec.hal_pattern = /\Ahal-.*-task\z/
to indicate that another gem whose name matches the pattern (and
which depends on this gem for headers) replaces the built-in
ports/<conf.ports>/ HAL implementation. After all gems are set
up, List#resolve_external_hal! drops the target's ports/* objs
from its object list so the matching gem supplies the HAL
symbols. Two or more matches is reported as a build error.
This restores the pre-be6413f0d8 ability to maintain an
out-of-tree HAL via add_dependency + naming convention, without
reintroducing the "HAL information scattered across gems"
problem: the parent gem still owns the scheduler, headers, and
bundled posix/win ports; external HAL gems are an explicit,
opt-in override.
Declare /\Ahal-.*-task\z/ for mruby-task -- the same naming
pattern used before be6413f0d8.
ref #6825
Co-authored-by: Claude <noreply@anthropic.com>
When `conf.ports` was given multiple names, every matching ports/
directory for each gem was compiled -- fine for single-name builds
and for gems that have at most one matching port, but a footgun
once HAL-using gems start providing multiple alternative ports
(e.g. mruby-task with both posix and an alternative runloop).
Iterate the chain and break on the first match. Existing builds
that pass at most one name per gem keep the same behavior;
`conf.ports :rp2040, :posix` now reads as "use rp2040 if a gem has
that port, otherwise posix" rather than "compile both".
ref #6825
Co-authored-by: Claude <noreply@anthropic.com>
The previous IO.popen capture of mrbc stdout (`-o-`) is vulnerable
to a Windows MinGW race: with parallel rake (-m), stdout pipe
inheritance can allow unrelated `_pp` build-progress messages from
sibling worker threads to leak into the captured pipe content,
corrupting the generated C file (recently seen as `CC build/...`
text inside gem_test.c, causing compile errors at unrelated lines).
Switch to `mrbc -o <tmpfile>` so the output is materialised in a
file before merging into the destination, fully isolating mrbc
from the parent's STDOUT.
Co-authored-by: Claude <noreply@anthropic.com>
Lets a gem author register a block that runs after the user's
`build.gem` block has been processed. Intended for filling in
defaults that depend on user-supplied configuration — for example,
library auto-detection that should only kick in when the user
hasn't explicitly chosen which library to use.
Initialization order is now:
1. block in MRuby::Gem::Specification.new (gem author defaults)
2. block in build.gem (user override)
3. block in post_user_config (gem author finalize, new)
Closes#6212, picked from PR by dearblue with the method renamed
from last_initializer to post_user_config (per matz's review).
Co-authored-by: Claude <noreply@anthropic.com>
Add conf.ports method to specify target platform tags (e.g.,
:esp32, :rp2040, :posix). Gems with matching ports/<name>/
directories will automatically compile those sources.
Host builds auto-detect :posix or :win when not explicitly set.
Cross builds require explicit specification. Existing gems
without ports/ directories are unaffected.
Co-authored-by: Claude <noreply@anthropic.com>
Replace separate float formatting (fmt_fp.c) and parsing (readfloat.c)
implementations with a unified fp_uscale.c using 128-bit unrounded
scaling. Both mrb_format_float() and mrb_read_float() now share a
single pow10 table and uscale() primitive for decimal/binary conversion.
This fixes subnormal parsing accuracy (old code returned 0.0 for the
smallest subnormals) and corrects %.2f rounding for values like
12345.125. Table size grows from ~5KB to ~11KB in .rodata.
Co-authored-by: Claude <noreply@anthropic.com>
Since presym is now always enabled, the @enable_presym flag,
presym_enabled? method, and all conditional branches guarding
presym-specific code paths are dead code. Remove them and
simplify the affected build logic.
Co-authored-by: Claude <noreply@anthropic.com>
Remove disable_presym from mrbc_build and cross-build fallback.
Add explicit object file dependencies on presym headers in
presym.rake to prevent compilation before headers are generated.
Co-authored-by: Claude <noreply@anthropic.com>
Gems like mruby-task add preprocessor defines (MRB_USE_TASK_SCHEDULER)
that affect mrb_state structure. The amalgamation generator now detects
these defines from the build configuration and adds them at the top of
mruby.h before struct definitions are encountered.
Supported define patterns: MRB_USE_*, MRB_UTF8_*, HAVE_MRUBY_*
Co-authored-by: Claude <noreply@anthropic.com>
Add ability to generate combined mruby.h and mruby.c files for
single-file embedding, similar to SQLite's amalgamation.
Usage: rake amalgam
Output: build/<target>/amalgam/mruby.{h,c}
Features:
- Headers concatenated in dependency order with guards stripped
- Sources concatenated with proper ordering (core, gems, mrblib)
- X-macro headers (ops.h) inlined at each include point
- Local includes automatically inlined
- Handles both src/ and core/ gem directory conventions
Co-authored-by: Claude <noreply@anthropic.com>
Headers in mrbgems are now categorized into three types:
- src/*.h: gem internal only
- include/*.h: inter-gem use (visible to dependent gems)
- include/export/*.h: external API (exported via mruby-config --cflags)
This prevents internal headers like *_hal.h from being exposed to
external users while maintaining inter-gem header accessibility.
Co-authored-by: Claude <noreply@anthropic.com>
Until now, GEMS added via `gem.add_dependency` retained the last `MRuby::Build.current` from the build configuration file, which was accessible from the top level of `mrbgem.rake`.
The issue resolved by the preceding patch was solely the C++ exception task within the mruby core.
This patch aims to resolve a similar sequencing issue that also exists in GEMS.
In practice, `mruby-compiler` is sometimes loaded via dependencies rather than being explicitly specified in the build configuration file.
In such cases, when `mruby-compiler/mrbgem.rake` is loaded, it is not yet determined whether C++ exceptions will be used. Consequently, even if it later becomes clear that `core/codegen-cxx.cxx` and `core/y.tab-cxx.cxx` are required, the system could not handle this.
To resolve this issue, we introduce the `MRuby::Gem::Specification#build_settings` method as a mechanism for lazily evaluating build setup.
However, for backward compatibility, the commands are cloned twice in `gem.setup` and `gem.setup_build`.
This is because many existing GEMS configure commands directly within the setup block.
ref. https://github.com/mruby/mruby/issues/6615
Until now, GEMs dependent on GEMs described in the build configuration file were loaded and set up after mruby core tasks were defined.
This caused an issue where, if C++ exceptions were enabled later by a dependent GEM, the necessary tasks for mruby core were not defined.
fixed https://github.com/mruby/mruby/issues/6615
Replace XML-style markup tags in comments with markdown equivalents:
- <code>...</code> to `...` (inline code)
- <tt>...</tt> to `...` (teletype/monospace)
- <i>...</i> to *...* (italics/emphasis)
- +...+ to `...` (parameter/variable references)
Updated 80+ files across core source, headers, mrbgems, and libraries
to use consistent markdown formatting in documentation comments.
Handled edge cases including special characters like <=> operators.
Co-authored-by: Atlassian Rovo Dev
Introduce the `MRuby::Build#install_excludes` attribute.
This attribute is an array to which you add strings, regular expressions, and proc objects that will serve as filters to exclude.
This feature was inspired by @hoshiumiarata's comment.
https://github.com/mruby/mruby/issues/6352#issuecomment-2426721517
```console
% find -s lib -type f -name '*.rb' -exec ruby -cw {} \;
lib/mruby/build/command.rb:320: warning: `+' after local variable or literal is interpreted as binary operator
lib/mruby/build/command.rb:320: warning: even though it seems like unary operator
Syntax OK
Syntax OK
Syntax OK
Syntax OK
Syntax OK
lib/mruby/gem.rb:469: warning: `&' interpreted as argument prefix
Syntax OK
Syntax OK
Syntax OK
Syntax OK
```
- Added the index number corresponding to the instruction code.
- Omitted trailing `|` from table elements.
The table elements in GitHub Flavored Markdown can't wrap wherever wanted.
And trying to align the end of it tends to make the whole thing longer.
Symbolic links were created with absolute paths, but to cope with path fluctuations between build and reference, they are now relative paths.
ref. #6084
In #6011, a hexadecimal escape sequence followed by a hexadecimal character would cause a compile error.
Also, avoid using "Numbered Parameter" which older Ruby does not have (e.g. AppVeyor).
ref. #6044
This is a complement to #5928.
The previous PR had the following problem:
- The `<INSTALL_DIR>/bin/*` file could not be replaced if the destination of the symbolic link was lost.
- The wrong link destination was written if `MRuby::Build.install_dir` was a relative path.
Previously, compiler flags were only added for GCC or similar.
The situation has not changed, but it has become easier to improve.
I expect `MRuby::Command::Compiler#setup_debug` to be defined as a singleton method inside the block given to `MRuby::Toolchain.new`.
Make the `mrb_init_mrbgems()` function do the cleanup and error handling.
Instead, simplify processing in the `GENERATED_TMP_mrb_XXX_gem_init()` function.
Previously, `mrb_load_irep()` or `mrb_load_proc()` would kill the process when an exception occurred.
With this patch, it is now caught by `mrb_core_init_protect()`.