ruby_wasm 2.7.2-x86_64-linux → 2.9.0-x86_64-linux

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8dba712de265137347381c0dda60772f2bdcaaa7f86d8533f5daa6fe87827473
4
- data.tar.gz: 8a1bff1fc0ef806eab846953cc236244b0a38ccb98e08839c92b22bf6f8685a3
3
+ metadata.gz: d7eb98187556c59db4ee513727126b7c3da415ebca81f796019d2c60fb6fd59f
4
+ data.tar.gz: 1500e3f933cab88615b88e8bf3063dcaa8508092406cdd6402d7e962aebb2e87
5
5
  SHA512:
6
- metadata.gz: 6463461470868c81e52bb7740c76095fbb50dcddca8f07d895cd259a6e819f55824cbaa5ba9ebe550a711bd12d422cb644922172eeefdb1acf41eca56e6369dd
7
- data.tar.gz: 1805cc8ec28ee3a0e80f33e13d8f21825a073b0d252b2a0d14fe93f14a3a538ffb0cd0be509b9e505899ef8c7194c15487412b1f09ac704cba58f299690076d7
6
+ metadata.gz: 93f6f95b4d79554438c99975927c269de85fbe93f7169087d1fc506814e46e056ac70106091dfc12566c33887d6ffd33139ee2c024c194a23ca0baa2f4dcab9c
7
+ data.tar.gz: b243611557df05f6504ff427801cfe4fa185bfb42d715b2951ac292795e0c7b768d39394e72702e5c76dad77bdd81ba036de7ef941f2727471cba5a2e7ea38fb
data/CONTRIBUTING.md CHANGED
@@ -129,7 +129,7 @@ $ npm install --save @ruby/wasm-wasi@latest
129
129
  # or if you want the nightly snapshot
130
130
  $ npm install --save @ruby/wasm-wasi@next
131
131
  # or you can specify the exact snapshot version
132
- $ npm install --save @ruby/wasm-wasi@2.7.2-2025-10-03-a
132
+ $ npm install --save @ruby/wasm-wasi@2.8.0-2025-12-29-a
133
133
  ```
134
134
 
135
135
 
@@ -138,7 +138,7 @@ $ npm install --save @ruby/wasm-wasi@2.7.2-2025-10-03-a
138
138
  When a new version of Ruby is released, the following steps need to be taken to add support for it in ruby.wasm:
139
139
 
140
140
  1. Update `lib/ruby_wasm/cli.rb`:
141
- - Add a new entry in the `build_source_aliases` method for the new version
141
+ - Add a new entry in the `build_config_aliases` method for the new version
142
142
  - Specify the tarball URL and required default extensions
143
143
 
144
144
  2. Update `Rakefile`:
data/Gemfile CHANGED
@@ -8,6 +8,7 @@ group :development do
8
8
  gem "rake"
9
9
  gem "rake-compiler"
10
10
  gem "rb_sys", "0.9.108"
11
+ gem "rdoc", "~> 7.0"
11
12
  end
12
13
 
13
14
  group :check do
data/README.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  [![Build ruby.wasm](https://github.com/ruby/ruby.wasm/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/ruby/ruby.wasm/actions/workflows/build.yml)
4
4
 
5
- ruby.wasm is a collection of WebAssembly ports of the [CRuby](https://github.com/ruby/ruby).
6
- It enables running Ruby application on browsers, WASI compatible WebAssembly runtimes, and Edge Computing platforms.
5
+ ruby.wasm is a collection of WebAssembly ports of [CRuby](https://github.com/ruby/ruby).
6
+ It enables running Ruby applications in browsers, WASI compatible WebAssembly runtimes, and Edge Computing platforms.
7
7
 
8
8
  ## Try ruby.wasm (no installation needed)
9
9
 
10
- Try ruby.wasm in [TryRuby](https://try.ruby-lang.org/playground#code=puts+RUBY_DESCRIPTION&engine=cruby-3.2.0dev) in your browser.
10
+ Try ruby.wasm on [TryRuby](https://try.ruby-lang.org/playground#code=puts+RUBY_DESCRIPTION&engine=cruby-3.2.0dev) in your browser.
11
11
 
12
12
  ## Quick Links
13
13
 
@@ -17,13 +17,13 @@ Try ruby.wasm in [TryRuby](https://try.ruby-lang.org/playground#code=puts+RUBY_D
17
17
  - [Complete Examples](https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-wasm-wasi/example)
18
18
  - [Community Showcase](https://github.com/ruby/ruby.wasm/wiki/Showcase)
19
19
 
20
- ## Quick Example: Ruby on Web browser
20
+ ## Quick Example: Ruby in a Web browser
21
21
 
22
- Create and save `index.html` page with the following contents:
22
+ Create and save an `index.html` page with the following contents:
23
23
 
24
24
  ```html
25
25
  <html>
26
- <script src="https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/browser.script.iife.js"></script>
26
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/browser.script.iife.js"></script>
27
27
  <script type="text/ruby">
28
28
  require "js"
29
29
 
@@ -40,18 +40,18 @@ Dependencies: [wasmtime](https://github.com/bytecodealliance/wasmtime)
40
40
  ```console
41
41
  $ gem install ruby_wasm
42
42
  # Download a prebuilt Ruby release
43
- $ curl -LO https://github.com/ruby/ruby.wasm/releases/latest/download/ruby-3.4-wasm32-unknown-wasip1-full.tar.gz
44
- $ tar xfz ruby-3.4-wasm32-unknown-wasip1-full.tar.gz
43
+ $ curl -LO https://github.com/ruby/ruby.wasm/releases/latest/download/ruby-4.0-wasm32-unknown-wasip1-full.tar.gz
44
+ $ tar xfz ruby-4.0-wasm32-unknown-wasip1-full.tar.gz
45
45
 
46
46
  # Extract ruby binary not to pack itself
47
- $ mv ruby-3.4-wasm32-unknown-wasip1-full/usr/local/bin/ruby ruby.wasm
47
+ $ mv ruby-4.0-wasm32-unknown-wasip1-full/usr/local/bin/ruby ruby.wasm
48
48
 
49
49
  # Put your app code
50
50
  $ mkdir src
51
51
  $ echo "puts 'Hello'" > src/my_app.rb
52
52
 
53
53
  # Pack the whole directory under /usr and your app dir
54
- $ rbwasm pack ruby.wasm --dir ./src::/src --dir ./ruby-3.4-wasm32-unknown-wasip1-full/usr::/usr -o my-ruby-app.wasm
54
+ $ rbwasm pack ruby.wasm --dir ./src::/src --dir ./ruby-4.0-wasm32-unknown-wasip1-full/usr::/usr -o my-ruby-app.wasm
55
55
 
56
56
  # Run the packed scripts
57
57
  $ wasmtime my-ruby-app.wasm /src/my_app.rb
@@ -71,6 +71,11 @@ See the `README.md` of each package for more detail and its usage.
71
71
  </tr>
72
72
  </thead>
73
73
  <tbody>
74
+ <tr>
75
+ <td><a href="/packages/npm-packages/ruby-4.0-wasm-wasi">@ruby/4.0-wasm-wasi</a></td>
76
+ <td>CRuby 4.0 built on WASI with JS interop support</td>
77
+ <td><a href="https://www.npmjs.com/package/@ruby/4.0-wasm-wasi" rel="nofollow"><img src="https://badge.fury.io/js/@ruby%2F4.0-wasm-wasi.svg" alt="npm version" style="max-width: 100%;"></a></td>
78
+ </tr>
74
79
  <tr>
75
80
  <td><a href="/packages/npm-packages/ruby-3.4-wasm-wasi">@ruby/3.4-wasm-wasi</a></td>
76
81
  <td>CRuby 3.4 built on WASI with JS interop support</td>
@@ -150,7 +155,7 @@ A _build_ is a combination of ruby version, _profile_, and _target_.
150
155
 
151
156
  The current WASI target build does not yet support `Thread` related APIs. Specifically, WASI does not yet have an API for creating and managing threads yet.
152
157
 
153
- Also there is no support for networking. It is one of the goal of WASI to support networking in the future, but it is not yet implemented.
158
+ Also there is no support for networking. It is one of the goals of WASI to support networking in the future, but it is not yet implemented.
154
159
 
155
160
 
156
161
  ## Contributing
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ require "ruby_wasm/rake_task"
9
9
  require "ruby_wasm/packager"
10
10
  require "ruby_wasm/cli"
11
11
 
12
- BUILD_SOURCES = %w[3.4 3.3 3.2 head]
12
+ BUILD_SOURCES = %w[4.0 3.4 3.3 3.2 head]
13
13
  BUILD_PROFILES = %w[full minimal]
14
14
 
15
15
  BUILDS =
@@ -29,14 +29,20 @@ NPM_PACKAGES = [
29
29
  name: "ruby-head-wasm-wasi",
30
30
  ruby_version: "head",
31
31
  gemfile: "packages/npm-packages/ruby-head-wasm-wasi/Gemfile",
32
- target: "wasm32-unknown-wasip1",
32
+ target: "wasm32-unknown-wasip1"
33
33
  },
34
34
  {
35
35
  name: "ruby-head-wasm-wasip2",
36
36
  ruby_version: "head",
37
37
  gemfile: "packages/npm-packages/ruby-head-wasm-wasip2/Gemfile",
38
38
  target: "wasm32-unknown-wasip2",
39
- enable_component_model: true,
39
+ enable_component_model: true
40
+ },
41
+ {
42
+ name: "ruby-4.0-wasm-wasi",
43
+ ruby_version: "4.0",
44
+ gemfile: "packages/npm-packages/ruby-4.0-wasm-wasi/Gemfile",
45
+ target: "wasm32-unknown-wasip1"
40
46
  },
41
47
  {
42
48
  name: "ruby-3.4-wasm-wasi",
@@ -66,16 +72,6 @@ STANDALONE_PACKAGES = [
66
72
 
67
73
  LIB_ROOT = File.dirname(__FILE__)
68
74
 
69
- TOOLCHAINS = {}
70
- BUILDS
71
- .map { |_, target, _| target }
72
- .uniq
73
- .each do |target|
74
- build_dir = File.join(LIB_ROOT, "build")
75
- toolchain = RubyWasm::Toolchain.get(target, build_dir)
76
- TOOLCHAINS[toolchain.name] = toolchain
77
- end
78
-
79
75
  class BuildTask < Struct.new(:name, :target, :build_command)
80
76
  def ruby_cache_key
81
77
  return @key if @key
data/docs/cheat_sheet.md CHANGED
@@ -8,10 +8,10 @@
8
8
 
9
9
  ## Node.js
10
10
 
11
- To install the package, install `@ruby/3.4-wasm-wasi` and `@ruby/wasm-wasi` from npm:
11
+ To install the package, install `@ruby/4.0-wasm-wasi` and `@ruby/wasm-wasi` from npm:
12
12
 
13
13
  ```console
14
- npm install --save @ruby/3.4-wasm-wasi @ruby/wasm-wasi
14
+ npm install --save @ruby/4.0-wasm-wasi @ruby/wasm-wasi
15
15
  ```
16
16
 
17
17
  Then instantiate a Ruby VM by the following code:
@@ -20,7 +20,7 @@ Then instantiate a Ruby VM by the following code:
20
20
  import fs from "fs/promises";
21
21
  import { DefaultRubyVM } from "@ruby/wasm-wasi/dist/node";
22
22
 
23
- const binary = await fs.readFile("./node_modules/@ruby/3.4-wasm-wasi/dist/ruby.wasm");
23
+ const binary = await fs.readFile("./node_modules/@ruby/4.0-wasm-wasi/dist/ruby.wasm");
24
24
  const module = await WebAssembly.compile(binary);
25
25
  const { vm } = await DefaultRubyVM(module);
26
26
  vm.eval(`puts "hello world"`);
@@ -38,7 +38,7 @@ The easiest way to run Ruby on browser is to use `browser.script.iife.js` script
38
38
 
39
39
  ```html
40
40
  <html>
41
- <script src="https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/browser.script.iife.js"></script>
41
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/browser.script.iife.js"></script>
42
42
  <script type="text/ruby">
43
43
  require "js"
44
44
  JS.global[:document].write "Hello, world!"
@@ -51,8 +51,8 @@ If you want to control Ruby VM from JavaScript, you can use `@ruby/wasm-wasi` pa
51
51
  ```html
52
52
  <html>
53
53
  <script type="module">
54
- import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.2/dist/browser/+esm";
55
- const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/ruby+stdlib.wasm");
54
+ import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.9.0/dist/browser/+esm";
55
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/ruby+stdlib.wasm");
56
56
  const module = await WebAssembly.compileStreaming(response);
57
57
  const { vm } = await DefaultRubyVM(module);
58
58
 
@@ -69,11 +69,11 @@ If you want to control Ruby VM from JavaScript, you can use `@ruby/wasm-wasi` pa
69
69
 
70
70
  ```html
71
71
  <html>
72
- <script src="https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.2/dist/browser.umd.js"></script>
72
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.9.0/dist/browser.umd.js"></script>
73
73
  <script>
74
74
  const main = async () => {
75
75
  const { DefaultRubyVM } = window["ruby-wasm-wasi"];
76
- const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/ruby+stdlib.wasm");
76
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/ruby+stdlib.wasm");
77
77
  const module = await WebAssembly.compileStreaming(response);
78
78
  const { vm } = await DefaultRubyVM(module);
79
79
 
@@ -128,7 +128,7 @@ end
128
128
 
129
129
  ```html
130
130
  <html>
131
- <script src="https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/browser.script.iife.js"></script>
131
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/browser.script.iife.js"></script>
132
132
  <script type="text/ruby" data-eval="async">
133
133
  require "js"
134
134
 
@@ -143,8 +143,8 @@ Or using `@ruby/wasm-wasi` package API `RubyVM#evalAsync`:
143
143
  ```html
144
144
  <html>
145
145
  <script type="module">
146
- import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.2/dist/browser/+esm";
147
- const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/ruby+stdlib.wasm");
146
+ import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.9.0/dist/browser/+esm";
147
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/ruby+stdlib.wasm");
148
148
  const module = await WebAssembly.compileStreaming(response);
149
149
  const { vm } = await DefaultRubyVM(module);
150
150
 
data/docs/faq.md CHANGED
@@ -6,9 +6,9 @@
6
6
 
7
7
  # FAQ
8
8
 
9
- ## Where my `puts` output goes?
9
+ ## Where does my `puts` output go?
10
10
 
11
- By default, `puts` output goes to `STDOUT` which is a JavaScript `console.log` function. You can override it by setting `$stdout` to a Ruby object which has `write` method.
11
+ By default, `puts` output goes to `STDOUT` which is a JavaScript `console.log` function. You can override it by setting `$stdout` to a Ruby object which has a `write` method.
12
12
 
13
13
  ```ruby
14
14
  $stdout = Object.new.tap do |obj|
Binary file
Binary file
Binary file
@@ -147,6 +147,16 @@ module RubyWasm
147
147
  end
148
148
  end
149
149
 
150
+ class SilentExecutor
151
+ def system(*args, chdir: nil, env: nil)
152
+ # @type var kwargs: Hash[Symbol, untyped]
153
+ kwargs = {}
154
+ kwargs[:chdir] = chdir if chdir
155
+ kwargs[:exception] = true
156
+ __skip__ = env ? Kernel.system(env, *args, **kwargs) : Kernel.system(*args, **kwargs)
157
+ end
158
+ end
159
+
150
160
  # Human readable status printer for the build.
151
161
  class StatusPrinter
152
162
  def initialize
@@ -204,7 +204,7 @@ module RubyWasm
204
204
  def build(executor, remake: false, reconfigure: false)
205
205
  executor.mkdir_p dest_dir
206
206
  executor.mkdir_p build_dir
207
- @toolchain.install
207
+ @toolchain.install(executor)
208
208
  [@source, @baseruby, @libyaml, @zlib, @openssl, @wasi_vfs].each do |prod|
209
209
  next unless prod
210
210
  executor.begin_section prod.class, prod.name, "Building"
@@ -322,6 +322,10 @@ module RubyWasm
322
322
  File.join(@baseruby.install_dir, "bin/ruby")
323
323
  end
324
324
 
325
+ def dump_ast_path
326
+ File.join(@baseruby.product_build_dir, "dump_ast")
327
+ end
328
+
325
329
  def configure_args(build_triple, toolchain)
326
330
  target = @params.target.triple
327
331
  default_exts = @params.default_exts
@@ -336,6 +340,9 @@ module RubyWasm
336
340
  args << %Q(--with-zlib-dir=#{@zlib.install_root})
337
341
  args << %Q(--with-openssl-dir=#{@openssl.install_root}) if @openssl
338
342
  args << %Q(--with-baseruby=#{baseruby_path})
343
+ # Use the host-built dump_ast so cross builds don't try to execute the
344
+ # target-side wasm dump_ast while generating .rbinc files.
345
+ args << %Q(--with-dump-ast=#{dump_ast_path})
339
346
 
340
347
  case target
341
348
  when /^wasm32-unknown-wasi/
@@ -345,6 +352,17 @@ module RubyWasm
345
352
  wasi_sdk_path = @toolchain
346
353
  args << %Q(WASMOPT=#{wasi_sdk_path.wasm_opt})
347
354
  args << %Q(WASI_SDK_PATH=#{wasi_sdk_path.wasi_sdk_path})
355
+ # NOTE: wasi-libc 22 and later defines stubs for fchmod and chmod
356
+ # but they just return ENOTSUP, and ruby's configure doesn't check
357
+ # the runtime behavior. So we need to tell configure that
358
+ # these functions are not available.
359
+ # https://github.com/WebAssembly/wasi-libc/pull/463
360
+ args << %Q(ac_cv_func_fchmod=no)
361
+ args << %Q(ac_cv_func_chmod=no)
362
+ # TODO: wasi-libc 22 and later started using musl's realpath impl but
363
+ # it broke Kernel#require on @bjorn3/browser_wasi_shim setup for some
364
+ # reason. So we disable it for now.
365
+ args << %Q(ac_cv_func_realpath=no)
348
366
  when "wasm32-unknown-emscripten"
349
367
  ldflags.concat(%w[-s MODULARIZE=1])
350
368
  env_emcc_ldflags = ENV["RUBY_WASM_EMCC_LDFLAGS"] || ""
@@ -16,10 +16,15 @@ module RubyWasm
16
16
  raise "missing environment variable: #{name}" if ENV[name].nil?
17
17
  end
18
18
 
19
- def self.get(target, build_dir = nil)
19
+ def self.get(target, options, build_dir = nil)
20
20
  case target
21
21
  when /^wasm32-unknown-wasi/
22
- return RubyWasm::WASISDK.new(build_dir: build_dir)
22
+ return(
23
+ RubyWasm::WASISDK.new(
24
+ build_dir: build_dir,
25
+ version: options[:wasi_sdk_version]
26
+ )
27
+ )
23
28
  when "wasm32-unknown-emscripten"
24
29
  return RubyWasm::Emscripten.new
25
30
  else
@@ -56,32 +61,24 @@ module RubyWasm
56
61
  def initialize(
57
62
  wasi_sdk_path = ENV["WASI_SDK_PATH"],
58
63
  build_dir: nil,
59
- version_major: 21,
60
- version_minor: 0,
64
+ version: "23.0",
61
65
  binaryen_version: 108
62
66
  )
63
- @wasm_opt_path = Toolchain.find_path("wasm-opt")
64
67
  @need_fetch_wasi_sdk = wasi_sdk_path.nil?
65
- @need_fetch_binaryen = @wasm_opt_path.nil?
66
-
67
68
  if @need_fetch_wasi_sdk
68
69
  if build_dir.nil?
69
70
  raise "build_dir is required when WASI_SDK_PATH is not set"
70
71
  end
71
- wasi_sdk_path = File.join(build_dir, "toolchain", "wasi-sdk")
72
- @version_major = version_major
73
- @version_minor = version_minor
74
- end
75
-
76
- if @need_fetch_binaryen
77
- if build_dir.nil?
78
- raise "build_dir is required when wasm-opt not installed in PATH"
72
+ wasi_sdk_path = File.join(build_dir, "toolchain", "wasi-sdk-#{version}")
73
+ if version.nil?
74
+ raise "version is required when WASI_SDK_PATH is not set"
79
75
  end
80
- @binaryen_path = File.join(build_dir, "toolchain", "binaryen")
81
- @binaryen_version = binaryen_version
82
- @wasm_opt_path = File.join(@binaryen_path, "bin", "wasm-opt")
76
+ @version = version
83
77
  end
84
78
 
79
+ @binaryen =
80
+ Binaryen.new(build_dir: build_dir, binaryen_version: binaryen_version)
81
+
85
82
  @tools = {
86
83
  cc: "#{wasi_sdk_path}/bin/clang",
87
84
  cxx: "#{wasi_sdk_path}/bin/clang++",
@@ -101,27 +98,127 @@ module RubyWasm
101
98
  end
102
99
 
103
100
  def wasm_opt
104
- @wasm_opt_path
101
+ @binaryen.wasm_opt
105
102
  end
106
103
 
107
104
  def wasi_sdk_path
108
105
  @wasi_sdk_path
109
106
  end
110
107
 
111
- def download_url(version_major, version_minor)
112
- version = "#{version_major}.#{version_minor}"
108
+ def download_url
109
+ major, _ = @version.split(".").map(&:to_i)
110
+ # @type var assets: Array[[Regexp, Array[String]]]
113
111
  assets = [
114
- [/x86_64-linux/, "wasi-sdk-#{version}-linux.tar.gz"],
115
- [/(arm64e?|x86_64)-darwin/, "wasi-sdk-#{version}-macos.tar.gz"]
112
+ [
113
+ /x86_64-linux/,
114
+ [
115
+ "wasi-sdk-#{@version}-x86_64-linux.tar.gz",
116
+ # For wasi-sdk version < 23.0
117
+ "wasi-sdk-#{@version}-linux.tar.gz"
118
+ ]
119
+ ],
120
+ [
121
+ /arm64e?-darwin/,
122
+ [
123
+ "wasi-sdk-#{@version}-arm64-macos.tar.gz",
124
+ # For wasi-sdk version < 23.0
125
+ "wasi-sdk-#{@version}-macos.tar.gz"
126
+ ]
127
+ ],
128
+ [
129
+ /x86_64-darwin/,
130
+ [
131
+ "wasi-sdk-#{@version}-x86_64-macos.tar.gz",
132
+ # For wasi-sdk version < 23.0
133
+ "wasi-sdk-#{@version}-macos.tar.gz"
134
+ ]
135
+ ]
116
136
  ]
117
- asset = assets.find { |os, _| os =~ RUBY_PLATFORM }&.at(1)
137
+ asset = assets.find { |os, candidates| os =~ RUBY_PLATFORM }
118
138
  if asset.nil?
119
139
  raise "unsupported platform for fetching WASI SDK: #{RUBY_PLATFORM}"
120
140
  end
121
- "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-#{version_major}/#{asset}"
141
+ _, candidates = asset
142
+ candidates_urls =
143
+ candidates.map do |candidate|
144
+ "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-#{major}/#{candidate}"
145
+ end
146
+ require "net/http"
147
+ # Find an asset that exists by checking HEAD response to see if the asset exists
148
+ candidates_urls.each do |url_str|
149
+ # @type var url: URI::HTTPS
150
+ url = URI.parse(url_str)
151
+ ok =
152
+ __skip__ = Net::HTTP.start(
153
+ url.host,
154
+ url.port,
155
+ use_ssl: url.scheme == "https"
156
+ ) do |http|
157
+ response = http.head(url.request_uri)
158
+ next response.code == "302"
159
+ end
160
+ return url_str if ok
161
+ end
162
+ raise "WASI SDK asset not found: #{candidates_urls.join(", ")}"
163
+ end
164
+
165
+ def install_wasi_sdk(executor)
166
+ return unless @need_fetch_wasi_sdk
167
+ wasi_sdk_tarball =
168
+ File.join(File.dirname(@wasi_sdk_path), "wasi-sdk-#{@version}.tar.gz")
169
+ unless File.exist? wasi_sdk_tarball
170
+ FileUtils.mkdir_p File.dirname(wasi_sdk_tarball)
171
+ executor.system "curl",
172
+ "-fsSL",
173
+ "-o",
174
+ wasi_sdk_tarball,
175
+ self.download_url
176
+ end
177
+ unless File.exist? @wasi_sdk_path
178
+ FileUtils.mkdir_p @wasi_sdk_path
179
+ executor.system "tar",
180
+ "-C",
181
+ @wasi_sdk_path,
182
+ "--strip-component",
183
+ "1",
184
+ "-xzf",
185
+ wasi_sdk_tarball
186
+ end
187
+ end
188
+
189
+ def install(executor)
190
+ install_wasi_sdk(executor)
191
+ @binaryen.install(executor)
192
+ end
193
+ end
194
+
195
+ class Binaryen
196
+ def initialize(build_dir: nil, binaryen_version: 108)
197
+ @wasm_opt_path = Toolchain.find_path("wasm-opt")
198
+ @need_fetch_binaryen = @wasm_opt_path.nil?
199
+ if @need_fetch_binaryen
200
+ if build_dir.nil?
201
+ raise "build_dir is required when wasm-opt not installed in PATH"
202
+ end
203
+ @binaryen_path = File.join(build_dir, "toolchain", "binaryen")
204
+ @binaryen_version = binaryen_version
205
+ @wasm_opt_path = File.join(@binaryen_path, "bin", "wasm-opt")
206
+ end
207
+ end
208
+
209
+ def wasm_opt
210
+ @wasm_opt_path
122
211
  end
123
212
 
124
- def binaryen_download_url(version)
213
+ def binaryen_path
214
+ @binaryen_path
215
+ end
216
+
217
+ def binaryen_version
218
+ @binaryen_version
219
+ end
220
+
221
+ def download_url(version)
125
222
  assets = [
126
223
  [
127
224
  /x86_64-linux/,
@@ -143,47 +240,44 @@ module RubyWasm
143
240
  "https://github.com/WebAssembly/binaryen/releases/download/version_#{@binaryen_version}/#{asset}"
144
241
  end
145
242
 
146
- def install_wasi_sdk
147
- return unless @need_fetch_wasi_sdk
148
- wasi_sdk_tarball =
149
- File.join(File.dirname(@wasi_sdk_path), "wasi-sdk.tar.gz")
150
- unless File.exist? wasi_sdk_tarball
151
- FileUtils.mkdir_p File.dirname(wasi_sdk_tarball)
152
- system "curl -L -o #{wasi_sdk_tarball} #{self.download_url(@version_major, @version_minor)}"
153
- end
154
- unless File.exist? @wasi_sdk_path
155
- FileUtils.mkdir_p @wasi_sdk_path
156
- system "tar -C #{@wasi_sdk_path} --strip-component 1 -xzf #{wasi_sdk_tarball}"
157
- end
158
- end
159
-
160
- def install_binaryen
243
+ def install(executor)
161
244
  return unless @need_fetch_binaryen
162
245
  binaryen_tarball = File.expand_path("../binaryen.tar.gz", @binaryen_path)
163
246
  unless File.exist? binaryen_tarball
164
247
  FileUtils.mkdir_p File.dirname(binaryen_tarball)
165
- system "curl -L -o #{binaryen_tarball} #{self.binaryen_download_url(@binaryen_version)}"
248
+ executor.system "curl",
249
+ "-L",
250
+ "-o",
251
+ binaryen_tarball,
252
+ self.download_url(@binaryen_version)
166
253
  end
167
254
 
168
255
  unless File.exist? @binaryen_path
169
256
  FileUtils.mkdir_p @binaryen_path
170
- system "tar -C #{@binaryen_path} --strip-component 1 -xzf #{binaryen_tarball}"
257
+ executor.system "tar",
258
+ "-C",
259
+ @binaryen_path,
260
+ "--strip-component",
261
+ "1",
262
+ "-xzf",
263
+ binaryen_tarball
171
264
  end
172
265
  end
173
-
174
- def install
175
- install_wasi_sdk
176
- install_binaryen
177
- end
178
266
  end
179
267
 
180
268
  class Emscripten < Toolchain
181
269
  def initialize
182
- @tools = { cc: "emcc", cxx: "em++", ld: "emcc", ar: "emar", ranlib: "emranlib" }
270
+ @tools = {
271
+ cc: "emcc",
272
+ cxx: "em++",
273
+ ld: "emcc",
274
+ ar: "emar",
275
+ ranlib: "emranlib"
276
+ }
183
277
  @name = "emscripten"
184
278
  end
185
279
 
186
- def install
280
+ def install(executor)
187
281
  end
188
282
 
189
283
  def find_tool(name)
@@ -43,7 +43,7 @@ class RubyWasm::Build
43
43
  @target = target
44
44
  @build_dir = build_dir
45
45
  @rubies_dir = rubies_dir
46
- @toolchain = (toolchain || RubyWasm::Toolchain.get(target, @build_dir))
46
+ @toolchain = toolchain || raise("toolchain is required")
47
47
 
48
48
  @libyaml = RubyWasm::LibYAMLProduct.new(@build_dir, @target, @toolchain)
49
49
  @zlib = RubyWasm::ZlibProduct.new(@build_dir, @target, @toolchain)
data/lib/ruby_wasm/cli.rb CHANGED
@@ -181,12 +181,12 @@ module RubyWasm
181
181
  private
182
182
 
183
183
  def build_config(options)
184
- build_source, all_default_exts = compute_build_source(options)
185
184
  # @type var config: Packager::build_config
186
- config = { target: options[:target_triplet], src: build_source }
185
+ config = compute_build_alias(options)
186
+ config[:target] = options[:target_triplet]
187
187
  case options[:profile]
188
188
  when "full"
189
- config[:default_exts] = all_default_exts || ""
189
+ config[:default_exts] = config[:all_default_exts] || ""
190
190
  env_additional_exts = ENV["RUBY_WASM_ADDITIONAL_EXTS"] || ""
191
191
  unless env_additional_exts.empty?
192
192
  config[:default_exts] += "," + env_additional_exts
@@ -201,24 +201,32 @@ module RubyWasm
201
201
  config
202
202
  end
203
203
 
204
- def compute_build_source(options)
204
+ def compute_build_alias(options)
205
205
  src_name = options[:ruby_version]
206
- aliases = self.class.build_source_aliases(root)
207
- source = aliases[src_name]
208
- if source.nil?
206
+ aliases = self.class.build_config_aliases(root)
207
+ config = aliases[src_name]
208
+ if config.nil?
209
209
  if File.directory?(src_name)
210
210
  # Treat as a local source if the given name is a source directory.
211
211
  RubyWasm.logger.debug "Using local source: #{src_name}"
212
212
  if options[:patches].any?
213
213
  RubyWasm.logger.warn "Patches specified through --patch are ignored for local sources"
214
214
  end
215
- # @type var local_source: RubyWasm::Packager::build_source_local
216
- local_source = { type: "local", path: src_name }
217
- # @type var local_source: RubyWasm::Packager::build_source
218
- local_source = local_source.merge(name: "local", patches: [])
219
215
  # FIXME: We should have a way to specify extensions to be included by users.
220
216
  # For now, assume all default extensions available in the head revision are available.
221
- return [local_source, RubyWasm::Packager::ALL_DEFAULT_EXTS]
217
+ # @type var patches: Array[String]
218
+ patches = []
219
+ return(
220
+ {
221
+ name: "local",
222
+ src: {
223
+ type: "local",
224
+ path: src_name,
225
+ patches: patches
226
+ },
227
+ all_default_exts: RubyWasm::Packager::ALL_DEFAULT_EXTS
228
+ }
229
+ )
222
230
  end
223
231
  # Otherwise, it's an unknown source.
224
232
  raise(
@@ -226,64 +234,100 @@ module RubyWasm
226
234
  )
227
235
  end
228
236
  # Apply user-specified patches in addition to bundled patches.
229
- source[:patches].concat(options[:patches])
230
- # @type var all_default_exts: String
231
- __skip__ = all_default_exts = source[:all_default_exts]
232
- [source, all_default_exts]
237
+ config[:src][:patches].concat(options[:patches])
238
+ config
233
239
  end
234
240
 
235
241
  # Retrieves the alias definitions for the Ruby sources.
236
- def self.build_source_aliases(root)
237
- # @type var sources: Hash[string, RubyWasm::Packager::build_source]
238
- sources = {
239
- "head" => {
240
- type: "github",
241
- repo: "ruby/ruby",
242
- rev: "master",
242
+ def self.build_config_aliases(root)
243
+ # @type var aliases: Array[RubyWasm::Packager::build_source]
244
+ aliases = [
245
+ {
246
+ name: "head",
247
+ src: {
248
+ type: "github",
249
+ repo: "ruby/ruby",
250
+ rev: "master"
251
+ },
243
252
  all_default_exts: RubyWasm::Packager::ALL_DEFAULT_EXTS,
253
+ wasi_sdk_version: "24.0"
254
+ },
255
+ {
256
+ name: "4.0",
257
+ src: {
258
+ type: "tarball",
259
+ url: "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.0.tar.gz"
260
+ },
261
+ all_default_exts:
262
+ "cgi/escape,continuation,coverage,date,digest/bubblebabble,digest,digest/md5,digest/rmd160,digest/sha1,digest/sha2,etc,fcntl,json,json/generator,json/parser,objspace,pathname,psych,rbconfig/sizeof,ripper,stringio,strscan,monitor,zlib,openssl",
263
+ wasi_sdk_version: "24.0"
244
264
  },
245
- "3.4" => {
246
- type: "tarball",
247
- url: "https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.1.tar.gz",
248
- all_default_exts: "cgi/escape,continuation,coverage,date,digest/bubblebabble,digest,digest/md5,digest/rmd160,digest/sha1,digest/sha2,etc,fcntl,json,json/generator,json/parser,objspace,pathname,psych,rbconfig/sizeof,ripper,stringio,strscan,monitor,zlib,openssl",
265
+ {
266
+ name: "3.4",
267
+ src: {
268
+ type: "tarball",
269
+ url: "https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.1.tar.gz"
270
+ },
271
+ all_default_exts:
272
+ "cgi/escape,continuation,coverage,date,digest/bubblebabble,digest,digest/md5,digest/rmd160,digest/sha1,digest/sha2,etc,fcntl,json,json/generator,json/parser,objspace,pathname,psych,rbconfig/sizeof,ripper,stringio,strscan,monitor,zlib,openssl",
273
+ wasi_sdk_version: "22.0"
249
274
  },
250
- "3.3" => {
251
- type: "tarball",
252
- url: "https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.3.tar.gz",
253
- all_default_exts: "bigdecimal,cgi/escape,continuation,coverage,date,dbm,digest/bubblebabble,digest,digest/md5,digest/rmd160,digest/sha1,digest/sha2,etc,fcntl,fiber,gdbm,json,json/generator,json/parser,nkf,objspace,pathname,psych,racc/cparse,rbconfig/sizeof,ripper,stringio,strscan,monitor,zlib,openssl",
275
+ {
276
+ name: "3.3",
277
+ src: {
278
+ type: "tarball",
279
+ url: "https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.3.tar.gz"
280
+ },
281
+ all_default_exts:
282
+ "bigdecimal,cgi/escape,continuation,coverage,date,dbm,digest/bubblebabble,digest,digest/md5,digest/rmd160,digest/sha1,digest/sha2,etc,fcntl,fiber,gdbm,json,json/generator,json/parser,nkf,objspace,pathname,psych,racc/cparse,rbconfig/sizeof,ripper,stringio,strscan,monitor,zlib,openssl",
283
+ wasi_sdk_version: "22.0"
254
284
  },
255
- "3.2" => {
256
- type: "tarball",
257
- url: "https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.4.tar.gz",
258
- all_default_exts: "bigdecimal,cgi/escape,continuation,coverage,date,dbm,digest/bubblebabble,digest,digest/md5,digest/rmd160,digest/sha1,digest/sha2,etc,fcntl,fiber,gdbm,json,json/generator,json/parser,nkf,objspace,pathname,psych,racc/cparse,rbconfig/sizeof,ripper,stringio,strscan,monitor,zlib,openssl",
285
+ {
286
+ name: "3.2",
287
+ src: {
288
+ type: "tarball",
289
+ url: "https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.4.tar.gz"
290
+ },
291
+ all_default_exts:
292
+ "bigdecimal,cgi/escape,continuation,coverage,date,dbm,digest/bubblebabble,digest,digest/md5,digest/rmd160,digest/sha1,digest/sha2,etc,fcntl,fiber,gdbm,json,json/generator,json/parser,nkf,objspace,pathname,psych,racc/cparse,rbconfig/sizeof,ripper,stringio,strscan,monitor,zlib,openssl",
293
+ wasi_sdk_version: "22.0"
259
294
  }
260
- }
295
+ ]
296
+
297
+ # Set the name in the source config.
298
+ aliases.each { |config| config[:src][:name] = config[:name] }
261
299
 
262
300
  # Apply bundled and user-specified `<root>/patches` directories.
263
- sources.each do |name, source|
264
- source[:name] = name
301
+ aliases.each do |config|
265
302
  patches_dirs = [bundled_patches_path, File.join(root, "patches")]
266
- source[:patches] = patches_dirs.flat_map do |patches_dir|
267
- Dir[File.join(patches_dir, name, "*.patch")]
268
- .map { |p| File.expand_path(p) }
269
- end.uniq
303
+ config[:src][:patches] = patches_dirs
304
+ .flat_map do |patches_dir|
305
+ Dir[File.join(patches_dir, config[:name], "*.patch")].map do |p|
306
+ File.expand_path(p)
307
+ end
308
+ end
309
+ .uniq
270
310
  end
271
311
 
312
+ aliases_by_name = aliases.to_h { |config| [config[:name], config] }
313
+
314
+ # Pin the revisions based on build_manifest.json if available.
272
315
  build_manifest = File.join(root, "build_manifest.json")
273
316
  if File.exist?(build_manifest)
274
317
  begin
275
318
  manifest = JSON.parse(File.read(build_manifest))
276
319
  manifest["ruby_revisions"].each do |name, rev|
277
- source = sources[name]
320
+ source = aliases_by_name[name][:src]
278
321
  next unless source[:type] == "github"
279
322
  # @type var source: RubyWasm::Packager::build_source_github
280
323
  source[:rev] = rev
281
324
  end
282
325
  rescue StandardError => e
283
326
  RubyWasm.logger.warn "Failed to load build_manifest.json: #{e}"
327
+ raise e
284
328
  end
285
329
  end
286
- sources
330
+ aliases_by_name
287
331
  end
288
332
 
289
333
  # Retrieves the root directory of the Ruby project.
@@ -179,7 +179,7 @@ class RubyWasm::Packager::Core
179
179
  end
180
180
 
181
181
  def _build_gem_exts(executor, build, gem_home)
182
- build.toolchain.install
182
+ build.toolchain.install(executor)
183
183
  baseruby = build.baseruby
184
184
  unless Dir.exist?(baseruby.install_dir)
185
185
  baseruby.build(executor)
@@ -111,7 +111,7 @@ class RubyWasm::Packager
111
111
  options = build_options
112
112
  build_dir = File.join(@root, "build")
113
113
  rubies_dir = File.join(@root, "rubies")
114
- toolchain = RubyWasm::Toolchain.get(options[:target], build_dir)
114
+ toolchain = RubyWasm::Toolchain.get(options[:target], options, build_dir)
115
115
  options.merge(
116
116
  toolchain: toolchain,
117
117
  build_dir: build_dir,
@@ -1,3 +1,3 @@
1
1
  module RubyWasm
2
- VERSION = "2.7.2"
2
+ VERSION = "2.9.0"
3
3
  end
data/package-lock.json CHANGED
@@ -17,6 +17,12 @@
17
17
  "typedoc": "^0.28.8"
18
18
  }
19
19
  },
20
+ "node_modules/@bjorn3/browser_wasi_shim": {
21
+ "version": "0.4.2",
22
+ "resolved": "https://registry.npmjs.org/@bjorn3/browser_wasi_shim/-/browser_wasi_shim-0.4.2.tgz",
23
+ "integrity": "sha512-/iHkCVUG3VbcbmEHn5iIUpIrh7a7WPiwZ3sHy4HZKZzBdSadwdddYDZAII2zBvQYV0Lfi8naZngPCN7WPHI/hA==",
24
+ "license": "MIT OR Apache-2.0"
25
+ },
20
26
  "node_modules/@bytecodealliance/componentize-js": {
21
27
  "version": "0.14.0",
22
28
  "resolved": "https://registry.npmjs.org/@bytecodealliance/componentize-js/-/componentize-js-0.14.0.tgz",
@@ -1479,6 +1485,10 @@
1479
1485
  "resolved": "packages/npm-packages/ruby-3.4-wasm-wasi",
1480
1486
  "link": true
1481
1487
  },
1488
+ "node_modules/@ruby/4.0-wasm-wasi": {
1489
+ "resolved": "packages/npm-packages/ruby-4.0-wasm-wasi",
1490
+ "link": true
1491
+ },
1482
1492
  "node_modules/@ruby/head-wasm-emscripten": {
1483
1493
  "resolved": "packages/npm-packages/ruby-head-wasm-emscripten",
1484
1494
  "link": true
@@ -3576,7 +3586,7 @@
3576
3586
  },
3577
3587
  "packages/npm-packages/ruby-3.2-wasm-wasi": {
3578
3588
  "name": "@ruby/3.2-wasm-wasi",
3579
- "version": "2.7.2",
3589
+ "version": "2.9.0",
3580
3590
  "license": "MIT",
3581
3591
  "dependencies": {
3582
3592
  "@ruby/wasm-wasi": "^2.0.0"
@@ -3584,7 +3594,7 @@
3584
3594
  },
3585
3595
  "packages/npm-packages/ruby-3.3-wasm-wasi": {
3586
3596
  "name": "@ruby/3.3-wasm-wasi",
3587
- "version": "2.7.2",
3597
+ "version": "2.9.0",
3588
3598
  "license": "MIT",
3589
3599
  "dependencies": {
3590
3600
  "@ruby/wasm-wasi": "^2.0.0"
@@ -3592,7 +3602,15 @@
3592
3602
  },
3593
3603
  "packages/npm-packages/ruby-3.4-wasm-wasi": {
3594
3604
  "name": "@ruby/3.4-wasm-wasi",
3595
- "version": "2.7.2",
3605
+ "version": "2.9.0",
3606
+ "license": "MIT",
3607
+ "dependencies": {
3608
+ "@ruby/wasm-wasi": "^2.0.0"
3609
+ }
3610
+ },
3611
+ "packages/npm-packages/ruby-4.0-wasm-wasi": {
3612
+ "name": "@ruby/4.0-wasm-wasi",
3613
+ "version": "2.9.0",
3596
3614
  "license": "MIT",
3597
3615
  "dependencies": {
3598
3616
  "@ruby/wasm-wasi": "^2.0.0"
@@ -3600,12 +3618,12 @@
3600
3618
  },
3601
3619
  "packages/npm-packages/ruby-head-wasm-emscripten": {
3602
3620
  "name": "@ruby/head-wasm-emscripten",
3603
- "version": "2.7.2",
3621
+ "version": "2.9.0",
3604
3622
  "license": "MIT"
3605
3623
  },
3606
3624
  "packages/npm-packages/ruby-head-wasm-wasi": {
3607
3625
  "name": "@ruby/head-wasm-wasi",
3608
- "version": "2.7.2",
3626
+ "version": "2.9.0",
3609
3627
  "license": "MIT",
3610
3628
  "dependencies": {
3611
3629
  "@ruby/wasm-wasi": "^2.0.0"
@@ -3613,7 +3631,7 @@
3613
3631
  },
3614
3632
  "packages/npm-packages/ruby-head-wasm-wasip2": {
3615
3633
  "name": "@ruby/head-wasm-wasip2",
3616
- "version": "2.7.2",
3634
+ "version": "2.9.0",
3617
3635
  "license": "MIT",
3618
3636
  "dependencies": {
3619
3637
  "@bytecodealliance/preview2-shim": "^0.17.2",
@@ -3630,10 +3648,10 @@
3630
3648
  },
3631
3649
  "packages/npm-packages/ruby-wasm-wasi": {
3632
3650
  "name": "@ruby/wasm-wasi",
3633
- "version": "2.7.2",
3651
+ "version": "2.9.0",
3634
3652
  "license": "MIT",
3635
3653
  "dependencies": {
3636
- "@bjorn3/browser_wasi_shim": "^0.3.0",
3654
+ "@bjorn3/browser_wasi_shim": "^0.4.2",
3637
3655
  "tslib": "^2.8.1"
3638
3656
  },
3639
3657
  "devDependencies": {
@@ -3645,10 +3663,6 @@
3645
3663
  "vitest": "^3.2.4"
3646
3664
  }
3647
3665
  },
3648
- "packages/npm-packages/ruby-wasm-wasi/node_modules/@bjorn3/browser_wasi_shim": {
3649
- "version": "0.3.0",
3650
- "license": "MIT OR Apache-2.0"
3651
- },
3652
3666
  "packages/npm-packages/ruby-wasm-wasi/node_modules/@bytecodealliance/jco": {
3653
3667
  "version": "1.8.1",
3654
3668
  "resolved": "https://registry.npmjs.org/@bytecodealliance/jco/-/jco-1.8.1.tgz",
data/rakelib/ci.rake CHANGED
@@ -1,7 +1,8 @@
1
1
  def latest_build_sources
2
2
  BUILD_SOURCES
3
3
  .filter_map do |name|
4
- src = RubyWasm::CLI.build_source_aliases(LIB_ROOT)[name]
4
+ config = RubyWasm::CLI.build_config_aliases(LIB_ROOT)[name]
5
+ src = config[:src]
5
6
  case src[:type]
6
7
  when "github"
7
8
  url = "repos/#{src[:repo]}/commits/#{src[:rev]}"
@@ -23,7 +24,8 @@ def release_note
23
24
  EOS
24
25
 
25
26
  BUILD_SOURCES.each do |name|
26
- source = RubyWasm::CLI.build_source_aliases(LIB_ROOT)[name]
27
+ config = RubyWasm::CLI.build_config_aliases(LIB_ROOT)[name]
28
+ source = config[:src]
27
29
  case source[:type]
28
30
  when "github"
29
31
  output +=
@@ -1,10 +1,10 @@
1
1
  wasi_vfs = RubyWasm::WasiVfsProduct.new(File.join(Dir.pwd, "build"))
2
- wasi_sdk = TOOLCHAINS["wasi-sdk"]
2
+ binaryen = RubyWasm::Binaryen.new(build_dir: File.join(Dir.pwd, "build"))
3
3
  def exe_rbwasm = File.expand_path(File.join(__dir__, "..", "exe", "rbwasm"))
4
4
 
5
5
  tools = {
6
6
  "WASI_VFS_CLI" => exe_rbwasm,
7
- "WASMOPT" => wasi_sdk.wasm_opt
7
+ "WASMOPT" => binaryen.wasm_opt
8
8
  }
9
9
 
10
10
  def npm_pkg_build_command(pkg)
@@ -51,7 +51,7 @@ def vendor_gem_cache(pkg)
51
51
  JS::VERSION
52
52
  end
53
53
 
54
- def build_ruby(pkg, base_dir, pkg_dir, wasi_sdk, clean: false)
54
+ def build_ruby(pkg, base_dir, pkg_dir, binaryen, clean: false)
55
55
  build_command = npm_pkg_build_command(pkg)
56
56
  # Skip if the package does not require building ruby
57
57
  return unless build_command
@@ -111,12 +111,12 @@ def build_ruby(pkg, base_dir, pkg_dir, wasi_sdk, clean: false)
111
111
  File.join(dist_dir, "ruby.debug+stdlib.wasm")
112
112
  end
113
113
 
114
- sh wasi_sdk.wasm_opt,
114
+ sh binaryen.wasm_opt,
115
115
  "--strip-debug",
116
116
  File.join(dist_dir, "ruby.wasm"),
117
117
  "-o",
118
118
  File.join(dist_dir, "ruby.wasm")
119
- sh wasi_sdk.wasm_opt,
119
+ sh binaryen.wasm_opt,
120
120
  "--strip-debug",
121
121
  File.join(dist_dir, "ruby.debug+stdlib.wasm"),
122
122
  "-o",
@@ -137,7 +137,7 @@ namespace :npm do
137
137
  namespace pkg[:name] do
138
138
  desc "Build ruby for npm package #{pkg[:name]}"
139
139
  task "ruby" do
140
- build_ruby(pkg, base_dir, pkg_dir, wasi_sdk)
140
+ build_ruby(pkg, base_dir, pkg_dir, binaryen)
141
141
  end
142
142
 
143
143
  desc "Build npm package #{pkg[:name]}"
@@ -147,7 +147,7 @@ namespace :npm do
147
147
 
148
148
  desc "Clean and build npm package #{pkg[:name]}"
149
149
  task "clean-build" do
150
- build_ruby(pkg, base_dir, pkg_dir, wasi_sdk, clean: true)
150
+ build_ruby(pkg, base_dir, pkg_dir, binaryen, clean: true)
151
151
  end
152
152
 
153
153
  desc "Check npm package #{pkg[:name]}"
@@ -158,7 +158,8 @@ namespace :npm do
158
158
 
159
159
  desc "Make tarball for npm package #{pkg[:name]}"
160
160
  task pkg[:name] do
161
- wasi_sdk.install_binaryen
161
+ executor = RubyWasm::BuildExecutor.new
162
+ binaryen.install(executor)
162
163
  Rake::Task["npm:#{pkg[:name]}:build"].invoke
163
164
  sh "npm pack", chdir: pkg_dir
164
165
  end
@@ -201,7 +202,8 @@ namespace :standalone do
201
202
 
202
203
  desc "Build standalone package #{pkg[:name]}"
203
204
  task "#{pkg[:name]}" => ["build:#{pkg[:build]}"] do
204
- wasi_sdk.install_binaryen
205
+ executor = RubyWasm::SilentExecutor.new
206
+ binaryen.install(executor)
205
207
  base_dir = Dir.pwd
206
208
  sh tools,
207
209
  "./build-package.sh #{base_dir}/rubies/ruby-#{pkg[:build]}",
@@ -218,6 +218,7 @@ module RubyWasm
218
218
  def extinit_obj: -> String
219
219
  def extinit_c_erb: -> String
220
220
  def baseruby_path: -> String
221
+ def dump_ast_path: -> String
221
222
  def configure_args: (String build_triple, Toolchain toolchain) -> Array[String]
222
223
  def rbconfig_rb: -> String?
223
224
  end
@@ -240,7 +241,7 @@ module RubyWasm
240
241
  def initialize: -> void
241
242
  def find_tool: (Symbol name) -> String
242
243
  def check_envvar: (untyped name) -> void
243
- def self.get: (Target target, ?String? build_dir) -> (Toolchain)
244
+ def self.get: (Target target, Hash[untyped, untyped] config, ?String? build_dir) -> (Toolchain)
244
245
  def self.find_path: (String command) -> String?
245
246
  def self.check_executable: (String command) -> String
246
247
  def cc: -> String
@@ -249,28 +250,38 @@ module RubyWasm
249
250
  def ld: -> String
250
251
  def ar: -> String
251
252
 
252
- def install: -> void
253
+ def install: (_CommandExecutor executor) -> void
253
254
  end
254
255
 
255
256
  class WASISDK < Toolchain
256
257
  @wasm_opt_path: String
257
258
  @need_fetch_wasi_sdk: bool
258
- @need_fetch_binaryen: bool
259
259
  @tools: Hash[Symbol, String]
260
260
  @wasi_sdk_path: String
261
- @binaryen_version: Integer
262
- @version_major: Integer
263
- @version_minor: Integer
264
- @binaryen_path: String
261
+ @version: String
262
+ @binaryen: Binaryen
265
263
 
266
- def initialize: (?String? wasi_sdk_path, ?build_dir: String?, ?version_major: Integer, ?version_minor: Integer, ?binaryen_version: Integer) -> void
264
+ def initialize: (?String? wasi_sdk_path, ?build_dir: String?, ?version: String, ?binaryen_version: Integer) -> void
267
265
  def find_tool: (Symbol name) -> String
268
266
  def wasm_opt: -> String
269
267
  def wasi_sdk_path: -> String
270
- def download_url: (Integer? version_major, Integer? version_minor) -> String
271
- def binaryen_download_url: (Integer? version) -> String
272
- def install_wasi_sdk: -> void
273
- def install_binaryen: -> void
268
+ def download_url: () -> String
269
+ def install_wasi_sdk: (_CommandExecutor executor) -> void
270
+ def install: (_CommandExecutor executor) -> void
271
+ end
272
+
273
+ class Binaryen
274
+ @need_fetch_binaryen: bool
275
+ @binaryen_path: String
276
+ @binaryen_version: Integer
277
+ @wasm_opt_path: String
278
+
279
+ def initialize: (?build_dir: String?, ?binaryen_version: Integer) -> void
280
+ def wasm_opt: -> String
281
+ def binaryen_path: -> String
282
+ def binaryen_version: -> Integer
283
+ def download_url: (Integer version) -> String
284
+ def install: (_CommandExecutor executor) -> void
274
285
  end
275
286
 
276
287
  class Emscripten < Toolchain
@@ -280,7 +291,12 @@ module RubyWasm
280
291
  def find_tool: (Symbol name) -> String
281
292
  end
282
293
 
294
+ interface _CommandExecutor
295
+ def system: (*_ToS args, ?chdir: String?, ?env: Hash[String, String]?) -> void
296
+ end
297
+
283
298
  class BuildExecutor
299
+ include _CommandExecutor
284
300
  @verbose: bool
285
301
  @github_actions_markup: bool
286
302
  @process_count: Integer
@@ -289,7 +305,6 @@ module RubyWasm
289
305
  attr_reader process_count: Integer
290
306
 
291
307
  def initialize: (?verbose: bool) -> void
292
- def system: (*_ToS args, ?chdir: String?, ?env: Hash[String, String]?) -> void
293
308
  def rm_rf: (FileUtils::pathlist list) -> void
294
309
  def rm_f: (FileUtils::pathlist list) -> void
295
310
  def cp_r: (FileUtils::pathlist src, path dest) -> void
@@ -304,6 +319,10 @@ module RubyWasm
304
319
  private def _print_command: (Array[_ToS] command, Hash[String, String]? env) -> void
305
320
  end
306
321
 
322
+ class SilentExecutor
323
+ include _CommandExecutor
324
+ end
325
+
307
326
  class StatusPrinter
308
327
  @mutex: Mutex
309
328
  @counter: Integer
@@ -319,6 +338,8 @@ module RubyWasm
319
338
  def format_size: (Integer size) -> String
320
339
 
321
340
  def download: (String url, String dest, String message) -> void
341
+ def head: (String url) -> bool
342
+ private def _head: (URI::HTTPS uri, Integer limit) -> bool
322
343
  end
323
344
 
324
345
  class BuildTask
@@ -38,8 +38,8 @@ module RubyWasm
38
38
  private
39
39
 
40
40
  def build_config: (cli_options options) -> Packager::build_config
41
- def compute_build_source: (cli_options options) -> [Packager::build_source, String?]
42
- def self.build_source_aliases: (string root) -> Hash[string, Packager::build_source]
41
+ def compute_build_alias: (cli_options options) -> Packager::build_config
42
+ def self.build_config_aliases: (string root) -> Hash[string, Packager::build_config]
43
43
  def self.bundled_patches_path: () -> string
44
44
  def root: () -> string
45
45
 
@@ -13,18 +13,9 @@ class RubyWasm::Packager
13
13
  type: "local",
14
14
  path: String,
15
15
  }
16
- type build_source = (build_source_github | build_source_tarball | build_source_local) & {
17
- name: string,
18
- patches: Array[String],
19
- }
16
+ type build_source = untyped
20
17
 
21
- type build_config = {
22
- target: String,
23
- src: RubyWasm::Packager::build_source,
24
- default_exts: String,
25
- suffix: String,
26
- gem_home: String?,
27
- }
18
+ type build_config = untyped
28
19
 
29
20
  type bytes = String
30
21
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_wasm
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.2
4
+ version: 2.9.0
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - Yuta Saito
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-03 00:00:00.000000000 Z
11
+ date: 2026-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -49,6 +49,7 @@ files:
49
49
  - ext/ruby_wasm/README.md
50
50
  - lib/ruby_wasm.rb
51
51
  - lib/ruby_wasm/3.2/ruby_wasm.so
52
+ - lib/ruby_wasm/3.3/ruby_wasm.so
52
53
  - lib/ruby_wasm/3.4/ruby_wasm.so
53
54
  - lib/ruby_wasm/build.rb
54
55
  - lib/ruby_wasm/build/build_params.rb