@@ -12,7 +12,7 @@ def build(executor, options)
1212
1313 extend Forwardable
1414
15- def_delegators :build_strategy , :cache_key , :artifact , :build_and_link_exts
15+ def_delegators :build_strategy , :cache_key , :artifact , :build_gem_exts , :link_gem_exts
1616
1717 private
1818
@@ -37,7 +37,11 @@ def build(executor, options)
3737 raise NotImplementedError
3838 end
3939
40- def build_and_link_exts ( executor , module_bytes )
40+ def build_gem_exts ( executor , gem_home )
41+ raise NotImplementedError
42+ end
43+
44+ def link_gem_exts ( executor , gem_home , module_bytes )
4145 raise NotImplementedError
4246 end
4347
@@ -93,13 +97,17 @@ def build(executor, options)
9397 build . crossruby . artifact
9498 end
9599
96- def build_and_link_exts ( executor , module_bytes )
100+ def build_gem_exts ( executor , gem_home )
97101 build = derive_build
98- self . build_exts ( executor , build )
99- self . link_exts ( executor , build )
102+ self . _build_gem_exts ( executor , build , gem_home )
100103 end
101104
102- def link_exts ( executor , build )
105+ def link_gem_exts ( executor , gem_home , module_bytes )
106+ build = derive_build
107+ self . _link_gem_exts ( executor , build , gem_home )
108+ end
109+
110+ def _link_gem_exts ( executor , build , gem_home )
103111 ruby_root = build . crossruby . dest_dir
104112
105113 libraries = [ File . join ( ruby_root , "usr" , "local" , "bin" , "ruby" ) ]
@@ -121,7 +129,10 @@ def link_exts(executor, build)
121129 end
122130 wasi_adapter = RubyWasm ::Packager ::ComponentAdapter . wasi_snapshot_preview1 ( "command" )
123131 adapters = [ wasi_adapter ]
124- dl_openable_libs = Dir . glob ( File . join ( ruby_root , "usr" , "local" , "lib" , "ruby" , "**" , "*.so" ) )
132+ dl_openable_libs = [ ]
133+ dl_openable_libs << [ File . join ( ruby_root , "usr" ) , Dir . glob ( File . join ( ruby_root , "usr" , "local" , "lib" , "ruby" , "**" , "*.so" ) ) ]
134+ dl_openable_libs << [ gem_home , Dir . glob ( File . join ( gem_home , "gems" , "**" , "*.so" ) ) ]
135+
125136 linker = RubyWasmExt ::ComponentLink . new
126137 linker . use_built_in_libdl ( true )
127138 linker . stub_missing_functions ( false )
@@ -135,12 +146,14 @@ def link_exts(executor, build)
135146 linker . library ( lib_name , module_bytes , false )
136147 end
137148
138- dl_openable_libs . each do |lib |
139- # DL openable lib_name should be a relative path from ruby_root
140- lib_name = "/" + Pathname . new ( lib ) . relative_path_from ( Pathname . new ( ruby_root ) ) . to_s
141- module_bytes = File . binread ( lib )
142- RubyWasm . logger . info "Linking #{ lib_name } (#{ module_bytes . size } bytes)"
143- linker . library ( lib_name , module_bytes , true )
149+ dl_openable_libs . each do |root , libs |
150+ libs . each do |lib |
151+ # DL openable lib_name should be a relative path from ruby_root
152+ lib_name = "/" + Pathname . new ( lib ) . relative_path_from ( Pathname . new ( File . dirname ( root ) ) ) . to_s
153+ module_bytes = File . binread ( lib )
154+ RubyWasm . logger . info "Linking #{ lib_name } (#{ module_bytes . size } bytes)"
155+ linker . library ( lib_name , module_bytes , true )
156+ end
144157 end
145158
146159 adapters . each do |adapter |
@@ -153,24 +166,30 @@ def link_exts(executor, build)
153166 return linker . encode ( )
154167 end
155168
156- def build_exts ( executor , build )
169+ def _build_gem_exts ( executor , build , gem_home )
157170 exts = specs_with_extensions . flat_map do |spec , exts |
158171 exts . map do |ext |
159172 ext_feature = File . dirname ( ext ) # e.g. "ext/cgi/escape"
160173 ext_srcdir = File . join ( spec . full_gem_path , ext_feature )
161174 ext_relative_path = File . join ( spec . full_name , ext_feature )
162- RubyWasm ::CrossRubyExtProduct . new (
175+ prod = RubyWasm ::CrossRubyExtProduct . new (
163176 ext_srcdir ,
164177 build . toolchain ,
165178 features : @packager . features ,
166179 ext_relative_path : ext_relative_path
167180 )
181+ [ prod , spec ]
168182 end
169183 end
170184
171- exts . each do |prod |
185+ exts . each do |prod , spec |
186+ libdir = File . join ( gem_home , "gems" , spec . full_name , spec . raw_require_paths . first )
187+ extra_mkargs = [
188+ "sitearchdir=#{ libdir } " ,
189+ "sitelibdir=#{ libdir } " ,
190+ ]
172191 executor . begin_section prod . class , prod . name , "Building"
173- prod . build ( executor , build . crossruby )
192+ prod . build ( executor , build . crossruby , extra_mkargs )
174193 executor . end_section prod . class , prod . name
175194 end
176195 end
@@ -301,7 +320,11 @@ def derive_build
301320 build
302321 end
303322
304- def build_and_link_exts ( executor , module_bytes )
323+ def build_gem_exts ( executor , gem_home )
324+ # No-op because we already built extensions as part of the Ruby build
325+ end
326+
327+ def link_gem_exts ( executor , gem_home , module_bytes )
305328 return module_bytes unless @packager . features . support_component_model?
306329
307330 linker = RubyWasmExt ::ComponentEncode . new
0 commit comments