From f22a991065ce614a74a69eccf36837e550135fa0 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 17 May 2026 06:57:54 +0900 Subject: [PATCH] build: pick first matching ports// per gem 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 --- lib/mruby/build.rb | 7 ++++--- lib/mruby/gem.rb | 10 ++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/mruby/build.rb b/lib/mruby/build.rb index effeccf3a..995611a4a 100644 --- a/lib/mruby/build.rb +++ b/lib/mruby/build.rb @@ -185,10 +185,11 @@ module MRuby end # Set target port names for this build. - # Gems with matching ports// directories will compile - # those platform-specific sources automatically. + # Each gem compiles the first matching ports// directory; + # later names in the list act as fallbacks for gems that don't + # ship a port for the earlier names. # conf.ports :esp32 - # conf.ports :rp2040, :posix + # conf.ports :rp2040, :posix # use rp2040 if available, else posix def ports(*names) @port_names = names.map { |n| n.to_s } end diff --git a/lib/mruby/gem.rb b/lib/mruby/gem.rb index c0fe806b4..4ad15da60 100644 --- a/lib/mruby/gem.rb +++ b/lib/mruby/gem.rb @@ -60,10 +60,16 @@ module MRuby @rbfiles = Dir.glob("#{@dir}/mrblib/**/*.rb").sort @objs = srcs_to_objs("src") - # Add platform-specific sources from ports// directories + # Add platform-specific sources from the first matching + # ports// directory. effective_ports is a fallback + # chain: later names act as defaults for gems that don't ship + # a port for the earlier names. build.effective_ports.each do |port| port_dir = "#{@dir}/ports/#{port}" - @objs += srcs_to_objs("ports/#{port}") if File.directory?(port_dir) + if File.directory?(port_dir) + @objs += srcs_to_objs("ports/#{port}") + break + end end @test_preload = nil # 'test/assert.rb'