Skip to content

Commit 0ca28b0

Browse files
build: Add experimental PIC support for WASI target
1 parent 150c74e commit 0ca28b0

File tree

8 files changed

+111
-15
lines changed

8 files changed

+111
-15
lines changed

lib/ruby_wasm/build/product/crossruby.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ def configure_args(build_triple, toolchain)
286286
xldflags = @xldflags.dup
287287

288288
args = self.system_triplet_args + ["--build", build_triple]
289-
args << "--with-static-linked-ext"
289+
args << "--with-static-linked-ext" unless @params.target.pic?
290290
args << %Q(--with-ext=#{default_exts})
291291
args << %Q(--with-libyaml-dir=#{@libyaml.install_root})
292292
args << %Q(--with-zlib-dir=#{@zlib.install_root})

lib/ruby_wasm/build/product/libyaml.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ def build(executor)
5858
"#{product_build_dir}/config/config.sub",
5959
"https://cdn.jsdelivr.net/gh/gcc-mirror/gcc@master/config.sub"
6060

61+
configure_args = self.configure_args.dup
62+
configure_args << "CFLAGS=-fPIC" if target.pic?
6163
executor.system "./configure", *configure_args, chdir: product_build_dir
6264
executor.system "make",
6365
"install",

lib/ruby_wasm/build/product/openssl.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ def configure_args
5252
-DHAVE_FORK=0
5353
]
5454
end
55+
56+
if @target.pic?
57+
args << "-fPIC"
58+
end
59+
5560
args + tools_args
5661
end
5762

lib/ruby_wasm/build/product/zlib.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ def build(executor)
5454
product_build_dir,
5555
"--strip-components=1"
5656

57+
configure_args = self.configure_args.dup
58+
configure_args << "CFLAGS=-fPIC" if target.pic?
5759
executor.system "env",
5860
*configure_args,
5961
"./configure",

lib/ruby_wasm/packager.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def package(executor, dest_dir, options)
3535
fs.remove_non_runtime_files(executor)
3636
fs.remove_stdlib(executor) unless options[:stdlib]
3737

38-
if full_build_options[:target] == "wasm32-unknown-wasi"
38+
if full_build_options[:target] == "wasm32-unknown-wasi" && !support_dynamic_linking?
3939
# wasi-vfs supports only WASI target
4040
wasi_vfs = RubyWasmExt::WasiVfs.new
4141
wasi_vfs.map_dir("/bundle", fs.bundle_dir)

lib/ruby_wasm/packager/core.rb

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,100 @@ def artifact
6161
end
6262

6363
class DynamicLinking < BuildStrategy
64+
def build(executor, options)
65+
build = derive_build
66+
force_rebuild =
67+
options[:remake] || options[:clean] || options[:reconfigure]
68+
if File.exist?(build.crossruby.artifact) && !force_rebuild
69+
return build.crossruby.artifact
70+
end
71+
build.crossruby.clean(executor) if options[:clean]
72+
73+
do_build =
74+
proc do
75+
build.crossruby.build(
76+
executor,
77+
remake: options[:remake],
78+
reconfigure: options[:reconfigure]
79+
)
80+
end
81+
82+
__skip__ =
83+
if defined?(Bundler)
84+
Bundler.with_unbundled_env(&do_build)
85+
else
86+
do_build.call
87+
end
88+
build.crossruby.artifact
89+
end
90+
91+
def build_exts(build)
92+
specs_with_extensions.flat_map do |spec, exts|
93+
exts.map do |ext|
94+
ext_feature = File.dirname(ext) # e.g. "ext/cgi/escape"
95+
ext_srcdir = File.join(spec.full_gem_path, ext_feature)
96+
ext_relative_path = File.join(spec.full_name, ext_feature)
97+
RubyWasm::CrossRubyExtProduct.new(
98+
ext_srcdir,
99+
build.toolchain,
100+
ext_relative_path: ext_relative_path
101+
)
102+
end
103+
end
104+
end
105+
106+
def cache_key(digest)
107+
derive_build.cache_key(digest)
108+
end
109+
110+
def artifact
111+
derive_build.crossruby.artifact
112+
end
113+
114+
def target
115+
RubyWasm::Target.new(@packager.full_build_options[:target], pic: true)
116+
end
117+
118+
def derive_build
119+
return @build if @build
120+
__skip__ =
121+
build ||= RubyWasm::Build.new(
122+
name, **@packager.full_build_options,
123+
target: target,
124+
# NOTE: We don't need linking libwasi_vfs because we use wasi-virt instead.
125+
wasi_vfs: nil
126+
)
127+
build.crossruby.cflags = %w[-fPIC -fvisibility=default]
128+
if @packager.full_build_options[:target] != "wasm32-unknown-emscripten"
129+
build.crossruby.debugflags = %w[-g]
130+
build.crossruby.wasmoptflags = %w[-O3 -g]
131+
build.crossruby.ldflags = %w[
132+
-Xlinker
133+
--stack-first
134+
-Xlinker
135+
-z
136+
-Xlinker
137+
stack-size=16777216
138+
]
139+
build.crossruby.xldflags = %w[
140+
-Xlinker -shared
141+
-Xlinker --export-dynamic
142+
-Xlinker --export-all
143+
-Xlinker --experimental-pic
144+
-Xlinker -export-if-defined=__main_argc_argv
145+
]
146+
end
147+
@build = build
148+
build
149+
end
150+
151+
def name
152+
require "digest"
153+
options = @packager.full_build_options
154+
src_channel = options[:src][:name]
155+
target_triplet = options[:target]
156+
"ruby-#{src_channel}-#{target_triplet}-pic#{options[:suffix]}"
157+
end
64158
end
65159

66160
class StaticLinking < BuildStrategy
@@ -100,7 +194,7 @@ def artifact
100194
end
101195

102196
def target
103-
RubyWasm::Target.new(@packager.full_build_options[:target], pic: true)
197+
RubyWasm::Target.new(@packager.full_build_options[:target])
104198
end
105199

106200
def derive_build

sig/ruby_wasm/build.rbs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -314,19 +314,9 @@ module RubyWasm
314314
end
315315

316316
class BuildTask
317-
@build_dir: String
318-
@rubies_dir: String
319-
@openssl: OpenSSLProduct
320-
317+
@build: Build
321318
attr_accessor name: String
322-
attr_reader source: BuildSource
323-
attr_reader target: String
324-
attr_reader toolchain: Toolchain
325-
attr_reader libyaml: LibYAMLProduct
326-
attr_reader zlib: ZlibProduct
327-
attr_reader wasi_vfs: WasiVfsProduct
328-
attr_reader baseruby: BaseRubyProduct
329-
attr_reader crossruby: CrossRubyProduct
319+
330320
def initialize: (String name, target: String, src: untyped, ?toolchain: Toolchain?, ?build_dir: String?, ?rubies_dir: String?, **untyped) -> void
331321
def hexdigest: -> String
332322
end

sig/ruby_wasm/packager.rbs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ class RubyWasm::Packager
6666
end
6767

6868
class DynamicLinking < RubyWasm::Packager::Core::BuildStrategy
69+
@build: RubyWasm::Build
70+
def derive_build: () -> RubyWasm::Build
71+
def name: () -> string
6972
end
7073

7174
class StaticLinking < RubyWasm::Packager::Core::BuildStrategy

0 commit comments

Comments
 (0)