@@ -187,31 +187,41 @@ def _build_gem_exts(executor, build, gem_home)
187187 baseruby . build ( executor )
188188 end
189189
190- exts = specs_with_extensions . flat_map do |spec , exts |
191- exts . map do |ext |
192- ext_feature = File . dirname ( ext ) # e.g. "ext/cgi/escape"
193- ext_srcdir = File . join ( spec . full_gem_path , ext_feature )
194- ext_relative_path = File . join ( spec . full_name , ext_feature )
195- prod = RubyWasm ::CrossRubyExtProduct . new (
196- ext_srcdir ,
197- build . toolchain ,
198- features : @packager . features ,
199- ext_relative_path : ext_relative_path
200- )
201- [ prod , spec ]
202- end
203- end
190+ crossruby = build . crossruby
191+ rbconfig_rb = crossruby . rbconfig_rb
204192
205- exts . each do |prod , spec |
206- libdir = File . join ( gem_home , "gems" , spec . full_name , spec . raw_require_paths . first )
207- extra_mkargs = [
208- "sitearchdir=#{ libdir } " ,
209- "sitelibdir=#{ libdir } " ,
210- ]
211- executor . begin_section prod . class , prod . name , "Building"
212- prod . build ( executor , build . crossruby , extra_mkargs )
213- executor . end_section prod . class , prod . name
214- end
193+ options = @packager . full_build_options
194+ target_triplet = options [ :target ]
195+
196+ local_path = File . join ( "bundle" , target_triplet )
197+ env = {
198+ "BUNDLE_APP_CONFIG" => File . join ( ".bundle" , target_triplet ) ,
199+ "BUNDLE_PATH" => local_path ,
200+ "BUNDLE_WITHOUT" => "build" ,
201+ # FIXME: BUNDLE_PATH is set as a installation destination here, but
202+ # it is also used as a source of gems to be loaded by RubyGems itself.
203+ # RubyGems loads "psych" gem and if Gemfile includes "psych" gem,
204+ # RubyGems tries to load "psych" gem from BUNDLE_PATH at the second
205+ # time of "bundle install" command. But the extension of "psych" gem
206+ # under BUNDLE_PATH is built for Wasm target, not for host platform,
207+ # so it fails to load the extension.
208+ #
209+ # Thus we preload psych from the default LOAD_PATH here to avoid
210+ # loading Wasm version of psych.so via `Kernel#require` patched by
211+ # RubyGems.
212+ "RUBYOPT" => "-rpsych" ,
213+ }
214+
215+ args = [
216+ File . join ( baseruby . install_dir , "bin" , "bundle" ) ,
217+ "install" ,
218+ "--standalone" ,
219+ "--target-rbconfig" ,
220+ rbconfig_rb ,
221+ ]
222+
223+ executor . system ( *args , env : env )
224+ executor . cp_r ( local_path , gem_home )
215225 end
216226
217227 def cache_key ( digest )
0 commit comments