From 0e44db114c67a83f24eafd0212d2efaac2c7b497 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 27 Mar 2026 22:36:03 +0900 Subject: [PATCH] build: add ports support for platform-specific gem sources Add conf.ports method to specify target platform tags (e.g., :esp32, :rp2040, :posix). Gems with matching ports// 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 --- lib/mruby/build.rb | 26 +++++++++++++++++++++++++- lib/mruby/gem.rb | 6 ++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/mruby/build.rb b/lib/mruby/build.rb index d5efea54b..effeccf3a 100644 --- a/lib/mruby/build.rb +++ b/lib/mruby/build.rb @@ -81,7 +81,7 @@ module MRuby include LoadGems attr_accessor :name, :bins, :exts, :file_separator, :build_dir, :gem_clone_dir, :defines, :libdir_name attr_reader :products, :libmruby_core_objs, :libmruby_objs, :gems, :toolchains, :presym, :mrbc_build, :gem_dir_to_repo_url - attr_reader :install_excludes + attr_reader :install_excludes, :port_names alias libmruby libmruby_objs @@ -138,6 +138,7 @@ module MRuby @mrbcfile_external = false @internal = internal @toolchains = [] + @port_names = nil @gem_dir_to_repo_url = {} # Add lambda instead of string because libdir_name or lib may be changed by user configuration @@ -183,6 +184,29 @@ module MRuby @enable_debug = true end + # Set target port names for this build. + # Gems with matching ports// directories will compile + # those platform-specific sources automatically. + # conf.ports :esp32 + # conf.ports :rp2040, :posix + def ports(*names) + @port_names = names.map { |n| n.to_s } + end + + # Returns the effective port names for this build. + # If not explicitly set, auto-detects :posix or :win for host builds. + def effective_ports + return @port_names if @port_names + if kind_of?(MRuby::CrossBuild) + [] + elsif ENV['OS'] == 'Windows_NT' || + ('A'..'Z').any? { |v| Dir.exist?("#{v}:") } + ['win'] + else + ['posix'] + end + end + def disable_lock @enable_lock = false end diff --git a/lib/mruby/gem.rb b/lib/mruby/gem.rb index abb9b71ac..b6d95dd5b 100644 --- a/lib/mruby/gem.rb +++ b/lib/mruby/gem.rb @@ -59,6 +59,12 @@ module MRuby @rbfiles = Dir.glob("#{@dir}/mrblib/**/*.rb").sort @objs = srcs_to_objs("src") + # Add platform-specific sources from ports// directories + build.effective_ports.each do |port| + port_dir = "#{@dir}/ports/#{port}" + @objs += srcs_to_objs("ports/#{port}") if File.directory?(port_dir) + end + @test_preload = nil # 'test/assert.rb' @test_args = {} @skip_test = false