ruby_wasm 2.5.1-aarch64-linux-musl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.clang-format +8 -0
  3. data/CONTRIBUTING.md +128 -0
  4. data/Gemfile +17 -0
  5. data/LICENSE +21 -0
  6. data/NOTICE +1293 -0
  7. data/README.md +154 -0
  8. data/Rakefile +164 -0
  9. data/Steepfile +24 -0
  10. data/benchmarks/vm_deep_call.rb +55 -0
  11. data/docs/api.md +2 -0
  12. data/docs/cheat_sheet.md +195 -0
  13. data/docs/faq.md +25 -0
  14. data/exe/rbwasm +7 -0
  15. data/ext/.gitignore +2 -0
  16. data/ext/README.md +11 -0
  17. data/ext/extinit.c.erb +32 -0
  18. data/lib/ruby_wasm/3.1/ruby_wasm.so +0 -0
  19. data/lib/ruby_wasm/3.2/ruby_wasm.so +0 -0
  20. data/lib/ruby_wasm/3.3/ruby_wasm.so +0 -0
  21. data/lib/ruby_wasm/build/build_params.rb +3 -0
  22. data/lib/ruby_wasm/build/downloader.rb +18 -0
  23. data/lib/ruby_wasm/build/executor.rb +191 -0
  24. data/lib/ruby_wasm/build/product/baseruby.rb +37 -0
  25. data/lib/ruby_wasm/build/product/crossruby.rb +360 -0
  26. data/lib/ruby_wasm/build/product/libyaml.rb +70 -0
  27. data/lib/ruby_wasm/build/product/openssl.rb +93 -0
  28. data/lib/ruby_wasm/build/product/product.rb +39 -0
  29. data/lib/ruby_wasm/build/product/ruby_source.rb +103 -0
  30. data/lib/ruby_wasm/build/product/wasi_vfs.rb +45 -0
  31. data/lib/ruby_wasm/build/product/zlib.rb +70 -0
  32. data/lib/ruby_wasm/build/product.rb +8 -0
  33. data/lib/ruby_wasm/build/target.rb +24 -0
  34. data/lib/ruby_wasm/build/toolchain/wit_bindgen.rb +31 -0
  35. data/lib/ruby_wasm/build/toolchain.rb +193 -0
  36. data/lib/ruby_wasm/build.rb +92 -0
  37. data/lib/ruby_wasm/cli.rb +347 -0
  38. data/lib/ruby_wasm/packager/component_adapter/wasi_snapshot_preview1.command.wasm +0 -0
  39. data/lib/ruby_wasm/packager/component_adapter/wasi_snapshot_preview1.reactor.wasm +0 -0
  40. data/lib/ruby_wasm/packager/component_adapter.rb +14 -0
  41. data/lib/ruby_wasm/packager/core.rb +333 -0
  42. data/lib/ruby_wasm/packager/file_system.rb +160 -0
  43. data/lib/ruby_wasm/packager.rb +96 -0
  44. data/lib/ruby_wasm/rake_task.rb +60 -0
  45. data/lib/ruby_wasm/util.rb +15 -0
  46. data/lib/ruby_wasm/version.rb +3 -0
  47. data/lib/ruby_wasm.rb +34 -0
  48. data/package-lock.json +9777 -0
  49. data/package.json +12 -0
  50. data/rakelib/check.rake +37 -0
  51. data/rakelib/ci.rake +152 -0
  52. data/rakelib/doc.rake +29 -0
  53. data/rakelib/format.rake +35 -0
  54. data/rakelib/gem.rake +22 -0
  55. data/rakelib/packaging.rake +165 -0
  56. data/rakelib/version.rake +40 -0
  57. data/sig/open_uri.rbs +4 -0
  58. data/sig/ruby_wasm/build.rbs +327 -0
  59. data/sig/ruby_wasm/cli.rbs +51 -0
  60. data/sig/ruby_wasm/ext.rbs +26 -0
  61. data/sig/ruby_wasm/packager.rbs +122 -0
  62. data/sig/ruby_wasm/util.rbs +5 -0
  63. data/tools/clang-format-diff.sh +18 -0
  64. data/tools/exe/rbminify +12 -0
  65. data/tools/lib/syntax_tree/minify_ruby.rb +63 -0
  66. metadata +114 -0
@@ -0,0 +1,3 @@
1
+ module RubyWasm
2
+ BuildParams = Struct.new(:name, :target, :default_exts, keyword_init: true)
3
+ end
@@ -0,0 +1,18 @@
1
+ module RubyWasm
2
+ class Downloader
3
+ def download(url, dest, message)
4
+ require "open-uri"
5
+ content_length = 0
6
+ uri = URI.parse(url)
7
+ OpenURI.open_uri(
8
+ uri,
9
+ content_length_proc: ->(len) { content_length = len },
10
+ progress_proc: ->(size) do
11
+ print "\r#{message} (#{SizeFormatter.format(content_length)}) %.2f%%" %
12
+ (size.to_f / content_length * 100)
13
+ end
14
+ ) { |f| File.open(dest, "wb") { |out| out.write f.read } }
15
+ puts "\r"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,191 @@
1
+ module RubyWasm
2
+ # Build executor to run the actual build commands.
3
+ class BuildExecutor
4
+ attr_reader :process_count
5
+
6
+ def initialize(verbose: false, process_count: nil)
7
+ @verbose = verbose
8
+ @github_actions_markup = ENV["ENABLE_GITHUB_ACTIONS_MARKUP"] != nil
9
+ __skip__ =
10
+ begin
11
+ require "etc"
12
+ @process_count = process_count || Etc.nprocessors
13
+ rescue LoadError
14
+ @process_count = process_count || 1
15
+ end
16
+ end
17
+
18
+ def system(*args, chdir: nil, env: nil)
19
+ require "open3"
20
+
21
+ _print_command(args, env)
22
+
23
+ # @type var kwargs: Hash[Symbol, untyped]
24
+ kwargs = {}
25
+ kwargs[:chdir] = chdir if chdir
26
+
27
+ args = args.to_a.map(&:to_s)
28
+ # TODO: Remove __skip__ once we have open3 RBS definitions.
29
+ __skip__ =
30
+ if @verbose || !$stdout.tty?
31
+ kwargs[:exception] = true
32
+ if env
33
+ Kernel.system(env, *args, **kwargs)
34
+ else
35
+ Kernel.system(*args, **kwargs)
36
+ end
37
+ else
38
+ printer = StatusPrinter.new
39
+ block =
40
+ proc do |stdin, stdout, stderr, wait_thr|
41
+ mux = Mutex.new
42
+ out = String.new
43
+ err = String.new
44
+ readers =
45
+ [
46
+ [stdout, :stdout, out],
47
+ [stderr, :stderr, err]
48
+ ].map do |io, name, str|
49
+ reader =
50
+ Thread.new do
51
+ while (line = io.gets)
52
+ mux.synchronize do
53
+ printer.send(name, line)
54
+ str << line
55
+ end
56
+ end
57
+ end
58
+ reader.report_on_exception = false
59
+ reader
60
+ end
61
+
62
+ readers.each(&:join)
63
+
64
+ [out, err, wait_thr.value]
65
+ end
66
+ begin
67
+ stdout, stderr, status =
68
+ if env
69
+ Open3.popen3(env, *args, **kwargs, &block)
70
+ else
71
+ Open3.popen3(*args, **kwargs, &block)
72
+ end
73
+ unless status.success?
74
+ $stderr.puts stdout
75
+ $stderr.puts stderr
76
+ cmd_to_print = args.map { |a| "'#{a}'" }.join(" ")
77
+ raise "Command failed with status (#{status.exitstatus}): #{cmd_to_print}"
78
+ end
79
+ ensure
80
+ printer.done
81
+ end
82
+ end
83
+ return
84
+ rescue => e
85
+ $stdout.flush
86
+ $stderr.puts "Try running with `rake --verbose` for more complete output."
87
+ raise e
88
+ end
89
+
90
+ def begin_section(klass, name, note)
91
+ message = "\e[1;36m==>\e[0m \e[1m#{klass}(#{name}) -- #{note}\e[0m"
92
+ if @github_actions_markup
93
+ puts "::group::#{message}"
94
+ else
95
+ puts message
96
+ end
97
+
98
+ # Record the start time
99
+ @start_times ||= Hash.new
100
+ @start_times[[klass, name]] = Time.now
101
+
102
+ $stdout.flush
103
+ end
104
+
105
+ def end_section(klass, name)
106
+ took = Time.now - @start_times[[klass, name]]
107
+ puts "::endgroup::" if @github_actions_markup
108
+ puts "\e[1;36m==>\e[0m \e[1m#{klass}(#{name}) -- done in #{took.round(2)}s\e[0m"
109
+ end
110
+
111
+ def rm_rf(list)
112
+ FileUtils.rm_rf(list)
113
+ end
114
+
115
+ def rm_f(list)
116
+ FileUtils.rm_f(list)
117
+ end
118
+
119
+ def cp_r(src, dest)
120
+ FileUtils.cp_r(src, dest)
121
+ end
122
+
123
+ def mv(src, dest)
124
+ FileUtils.mv(src, dest)
125
+ end
126
+
127
+ def mkdir_p(list)
128
+ FileUtils.mkdir_p(list)
129
+ end
130
+
131
+ def ln_s(src, dest)
132
+ FileUtils.ln_s(src, dest)
133
+ end
134
+
135
+ def write(path, data)
136
+ File.write(path, data)
137
+ end
138
+
139
+ private
140
+
141
+ def _print_command(args, env)
142
+ require "shellwords"
143
+ # Bold cyan
144
+ print "\e[1;36m ==>\e[0m "
145
+ print "env " + env.map { |k, v| "#{k}=#{v}" }.join(" ") + " " if env
146
+ print args.map { |arg| Shellwords.escape(arg.to_s) }.join(" ") + "\n"
147
+ end
148
+ end
149
+
150
+ # Human readable status printer for the build.
151
+ class StatusPrinter
152
+ def initialize
153
+ @mutex = Mutex.new
154
+ @counter = 0
155
+ @indicators = "|/-\\"
156
+ end
157
+
158
+ def stdout(message)
159
+ require "io/console"
160
+ @mutex.synchronize do
161
+ $stdout.print "\e[K"
162
+ first_line = message.lines(chomp: true).first || ""
163
+
164
+ # Make sure we don't line-wrap the output
165
+ size =
166
+ __skip__ =
167
+ IO.respond_to?(:console_size) ? IO.console_size : IO.console.winsize
168
+ terminal_width = size[1].to_i.nonzero? || 80
169
+ width_limit = terminal_width / 2 - 3
170
+
171
+ if first_line.length > width_limit
172
+ first_line = (first_line[0..width_limit - 5] || "") + "..."
173
+ end
174
+ indicator = @indicators[@counter] || " "
175
+ to_print = " " + indicator + " " + first_line
176
+ $stdout.print to_print
177
+ $stdout.print "\e[1A\n"
178
+ @counter += 1
179
+ @counter = 0 if @counter >= @indicators.length
180
+ end
181
+ end
182
+
183
+ def stderr(message)
184
+ @mutex.synchronize { $stdout.print message }
185
+ end
186
+
187
+ def done
188
+ @mutex.synchronize { $stdout.print "\e[K" }
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,37 @@
1
+ require_relative "./product"
2
+
3
+ module RubyWasm
4
+ class BaseRubyProduct < BuildProduct
5
+ def initialize(build_dir, source)
6
+ @build_dir = build_dir
7
+ @source = source
8
+ @channel = source.name
9
+ end
10
+
11
+ def product_build_dir
12
+ File.join(@build_dir, RbConfig::CONFIG["host"], "baseruby-#{@channel}")
13
+ end
14
+
15
+ def install_dir
16
+ File.join(product_build_dir, "opt")
17
+ end
18
+
19
+ def name
20
+ "baseruby-#{@channel}"
21
+ end
22
+
23
+ def build(executor)
24
+ executor.mkdir_p product_build_dir
25
+ @source.build(executor)
26
+ return if Dir.exist?(install_dir)
27
+ executor.system @source.configure_file,
28
+ "--prefix=#{install_dir}",
29
+ "--disable-install-doc",
30
+ chdir: product_build_dir
31
+ executor.system "make",
32
+ "-j#{executor.process_count}",
33
+ "install",
34
+ chdir: product_build_dir
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,360 @@
1
+ require_relative "./product"
2
+ require "json"
3
+
4
+ module RubyWasm
5
+ class CrossRubyExtProduct < BuildProduct
6
+ attr_reader :name
7
+
8
+ def initialize(srcdir, toolchain, ext_relative_path: nil)
9
+ @srcdir, @toolchain = srcdir, toolchain
10
+ # ext_relative_path is relative path from build dir
11
+ # e.g. cgi-0.3.6/ext/cgi/escape
12
+ @ext_relative_path = ext_relative_path || File.basename(srcdir)
13
+ @name = @ext_relative_path
14
+ end
15
+
16
+ def product_build_dir(crossruby)
17
+ File.join(crossruby.ext_build_dir, @ext_relative_path)
18
+ end
19
+
20
+ def linklist(crossruby)
21
+ File.join(product_build_dir(crossruby), "link.filelist")
22
+ end
23
+
24
+ def metadata_json(crossruby)
25
+ File.join(product_build_dir(crossruby), "rbwasm.metadata.json")
26
+ end
27
+
28
+ def feature_name(crossruby)
29
+ metadata = JSON.parse(File.read(metadata_json(crossruby)))
30
+ metadata["target"]
31
+ end
32
+
33
+ def make_args(crossruby)
34
+ make_args = []
35
+ make_args << "CC=#{@toolchain.cc}"
36
+ make_args << "LD=#{@toolchain.ld}"
37
+ make_args << "AR=#{@toolchain.ar}"
38
+ make_args << "RANLIB=#{@toolchain.ranlib}"
39
+
40
+ make_args
41
+ end
42
+
43
+ def build(executor, crossruby)
44
+ objdir = product_build_dir crossruby
45
+ executor.mkdir_p objdir
46
+ do_extconf executor, crossruby
47
+
48
+ executor.system "make", "-C", objdir, *make_args(crossruby), "clean"
49
+ build_target = crossruby.target.pic? ? "install-so" : "static"
50
+ executor.system "make",
51
+ "-j#{executor.process_count}",
52
+ "-C",
53
+ "#{objdir}",
54
+ *make_args(crossruby),
55
+ build_target
56
+ # A ext can provide link args by link.filelist. It contains only built archive file by default.
57
+ unless File.exist?(linklist(crossruby))
58
+ executor.write(
59
+ linklist(crossruby),
60
+ Dir.glob("#{objdir}/*.a").join("\n")
61
+ )
62
+ end
63
+ end
64
+
65
+ def do_extconf(executor, crossruby)
66
+ unless crossruby.target.pic?
67
+ self.do_legacy_extconf(executor, crossruby)
68
+ return
69
+ end
70
+ objdir = product_build_dir crossruby
71
+ source = crossruby.source
72
+ rbconfig_rb = Dir.glob(File.join(crossruby.dest_dir, "usr/local/lib/ruby/*/wasm32-wasi/rbconfig.rb")).first
73
+ raise "rbconfig.rb not found" unless rbconfig_rb
74
+ extconf_args = [
75
+ "-C", objdir,
76
+ "#{@srcdir}/extconf.rb",
77
+ "--target-rbconfig=#{rbconfig_rb}",
78
+ ]
79
+ executor.system Gem.ruby, *extconf_args
80
+ end
81
+
82
+ def do_legacy_extconf(executor, crossruby)
83
+ objdir = product_build_dir crossruby
84
+ source = crossruby.source
85
+ extconf_args = [
86
+ "-C", objdir,
87
+ "--disable=gems",
88
+ # HACK: top_srcdir is required to find ruby headers
89
+ "-e",
90
+ %Q($top_srcdir="#{source.src_dir}"),
91
+ # HACK: extout is required to find config.h
92
+ "-e",
93
+ %Q($extout="#{crossruby.build_dir}/.ext"),
94
+ # HACK: force static ext build by imitating extmk
95
+ "-e",
96
+ "$static = true; trace_var(:$static) {|v| $static = true }",
97
+ # HACK: $0 should be extconf.rb path due to mkmf source file detection
98
+ # and we want to insert some hacks before it. But -e and $0 cannot be
99
+ # used together, so we rewrite $0 in -e.
100
+ "-e",
101
+ %Q($0="#{@srcdir}/extconf.rb"),
102
+ "-e",
103
+ %Q(require_relative "#{@srcdir}/extconf.rb"),
104
+ # HACK: extract "$target" from extconf.rb to get a full target name
105
+ # like "cgi/escape" instead of "escape"
106
+ "-e",
107
+ %Q(require "json"; File.write("#{metadata_json(crossruby)}", JSON.dump({target: $target}))),
108
+ "-I#{crossruby.build_dir}"
109
+ ]
110
+ # Clear RUBYOPT to avoid loading unrelated bundle setup
111
+ executor.system crossruby.baseruby_path,
112
+ *extconf_args,
113
+ env: {
114
+ "RUBYOPT" => ""
115
+ }
116
+ end
117
+
118
+ def do_install_rb(executor, crossruby)
119
+ objdir = product_build_dir crossruby
120
+ executor.system "make", "-C", objdir, *make_args(crossruby), "install-rb"
121
+ end
122
+
123
+ def cache_key(digest)
124
+ digest << @name
125
+ # Compute hash value of files under srcdir
126
+ Dir
127
+ .glob("#{@srcdir}/**/*", File::FNM_DOTMATCH)
128
+ .each do |f|
129
+ next if File.directory?(f)
130
+ digest << f
131
+ digest << File.read(f)
132
+ end
133
+ end
134
+ end
135
+
136
+ class CrossRubyProduct < AutoconfProduct
137
+ attr_reader :target, :source, :toolchain
138
+ attr_accessor :user_exts,
139
+ :wasmoptflags,
140
+ :cppflags,
141
+ :cflags,
142
+ :ldflags,
143
+ :debugflags,
144
+ :xcflags,
145
+ :xldflags
146
+
147
+ def initialize(params, build_dir, rubies_dir, baseruby, source, toolchain)
148
+ @params = params
149
+ @rubies_dir = rubies_dir
150
+ @build_dir = build_dir
151
+ @baseruby = baseruby
152
+ @source = source
153
+ @toolchain = toolchain
154
+ @user_exts = []
155
+ @wasmoptflags = []
156
+ @cppflags = []
157
+ @cflags = []
158
+ @ldflags = []
159
+ @debugflags = []
160
+ @xcflags = []
161
+ @xldflags = []
162
+ super(@params.target, @toolchain)
163
+ end
164
+
165
+ def configure(executor, reconfigure: false)
166
+ if !File.exist?("#{build_dir}/Makefile") || reconfigure
167
+ args = configure_args(RbConfig::CONFIG["host"], toolchain)
168
+ executor.system source.configure_file, *args, chdir: build_dir
169
+ end
170
+ # NOTE: we need rbconfig.rb at configuration time to build user given extensions with mkmf
171
+ executor.system "make", "rbconfig.rb", chdir: build_dir
172
+ end
173
+
174
+ def need_exts_build?
175
+ @user_exts.any?
176
+ end
177
+
178
+ def need_extinit_obj?
179
+ need_exts_build? && !@target.pic?
180
+ end
181
+
182
+ def build_exts(executor)
183
+ @user_exts.each do |prod|
184
+ executor.begin_section prod.class, prod.name, "Building"
185
+ prod.build(executor, self)
186
+ executor.end_section prod.class, prod.name
187
+ end
188
+ end
189
+
190
+ def build(executor, remake: false, reconfigure: false)
191
+ executor.mkdir_p dest_dir
192
+ executor.mkdir_p build_dir
193
+ @toolchain.install
194
+ [@source, @baseruby, @libyaml, @zlib, @openssl, @wasi_vfs].each do |prod|
195
+ next unless prod
196
+ executor.begin_section prod.class, prod.name, "Building"
197
+ prod.build(executor)
198
+ executor.end_section prod.class, prod.name
199
+ end
200
+ executor.begin_section self.class, name, "Configuring"
201
+ configure(executor, reconfigure: reconfigure)
202
+ executor.end_section self.class, name
203
+
204
+ build_exts(executor) if need_exts_build?
205
+
206
+ executor.begin_section self.class, name, "Building"
207
+
208
+ if need_extinit_obj?
209
+ executor.mkdir_p File.dirname(extinit_obj)
210
+ executor.system "ruby",
211
+ extinit_c_erb,
212
+ *@user_exts.map { |ext| ext.feature_name(self) },
213
+ "--cc",
214
+ toolchain.cc,
215
+ "--output",
216
+ extinit_obj
217
+ end
218
+ install_dir = File.join(build_dir, "install")
219
+ if !File.exist?(install_dir) || remake || reconfigure
220
+ executor.system "make",
221
+ "-j#{executor.process_count}",
222
+ "install",
223
+ "DESTDIR=#{install_dir}",
224
+ chdir: build_dir
225
+ end
226
+
227
+ executor.rm_rf dest_dir
228
+ executor.cp_r install_dir, dest_dir
229
+ @user_exts.each { |ext| ext.do_install_rb(executor, self) }
230
+ executor.system "tar", "cfz", artifact, "-C", @rubies_dir, name
231
+
232
+ executor.end_section self.class, name
233
+ end
234
+
235
+ def clean(executor)
236
+ executor.rm_rf dest_dir
237
+ executor.rm_rf build_dir
238
+ executor.rm_rf ext_build_dir
239
+ executor.rm_f artifact
240
+ end
241
+
242
+ def name
243
+ @params.name
244
+ end
245
+
246
+ def cache_key(digest)
247
+ @params.target.cache_key(digest)
248
+ digest << @params.default_exts
249
+ @wasmoptflags.each { |f| digest << f }
250
+ @cppflags.each { |f| digest << f }
251
+ @cflags.each { |f| digest << f }
252
+ @ldflags.each { |f| digest << f }
253
+ @debugflags.each { |f| digest << f }
254
+ @xcflags.each { |f| digest << f }
255
+ @xldflags.each { |f| digest << f }
256
+ @user_exts.each { |ext| ext.cache_key(digest) }
257
+ end
258
+
259
+ def build_dir
260
+ File.join(@build_dir, @params.target.to_s, name)
261
+ end
262
+
263
+ def ext_build_dir
264
+ File.join(@build_dir, @params.target.to_s, name + "-ext")
265
+ end
266
+
267
+ def with_libyaml(libyaml)
268
+ @libyaml = libyaml
269
+ end
270
+
271
+ def with_zlib(zlib)
272
+ @zlib = zlib
273
+ end
274
+
275
+ def with_wasi_vfs(wasi_vfs)
276
+ @wasi_vfs = wasi_vfs
277
+ end
278
+
279
+ def with_openssl(openssl)
280
+ @openssl = openssl
281
+ end
282
+
283
+ def dest_dir
284
+ File.join(@rubies_dir, name)
285
+ end
286
+
287
+ def artifact
288
+ File.join(@rubies_dir, "#{name}.tar.gz")
289
+ end
290
+
291
+ def extinit_obj
292
+ "#{ext_build_dir}/extinit.o"
293
+ end
294
+
295
+ def extinit_c_erb
296
+ lib_root = File.expand_path("../../../../..", __FILE__)
297
+ File.join(lib_root, "ext", "extinit.c.erb")
298
+ end
299
+
300
+ def baseruby_path
301
+ File.join(@baseruby.install_dir, "bin/ruby")
302
+ end
303
+
304
+ def configure_args(build_triple, toolchain)
305
+ target = @params.target.triple
306
+ default_exts = @params.default_exts
307
+
308
+ ldflags = @ldflags.dup
309
+ xldflags = @xldflags.dup
310
+
311
+ args = self.system_triplet_args + ["--build", build_triple]
312
+ args << "--with-static-linked-ext" unless @params.target.pic?
313
+ args << %Q(--with-ext=#{default_exts})
314
+ args << %Q(--with-libyaml-dir=#{@libyaml.install_root})
315
+ args << %Q(--with-zlib-dir=#{@zlib.install_root})
316
+ args << %Q(--with-openssl-dir=#{@openssl.install_root}) if @openssl
317
+ args << %Q(--with-baseruby=#{baseruby_path})
318
+
319
+ case target
320
+ when /^wasm32-unknown-wasi/
321
+ xldflags << @wasi_vfs.lib_wasi_vfs_a if @wasi_vfs
322
+ # TODO: Find a way to force cast or update API
323
+ # @type var wasi_sdk_path: untyped
324
+ wasi_sdk_path = @toolchain
325
+ args << %Q(WASMOPT=#{wasi_sdk_path.wasm_opt})
326
+ args << %Q(WASI_SDK_PATH=#{wasi_sdk_path.wasi_sdk_path})
327
+ when "wasm32-unknown-emscripten"
328
+ ldflags.concat(%w[-s MODULARIZE=1])
329
+ env_emcc_ldflags = ENV["RUBY_WASM_EMCC_LDFLAGS"] || ""
330
+ unless env_emcc_ldflags.empty?
331
+ ldflags << env_emcc_ldflags
332
+ end
333
+ else
334
+ raise "unknown target: #{target}"
335
+ end
336
+
337
+ args.concat(self.tools_args)
338
+ (@user_exts || []).each { |lib| xldflags << "@#{lib.linklist(self)}" }
339
+ xldflags << extinit_obj if need_extinit_obj?
340
+
341
+ cflags = @cflags.dup
342
+ xcflags = @xcflags.dup
343
+ xcflags << "-DWASM_SETJMP_STACK_BUFFER_SIZE=24576"
344
+ xcflags << "-DWASM_FIBER_STACK_BUFFER_SIZE=24576"
345
+ xcflags << "-DWASM_SCAN_STACK_BUFFER_SIZE=24576"
346
+
347
+ args << %Q(LDFLAGS=#{ldflags.join(" ")})
348
+ args << %Q(XLDFLAGS=#{xldflags.join(" ")})
349
+ args << %Q(CFLAGS=#{cflags.join(" ")})
350
+ args << %Q(XCFLAGS=#{xcflags.join(" ")})
351
+ args << %Q(debugflags=#{@debugflags.join(" ")})
352
+ args << %Q(cppflags=#{@cppflags.join(" ")})
353
+ unless wasmoptflags.empty?
354
+ args << %Q(wasmoptflags=#{@wasmoptflags.join(" ")})
355
+ end
356
+ args << "--disable-install-doc"
357
+ args
358
+ end
359
+ end
360
+ end
@@ -0,0 +1,70 @@
1
+ require_relative "./product"
2
+
3
+ module RubyWasm
4
+ class LibYAMLProduct < AutoconfProduct
5
+ attr_reader :target
6
+
7
+ LIBYAML_VERSION = "0.2.5"
8
+
9
+ def initialize(build_dir, target, toolchain)
10
+ @build_dir = build_dir
11
+ @target = target
12
+ super(target, toolchain)
13
+ end
14
+
15
+ def product_build_dir
16
+ File.join(@build_dir, target.to_s, "yaml-#{LIBYAML_VERSION}")
17
+ end
18
+
19
+ def destdir
20
+ File.join(product_build_dir, "opt")
21
+ end
22
+
23
+ def install_root
24
+ File.join(destdir, "usr", "local")
25
+ end
26
+
27
+ def name
28
+ "libyaml-#{LIBYAML_VERSION}-#{target}"
29
+ end
30
+
31
+ def build(executor)
32
+ return if Dir.exist?(install_root)
33
+
34
+ executor.mkdir_p File.dirname(product_build_dir)
35
+ executor.rm_rf product_build_dir
36
+ executor.mkdir_p product_build_dir
37
+ tarball_path =
38
+ File.join(product_build_dir, "libyaml-#{LIBYAML_VERSION}.tar.gz")
39
+ executor.system "curl",
40
+ "-o",
41
+ tarball_path,
42
+ "-L",
43
+ "https://github.com/yaml/libyaml/releases/download/#{LIBYAML_VERSION}/yaml-#{LIBYAML_VERSION}.tar.gz"
44
+ executor.system "tar",
45
+ "xzf",
46
+ tarball_path,
47
+ "-C",
48
+ product_build_dir,
49
+ "--strip-components=1"
50
+
51
+ # obtain the latest config.guess and config.sub for Emscripten and WASI triple support
52
+ executor.system "curl",
53
+ "-o",
54
+ "#{product_build_dir}/config/config.guess",
55
+ "https://cdn.jsdelivr.net/gh/gcc-mirror/gcc@master/config.guess"
56
+ executor.system "curl",
57
+ "-o",
58
+ "#{product_build_dir}/config/config.sub",
59
+ "https://cdn.jsdelivr.net/gh/gcc-mirror/gcc@master/config.sub"
60
+
61
+ configure_args = self.configure_args.dup
62
+ configure_args << "CFLAGS=-fPIC" if target.pic?
63
+ executor.system "./configure", *configure_args, chdir: product_build_dir
64
+ executor.system "make",
65
+ "install",
66
+ "DESTDIR=#{destdir}",
67
+ chdir: product_build_dir
68
+ end
69
+ end
70
+ end