Skip to content

build: ask the build too whether a cross target compiles without floats - #7238

Merged
matz merged 1 commit into
mruby:masterfrom
takumin:crossbuild-mrbc-defines
Aug 17, 2026
Merged

build: ask the build too whether a cross target compiles without floats#7238
matz merged 1 commit into
mruby:masterfrom
takumin:crossbuild-mrbc-defines

Conversation

@takumin

@takumin takumin commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Since #7230 a cross target borrows mrbc from a build that answers
MRB_NO_FLOAT the way it does, because src/load.c refuses a whole irep over
a single pool entry the target cannot represent. The question is asked of the
compiler alone, and a build config can write the define on the build instead:

MRuby::Build.new('host') do |conf|
  conf.toolchain
  conf.gem :core => 'mruby-bin-mrbc'
end

MRuby::CrossBuild.new('nofloat-build-define') do |conf|
  conf.toolchain
  conf.defines << 'MRB_NO_FLOAT'
  conf.gem :core => 'mruby-bin-mruby'
  conf.test_runner.command = 'env'
  conf.enable_test
end

Command::Compiler#all_flags puts build.defines on every command line
(lib/mruby/build/command.rb:96 on master):

      define_flags = [defines, internal_defines, _defines, build.defines].flatten

so the target compiles without floats while cc.has_define?('MRB_NO_FLOAT')
says it does not. It borrows the host, whose mrbc has floats, and that
mrbc writes a pool entry the target refuses to load.

rake -m test with the config above master this PR
the mrbc it compiles the tests with the host build's, floats enabled one generated for it, MRB_NO_FLOAT
where it stops irep load error, at load test/t/array.rb:65, at the literal
what that is the failure #7230 removed the behaviour #7230 merged

On master the target builds, and refuses its own test suite the moment a float
literal reaches it:

$ rake -m test
...
TEST for nofloat-build-define
mrbtest - Embeddable Ruby Test

.........(unknown):0: irep load error (ScriptError)
rake aborted!

With this patch the target gets a mrbc that answers as it does, which
refuses the float literal where it is written, the same place
build_config/no-float.rb stops:

$ rake -m test
...
test/t/array.rb:65: Not implemented: PM_FLOAT_NODE
test/t/array.rb:0:0: generator error, Not implemented: PM_FLOAT_NODE
rake aborted!

What this does

Read both lists a build config writes, the way Build#has_define? reads them.
Build#has_define? itself cannot be asked here: it refuses until the gems are
set up, and a cross build binds its mrbc as it is declared, which is why the
compiler was read directly in the first place.

The question moves into MRBC_DEFINES as well, which the comparison and the
defines a generated build carries now both read, so a second define that
decides what a pool entry may hold is one entry rather than three places.
src/load.c refusing IREP_TT_INT64 on an MRB_INT32 target is one candidate
and is left alone here: it is not a regression of this kind, and the mrbc a
cross target borrows follows the machine doing the building on integer width
today.

Verified

build config outcome
the config above the target gets nofloat-build-define/mrbc, and stops at the literal
a cross build and a host that agree unchanged, borrows the host
build_config/no-float.rb unchanged, stops at the same place
build_config/default.rb rake -m test, 2123 assertions, 0 KO

Environment

OS Linux 7.0.0-28-generic, x86_64
Compiler gcc 13.3.0
Ruby 4.0.6
rake 13.3.1

No C source changes, so .text is unaffected in every build.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JJf1R2cytz2gAnJ2CgpGp1

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility checks for generated and host compilation tools.
    • Ensured builds consistently apply relevant target configuration settings, including floating-point support options.

A cross target borrows `mrbc` from a build that answers `MRB_NO_FLOAT` the way
it does, because `src/load.c` refuses a whole irep over a pool entry the
target cannot represent. The question was asked of the compiler alone, and a
build config can write the define on the build:

```ruby
MRuby::CrossBuild.new('target') do |conf|
  conf.defines << 'MRB_NO_FLOAT'
end
```

`Command::Compiler#all_flags` puts `build.defines` on every command line, so
the target compiles without floats while `cc.has_define?` says it does not. It
borrowed a `host` that answers otherwise, and the `mrbc` of that host wrote a
float pool entry the target refused to load:

```console
$ rake -m test
.........(unknown):0: irep load error (ScriptError)
```

Read both lists, the way `Build#has_define?` reads them. `Build#has_define?`
itself cannot be asked here: it refuses until the gems are set up, and a cross
build binds its `mrbc` as it is declared.

The question also moves to `MRBC_DEFINES`, which the comparison and the
defines the generated build carries now both read, so a second define that
decides what a pool entry may hold is one entry rather than three places.
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6eacc069-e935-4746-85c8-17171f7f1447

📥 Commits

Reviewing files that changed from the base of the PR and between 2e26db9 and 68ff787.

📒 Files selected for processing (1)
  • lib/mruby/build.rb

Included review availability: Your plan includes up to 8 reviews per rolling hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

CrossBuild centralizes mrbc compatibility defines. Host mrbc reuse now compares all required defines. Generated mrbc builds receive the target defines through their compilers.

Changes

Cross-build mrbc compatibility

Layer / File(s) Summary
Centralize mrbc define handling
lib/mruby/build.rb
CrossBuild::MRBC_DEFINES lists required compatibility macros. Host mrbc binding compares the complete set. Generated mrbc builds receive matching compiler defines.

Estimated code review effort: 3 (Moderate) | ~15–30 minutes

Merge Risk: 🔵 Low · up to 68ff7

The change aligns the generated mrbc with build-level target defines, preventing incompatible float bytecode from reaching no-float targets. The bounded risk is compiler/target define misalignment in less-common cross-build configurations, so the change is mergeable with owner awareness.

Suggested reviewers: matz, dearblue

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: cross-build handling now checks whether the target compiles without floats.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@matz
matz merged commit b5bf964 into mruby:master Aug 17, 2026
21 checks passed
@takumin
takumin deleted the crossbuild-mrbc-defines branch August 17, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants