ruby_wasm 2.5.0-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.clang-format +8 -0
  3. data/CONTRIBUTING.md +126 -0
  4. data/Gemfile +17 -0
  5. data/LICENSE +21 -0
  6. data/NOTICE +1293 -0
  7. data/README.md +153 -0
  8. data/Rakefile +163 -0
  9. data/Steepfile +24 -0
  10. data/benchmarks/vm_deep_call.rb +55 -0
  11. data/builders/wasm32-unknown-emscripten/Dockerfile +43 -0
  12. data/builders/wasm32-unknown-emscripten/entrypoint.sh +7 -0
  13. data/builders/wasm32-unknown-wasi/Dockerfile +47 -0
  14. data/builders/wasm32-unknown-wasi/entrypoint.sh +7 -0
  15. data/docs/api.md +2 -0
  16. data/docs/cheat_sheet.md +195 -0
  17. data/docs/faq.md +25 -0
  18. data/exe/rbwasm +7 -0
  19. data/ext/.gitignore +2 -0
  20. data/ext/README.md +11 -0
  21. data/ext/extinit.c.erb +32 -0
  22. data/lib/ruby_wasm/3.0/ruby_wasm.bundle +0 -0
  23. data/lib/ruby_wasm/3.1/ruby_wasm.bundle +0 -0
  24. data/lib/ruby_wasm/3.2/ruby_wasm.bundle +0 -0
  25. data/lib/ruby_wasm/build/build_params.rb +3 -0
  26. data/lib/ruby_wasm/build/downloader.rb +18 -0
  27. data/lib/ruby_wasm/build/executor.rb +187 -0
  28. data/lib/ruby_wasm/build/product/baseruby.rb +37 -0
  29. data/lib/ruby_wasm/build/product/crossruby.rb +330 -0
  30. data/lib/ruby_wasm/build/product/libyaml.rb +68 -0
  31. data/lib/ruby_wasm/build/product/openssl.rb +88 -0
  32. data/lib/ruby_wasm/build/product/product.rb +39 -0
  33. data/lib/ruby_wasm/build/product/ruby_source.rb +103 -0
  34. data/lib/ruby_wasm/build/product/wasi_vfs.rb +45 -0
  35. data/lib/ruby_wasm/build/product/zlib.rb +68 -0
  36. data/lib/ruby_wasm/build/product.rb +8 -0
  37. data/lib/ruby_wasm/build/toolchain/wit_bindgen.rb +31 -0
  38. data/lib/ruby_wasm/build/toolchain.rb +193 -0
  39. data/lib/ruby_wasm/build.rb +88 -0
  40. data/lib/ruby_wasm/cli.rb +217 -0
  41. data/lib/ruby_wasm/packager/core.rb +156 -0
  42. data/lib/ruby_wasm/packager/file_system.rb +158 -0
  43. data/lib/ruby_wasm/packager.rb +159 -0
  44. data/lib/ruby_wasm/rake_task.rb +59 -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 +33 -0
  48. data/package-lock.json +9500 -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 +151 -0
  56. data/rakelib/version.rake +40 -0
  57. data/sig/open_uri.rbs +4 -0
  58. data/sig/ruby_wasm/build.rbs +318 -0
  59. data/sig/ruby_wasm/cli.rbs +27 -0
  60. data/sig/ruby_wasm/ext.rbs +13 -0
  61. data/sig/ruby_wasm/packager.rbs +91 -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,330 @@
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 << "DESTDIR=#{crossruby.dest_dir}"
41
+ make_args
42
+ end
43
+
44
+ def build(executor, crossruby)
45
+ objdir = product_build_dir crossruby
46
+ executor.mkdir_p objdir
47
+ do_extconf executor, crossruby
48
+ executor.system "make",
49
+ "-j#{executor.process_count}",
50
+ "-C",
51
+ "#{objdir}",
52
+ *make_args(crossruby),
53
+ "static"
54
+ # A ext can provide link args by link.filelist. It contains only built archive file by default.
55
+ unless File.exist?(linklist(crossruby))
56
+ executor.write(
57
+ linklist(crossruby),
58
+ Dir.glob("#{objdir}/*.a").join("\n")
59
+ )
60
+ end
61
+ end
62
+
63
+ def do_extconf(executor, crossruby)
64
+ objdir = product_build_dir crossruby
65
+ source = crossruby.source
66
+ extconf_args = [
67
+ "--disable=gems",
68
+ # HACK: top_srcdir is required to find ruby headers
69
+ "-e",
70
+ %Q($top_srcdir="#{source.src_dir}"),
71
+ # HACK: extout is required to find config.h
72
+ "-e",
73
+ %Q($extout="#{crossruby.build_dir}/.ext"),
74
+ # HACK: skip have_devel check since ruby is not installed yet
75
+ "-e",
76
+ "$have_devel = true",
77
+ # HACK: force static ext build by imitating extmk
78
+ "-e",
79
+ "$static = true; trace_var(:$static) {|v| $static = true }",
80
+ # HACK: $0 should be extconf.rb path due to mkmf source file detection
81
+ # and we want to insert some hacks before it. But -e and $0 cannot be
82
+ # used together, so we rewrite $0 in -e.
83
+ "-e",
84
+ %Q($0="#{@srcdir}/extconf.rb"),
85
+ "-e",
86
+ %Q(require_relative "#{@srcdir}/extconf.rb"),
87
+ # HACK: extract "$target" from extconf.rb to get a full target name
88
+ # like "cgi/escape" instead of "escape"
89
+ "-e",
90
+ %Q(require "json"; File.write("#{metadata_json(crossruby)}", JSON.dump({target: $target}))),
91
+ "-I#{crossruby.build_dir}"
92
+ ]
93
+ # Clear RUBYOPT to avoid loading unrelated bundle setup
94
+ executor.system crossruby.baseruby_path,
95
+ *extconf_args,
96
+ chdir: objdir,
97
+ env: {
98
+ "RUBYOPT" => ""
99
+ }
100
+ end
101
+
102
+ def do_install_rb(executor, crossruby)
103
+ objdir = product_build_dir crossruby
104
+ executor.system "make", "-C", objdir, *make_args(crossruby), "install-rb"
105
+ end
106
+
107
+ def cache_key(digest)
108
+ digest << @name
109
+ # Compute hash value of files under srcdir
110
+ Dir
111
+ .glob("#{@srcdir}/**/*", File::FNM_DOTMATCH)
112
+ .each do |f|
113
+ next if File.directory?(f)
114
+ digest << f
115
+ digest << File.read(f)
116
+ end
117
+ end
118
+ end
119
+
120
+ class CrossRubyProduct < AutoconfProduct
121
+ attr_reader :source, :toolchain
122
+ attr_accessor :user_exts,
123
+ :wasmoptflags,
124
+ :cppflags,
125
+ :cflags,
126
+ :ldflags,
127
+ :debugflags,
128
+ :xcflags,
129
+ :xldflags
130
+
131
+ def initialize(params, build_dir, rubies_dir, baseruby, source, toolchain)
132
+ @params = params
133
+ @rubies_dir = rubies_dir
134
+ @build_dir = build_dir
135
+ @baseruby = baseruby
136
+ @source = source
137
+ @toolchain = toolchain
138
+ @user_exts = []
139
+ @wasmoptflags = []
140
+ @cppflags = []
141
+ @cflags = []
142
+ @ldflags = []
143
+ @debugflags = []
144
+ @xcflags = []
145
+ @xldflags = []
146
+ super(@params.target, @toolchain)
147
+ end
148
+
149
+ def configure(executor, reconfigure: false)
150
+ if !File.exist?("#{build_dir}/Makefile") || reconfigure
151
+ args = configure_args(RbConfig::CONFIG["host"], toolchain)
152
+ executor.system source.configure_file, *args, chdir: build_dir
153
+ end
154
+ # NOTE: we need rbconfig.rb at configuration time to build user given extensions with mkmf
155
+ executor.system "make", "rbconfig.rb", chdir: build_dir
156
+ end
157
+
158
+ def build_exts(executor)
159
+ @user_exts.each do |prod|
160
+ executor.begin_section prod.class, prod.name, "Building"
161
+ prod.build(executor, self)
162
+ executor.end_section prod.class, prod.name
163
+ end
164
+ end
165
+
166
+ def build(executor, remake: false, reconfigure: false)
167
+ executor.mkdir_p dest_dir
168
+ executor.mkdir_p build_dir
169
+ @toolchain.install
170
+ [@source, @baseruby, @libyaml, @zlib, @openssl, @wasi_vfs].each do |prod|
171
+ executor.begin_section prod.class, prod.name, "Building"
172
+ prod.build(executor)
173
+ executor.end_section prod.class, prod.name
174
+ end
175
+ executor.begin_section self.class, name, "Configuring"
176
+ configure(executor, reconfigure: reconfigure)
177
+ executor.end_section self.class, name
178
+
179
+ build_exts(executor)
180
+
181
+ executor.begin_section self.class, name, "Building"
182
+ executor.mkdir_p File.dirname(extinit_obj)
183
+ executor.system "ruby",
184
+ extinit_c_erb,
185
+ *@user_exts.map { |ext| ext.feature_name(self) },
186
+ "--cc",
187
+ toolchain.cc,
188
+ "--output",
189
+ extinit_obj
190
+ install_dir = File.join(build_dir, "install")
191
+ if !File.exist?(install_dir) || remake || reconfigure
192
+ executor.system "make",
193
+ "-j#{executor.process_count}",
194
+ "install",
195
+ "DESTDIR=#{install_dir}",
196
+ chdir: build_dir
197
+ end
198
+
199
+ executor.rm_rf dest_dir
200
+ executor.cp_r install_dir, dest_dir
201
+ @user_exts.each { |ext| ext.do_install_rb(executor, self) }
202
+ executor.system "tar", "cfz", artifact, "-C", @rubies_dir, name
203
+
204
+ executor.end_section self.class, name
205
+ end
206
+
207
+ def clean(executor)
208
+ executor.rm_rf dest_dir
209
+ executor.rm_rf build_dir
210
+ executor.rm_rf ext_build_dir
211
+ executor.rm_f artifact
212
+ end
213
+
214
+ def name
215
+ @params.name
216
+ end
217
+
218
+ def cache_key(digest)
219
+ digest << @params.target
220
+ digest << @params.default_exts
221
+ @wasmoptflags.each { |f| digest << f }
222
+ @cppflags.each { |f| digest << f }
223
+ @cflags.each { |f| digest << f }
224
+ @ldflags.each { |f| digest << f }
225
+ @debugflags.each { |f| digest << f }
226
+ @xcflags.each { |f| digest << f }
227
+ @xldflags.each { |f| digest << f }
228
+ @user_exts.each { |ext| ext.cache_key(digest) }
229
+ end
230
+
231
+ def build_dir
232
+ File.join(@build_dir, @params.target, name)
233
+ end
234
+
235
+ def ext_build_dir
236
+ File.join(@build_dir, @params.target, name + "-ext")
237
+ end
238
+
239
+ def with_libyaml(libyaml)
240
+ @libyaml = libyaml
241
+ end
242
+
243
+ def with_zlib(zlib)
244
+ @zlib = zlib
245
+ end
246
+
247
+ def with_wasi_vfs(wasi_vfs)
248
+ @wasi_vfs = wasi_vfs
249
+ end
250
+
251
+ def with_openssl(openssl)
252
+ @openssl = openssl
253
+ end
254
+
255
+ def dest_dir
256
+ File.join(@rubies_dir, name)
257
+ end
258
+
259
+ def artifact
260
+ File.join(@rubies_dir, "#{name}.tar.gz")
261
+ end
262
+
263
+ def extinit_obj
264
+ "#{ext_build_dir}/extinit.o"
265
+ end
266
+
267
+ def extinit_c_erb
268
+ lib_root = File.expand_path("../../../../..", __FILE__)
269
+ File.join(lib_root, "ext", "extinit.c.erb")
270
+ end
271
+
272
+ def baseruby_path
273
+ File.join(@baseruby.install_dir, "bin/ruby")
274
+ end
275
+
276
+ def configure_args(build_triple, toolchain)
277
+ target = @params.target
278
+ default_exts = @params.default_exts
279
+
280
+ ldflags = @ldflags.dup
281
+ xldflags = @xldflags.dup
282
+
283
+ args = self.system_triplet_args + ["--build", build_triple]
284
+ args << "--with-static-linked-ext"
285
+ args << %Q(--with-ext=#{default_exts})
286
+ args << %Q(--with-libyaml-dir=#{@libyaml.install_root})
287
+ args << %Q(--with-zlib-dir=#{@zlib.install_root})
288
+ args << %Q(--with-openssl-dir=#{@openssl.install_root}) if @openssl
289
+ args << %Q(--with-baseruby=#{baseruby_path})
290
+
291
+ case target
292
+ when "wasm32-unknown-wasi"
293
+ xldflags << @wasi_vfs.lib_wasi_vfs_a if @wasi_vfs
294
+ # TODO: Find a way to force cast or update API
295
+ # @type var wasi_sdk_path: untyped
296
+ wasi_sdk_path = @toolchain
297
+ args << %Q(WASMOPT=#{wasi_sdk_path.wasm_opt})
298
+ args << %Q(WASI_SDK_PATH=#{wasi_sdk_path.wasi_sdk_path})
299
+ when "wasm32-unknown-emscripten"
300
+ ldflags.concat(%w[-s MODULARIZE=1])
301
+ env_emcc_ldflags = ENV["RUBY_WASM_EMCC_LDFLAGS"] || ""
302
+ unless env_emcc_ldflags.empty?
303
+ ldflags << env_emcc_ldflags
304
+ end
305
+ else
306
+ raise "unknown target: #{target}"
307
+ end
308
+
309
+ args.concat(self.tools_args)
310
+ (@user_exts || []).each { |lib| xldflags << "@#{lib.linklist(self)}" }
311
+ xldflags << extinit_obj
312
+
313
+ xcflags = @xcflags.dup
314
+ xcflags << "-DWASM_SETJMP_STACK_BUFFER_SIZE=24576"
315
+ xcflags << "-DWASM_FIBER_STACK_BUFFER_SIZE=24576"
316
+ xcflags << "-DWASM_SCAN_STACK_BUFFER_SIZE=24576"
317
+
318
+ args << %Q(LDFLAGS=#{ldflags.join(" ")})
319
+ args << %Q(XLDFLAGS=#{xldflags.join(" ")})
320
+ args << %Q(XCFLAGS=#{xcflags.join(" ")})
321
+ args << %Q(debugflags=#{@debugflags.join(" ")})
322
+ args << %Q(cppflags=#{@cppflags.join(" ")})
323
+ unless wasmoptflags.empty?
324
+ args << %Q(wasmoptflags=#{@wasmoptflags.join(" ")})
325
+ end
326
+ args << "--disable-install-doc"
327
+ args
328
+ end
329
+ end
330
+ end
@@ -0,0 +1,68 @@
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, "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://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD"
56
+ executor.system "curl",
57
+ "-o",
58
+ "#{product_build_dir}/config/config.sub",
59
+ "https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD"
60
+
61
+ executor.system "./configure", *configure_args, chdir: product_build_dir
62
+ executor.system "make",
63
+ "install",
64
+ "DESTDIR=#{destdir}",
65
+ chdir: product_build_dir
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,88 @@
1
+ require_relative "./product"
2
+
3
+ module RubyWasm
4
+ class OpenSSLProduct < AutoconfProduct
5
+ attr_reader :target
6
+
7
+ OPENSSL_VERSION = "3.2.0"
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, "openssl-#{OPENSSL_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
+ "openssl-#{OPENSSL_VERSION}-#{target}"
29
+ end
30
+
31
+ def configure_args
32
+ args = %w[
33
+ gcc
34
+ -static
35
+ -no-asm
36
+ -no-threads
37
+ -no-afalgeng
38
+ -no-ui-console
39
+ -no-tests
40
+ -no-sock
41
+ -no-dgram
42
+ --libdir=lib
43
+ -Wl,--allow-undefined
44
+ ]
45
+ if @target == "wasm32-unknown-wasi"
46
+ args.concat %w[
47
+ -D_WASI_EMULATED_SIGNAL
48
+ -D_WASI_EMULATED_PROCESS_CLOCKS
49
+ -D_WASI_EMULATED_MMAN
50
+ -D_WASI_EMULATED_GETPID
51
+ -DNO_CHMOD
52
+ -DHAVE_FORK=0
53
+ ]
54
+ end
55
+ args + tools_args
56
+ end
57
+
58
+ def build(executor)
59
+ return if File.exist?(File.join(install_root, "lib", "libssl.a"))
60
+
61
+ executor.mkdir_p File.dirname(product_build_dir)
62
+ executor.rm_rf product_build_dir
63
+ executor.mkdir_p product_build_dir
64
+ tarball_path =
65
+ File.join(product_build_dir, "openssl-#{OPENSSL_VERSION}.tar.gz")
66
+ executor.system "curl",
67
+ "-o",
68
+ tarball_path,
69
+ "-L",
70
+ "https://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz"
71
+ executor.system "tar",
72
+ "xzf",
73
+ tarball_path,
74
+ "-C",
75
+ product_build_dir,
76
+ "--strip-components=1"
77
+
78
+ executor.system "./Configure", *configure_args, chdir: product_build_dir
79
+ # Use "install_sw" instead of "install" because it tries to install docs and it's very slow.
80
+ # OpenSSL build system doesn't have well support for parallel build, so force -j1.
81
+ executor.system "make",
82
+ "-j1",
83
+ "install_dev",
84
+ "DESTDIR=#{destdir}",
85
+ chdir: product_build_dir
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,39 @@
1
+ module RubyWasm
2
+ class BuildProduct
3
+ def name
4
+ raise NotImplementedError, "identifiable product name must be implemented"
5
+ end
6
+ end
7
+
8
+ class AutoconfProduct < BuildProduct
9
+ def initialize(target, toolchain)
10
+ @target = target
11
+ @toolchain = toolchain
12
+ end
13
+ def system_triplet_args
14
+ args = []
15
+ case @target
16
+ when "wasm32-unknown-wasi"
17
+ args.concat(%W[--host wasm32-wasi])
18
+ when "wasm32-unknown-emscripten"
19
+ args.concat(%W[--host wasm32-emscripten])
20
+ else
21
+ raise "unknown target: #{@target}"
22
+ end
23
+ args
24
+ end
25
+
26
+ def tools_args
27
+ args = []
28
+ args << "CC=#{@toolchain.cc}"
29
+ args << "LD=#{@toolchain.ld}"
30
+ args << "AR=#{@toolchain.ar}"
31
+ args << "RANLIB=#{@toolchain.ranlib}"
32
+ args
33
+ end
34
+
35
+ def configure_args
36
+ system_triplet_args + tools_args
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,103 @@
1
+ require_relative "./product"
2
+
3
+ module RubyWasm
4
+ class BuildSource < BuildProduct
5
+ def initialize(params, build_dir)
6
+ @params = params
7
+ @build_dir = build_dir
8
+ end
9
+
10
+ def name
11
+ @params[:name]
12
+ end
13
+
14
+ def cache_key(digest)
15
+ digest << @params[:type]
16
+ case @params[:type]
17
+ when "github"
18
+ digest << @params[:rev]
19
+ when "tarball"
20
+ digest << @params[:url]
21
+ when "local"
22
+ digest << File.mtime(@params[:src]).to_i.to_s
23
+ else
24
+ raise "unknown source type: #{@params[:type]}"
25
+ end
26
+ end
27
+
28
+ def src_dir
29
+ File.join(@build_dir, "checkouts", @params[:name])
30
+ end
31
+
32
+ def configure_file
33
+ File.join(src_dir, "configure")
34
+ end
35
+
36
+ def fetch(executor)
37
+ case @params[:type]
38
+ when "github"
39
+ repo_url = "https://github.com/#{@params[:repo]}.git"
40
+ executor.mkdir_p src_dir
41
+ executor.system "git", "init", chdir: src_dir
42
+ executor.system "git",
43
+ "remote",
44
+ "add",
45
+ "origin",
46
+ repo_url,
47
+ chdir: src_dir
48
+ executor.system(
49
+ "git",
50
+ "fetch",
51
+ "--depth",
52
+ "1",
53
+ "origin",
54
+ "#{@params[:rev]}:origin/#{@params[:rev]}",
55
+ chdir: src_dir
56
+ )
57
+ executor.system(
58
+ "git",
59
+ "checkout",
60
+ "origin/#{@params[:rev]}",
61
+ chdir: src_dir
62
+ )
63
+ when "tarball"
64
+ executor.mkdir_p src_dir
65
+ tarball_path =
66
+ File.join(File.dirname(src_dir), File.basename(src_dir) + ".tar.gz")
67
+ executor.system("curl", "-L", "-o", tarball_path, @params[:url])
68
+ executor.system(
69
+ "tar",
70
+ "xf",
71
+ tarball_path,
72
+ "-C",
73
+ src_dir,
74
+ "--strip-components=1"
75
+ )
76
+ when "local"
77
+ executor.mkdir_p File.dirname(src_dir)
78
+ executor.cp_r @params[:src], src_dir
79
+ else
80
+ raise "unknown source type: #{@params[:type]}"
81
+ end
82
+ (@params[:patches] || []).each do |patch_path|
83
+ executor.system "patch", "-p1", patch_path, chdir: src_dir
84
+ end
85
+ end
86
+
87
+ def build(executor)
88
+ fetch(executor) unless File.exist?(src_dir)
89
+ unless File.exist?(configure_file)
90
+ executor.system "ruby",
91
+ "tool/downloader.rb",
92
+ "-d",
93
+ "tool",
94
+ "-e",
95
+ "gnu",
96
+ "config.guess",
97
+ "config.sub",
98
+ chdir: src_dir
99
+ executor.system "./autogen.sh", chdir: src_dir
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,45 @@
1
+ require_relative "./product"
2
+
3
+ module RubyWasm
4
+ class WasiVfsProduct < BuildProduct
5
+ WASI_VFS_VERSION = "0.5.0"
6
+
7
+ def initialize(build_dir)
8
+ @build_dir = build_dir
9
+ @need_fetch_lib = ENV["LIB_WASI_VFS_A"].nil?
10
+ end
11
+
12
+ def lib_product_build_dir
13
+ File.join(
14
+ @build_dir,
15
+ "wasm32-unknown-wasi",
16
+ "wasi-vfs-#{WASI_VFS_VERSION}"
17
+ )
18
+ end
19
+
20
+ def lib_wasi_vfs_a
21
+ ENV["LIB_WASI_VFS_A"] || File.join(lib_product_build_dir, "libwasi_vfs.a")
22
+ end
23
+
24
+ def name
25
+ "wasi-vfs-#{WASI_VFS_VERSION}-#{RbConfig::CONFIG["host"]}"
26
+ end
27
+
28
+ def build(executor)
29
+ return if !@need_fetch_lib || File.exist?(lib_wasi_vfs_a)
30
+ require "tmpdir"
31
+ lib_wasi_vfs_url =
32
+ "https://github.com/kateinoigakukun/wasi-vfs/releases/download/v#{WASI_VFS_VERSION}/libwasi_vfs-wasm32-unknown-unknown.zip"
33
+ Dir.mktmpdir do |tmpdir|
34
+ executor.system "curl",
35
+ "-L",
36
+ lib_wasi_vfs_url,
37
+ "-o",
38
+ "#{tmpdir}/libwasi_vfs.zip"
39
+ executor.system "unzip", "#{tmpdir}/libwasi_vfs.zip", "-d", tmpdir
40
+ executor.mkdir_p File.dirname(lib_wasi_vfs_a)
41
+ executor.mv File.join(tmpdir, "libwasi_vfs.a"), lib_wasi_vfs_a
42
+ end
43
+ end
44
+ end
45
+ end