ruby_wasm 2.6.2-x86_64-linux-musl → 2.7.1-x86_64-linux-musl

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 600f38b1685c5427dc537c287f3fb6d17944613758b5451ea46110318d681500
4
- data.tar.gz: 880db754bb7abf5744ef2adbcfa7f4bb6af06eb8be610e7e7781a7f15a648b54
3
+ metadata.gz: 0276a0c3649ee468e43730331a014773851603bb2d9d65ad2cf9dddfb24057a8
4
+ data.tar.gz: 33c4803879470e0c90af19499481c4ba2360846799cc58840600c5327e0cfe38
5
5
  SHA512:
6
- metadata.gz: 2614e52c087fc8e9927917e40bcfce57cd2d3117ebfb8657af7e993d08084e5614e6e0d61bdc601f3a644f9ef725e79a2f44944efb1daa1431700c24f859cd59
7
- data.tar.gz: 74c712f53ed169c9173e7ffd5efd0207c6f933c82e3ceaf2b5f9a0f0d5ca0b20fa15e7584e213c319a79075de737075cefcffb7754584ad549728d216cff549f
6
+ metadata.gz: ef17a9dece48ae79a0f1c379234710e284b31ee89ec20e1dbbdfb3f9ae3691a53971beb13b2c25f7cca9f2b03e45f4a77f978c0f658338c5a11c671339702c88
7
+ data.tar.gz: a9f9236f32c6e16bf5044a6bd74942e04492eebd81151aaa64cb14ae0ba41fb4bb2e87026f597b86961f1d679109dff9dd150a54ca55e4060ffd1a69a4a455ac
data/CONTRIBUTING.md CHANGED
@@ -9,8 +9,6 @@ This document describes development setup and pointers for diving into this proj
9
9
  $ git clone https://github.com/ruby/ruby.wasm --recursive
10
10
  $ cd ruby.wasm
11
11
  $ ./bin/setup
12
- # Just for building vendor/jco (will be removed soon)
13
- $ rustup target add wasm32-wasi
14
12
  # Compile extension library
15
13
  $ bundle exec rake compile
16
14
  $ rake --tasks
@@ -26,9 +24,9 @@ $ rake build:download_prebuilt
26
24
  $ rake build:head-wasm32-unknown-wasip1-full
27
25
 
28
26
  # Build npm package
29
- $ rake npm:ruby-head-wasm-wasi
27
+ $ rake npm:ruby-head-wasm-wasip2:build
30
28
  # Test npm package
31
- $ rake npm:ruby-head-wasm-wasi:check
29
+ $ rake npm:ruby-head-wasm-wasip2:check
32
30
  ```
33
31
 
34
32
  If you need to re-build Ruby, please clean `./rubies` directory, and run `rake npm:ruby-head-wasm-wasi` again.
@@ -111,9 +109,13 @@ $ rake 'bump_version[0.6.0]'
111
109
  $ git commit -m"Bump version to 0.6.0"
112
110
  $ git tag 0.6.0
113
111
  $ git push origin 0.6.0
114
- $ for pkg in pkg/ruby_wasm-*; do gem push $pkg; done
112
+ # After GitHub Actions "Build gems" is done
113
+ # https://github.com/ruby/ruby.wasm/actions/workflows/build-gems.yml
114
+ $ gh run download <run-id>
115
+ $ for pkg in cross-gem/pkg/ruby_wasm-*; do gem push $pkg; done
115
116
  $ gem build && gem push ruby_wasm-*.gem && rm ruby_wasm-*.gem
116
117
  $ (cd packages/gems/js/ && gem build && gem push js-*.gem && rm js-*.gem)
118
+ $ rake bump_dev_version
117
119
  ```
118
120
 
119
121
  ## Release Channels
@@ -127,5 +129,45 @@ $ npm install --save @ruby/wasm-wasi@latest
127
129
  # or if you want the nightly snapshot
128
130
  $ npm install --save @ruby/wasm-wasi@next
129
131
  # or you can specify the exact snapshot version
130
- $ npm install --save @ruby/wasm-wasi@2.6.2-2024-06-29-a
132
+ $ npm install --save @ruby/wasm-wasi@2.7.1-2025-01-23-a
131
133
  ```
134
+
135
+
136
+ ## Adding Support for a New Ruby Version
137
+
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
+
140
+ 1. Update `lib/ruby_wasm/cli.rb`:
141
+ - Add a new entry in the `build_source_aliases` method for the new version
142
+ - Specify the tarball URL and required default extensions
143
+
144
+ 2. Update `Rakefile`:
145
+ - Add the new version to `BUILD_SOURCES`
146
+ - Add a new entry in `NPM_PACKAGES` for the new version
147
+
148
+ 3. Create a new npm package:
149
+ ```console
150
+ # Copy from head package
151
+ $ cp -r packages/npm-packages/ruby-head-wasm-wasi packages/npm-packages/ruby-NEW.VERSION-wasm-wasi
152
+
153
+ # Update version references
154
+ # - In package.json: Update name, version, and description
155
+ # - In README.md: Update version references
156
+ ```
157
+ Note: Most of the package contents can be reused from the head package as is, since the JavaScript API and build configuration remain the same across versions.
158
+
159
+ 4. Update `package-lock.json` by `npm install`
160
+
161
+ 4. Update documentation:
162
+ - Update version references in `README.md`
163
+ - Update examples in `docs/cheat_sheet.md`
164
+ - Update the package list in `packages/npm-packages/ruby-wasm-wasi/README.md`
165
+
166
+ 5. Test the build:
167
+ ```console
168
+ $ rake build:NEW.VERSION-wasm32-unknown-wasip1-full
169
+ $ rake npm:ruby-NEW.VERSION-wasm-wasi:build
170
+ $ rake npm:ruby-NEW.VERSION-wasm-wasi:check
171
+ ```
172
+
173
+ 6. Create a pull request with all the changes
data/Gemfile CHANGED
@@ -7,11 +7,12 @@ gemspec
7
7
  group :development do
8
8
  gem "rake"
9
9
  gem "rake-compiler"
10
- gem "rb_sys", "0.9.97"
10
+ gem "rb_sys", "0.9.108"
11
11
  end
12
12
 
13
13
  group :check do
14
- gem "webrick"
14
+ # Use the latest version of webrick for URI change in Ruby 3.4
15
+ gem "webrick", "~> 1.8.2"
15
16
  gem "syntax_tree", "~> 3.5"
16
- gem "steep"
17
+ gem "steep", "~> 1.9" if RUBY_VERSION >= "3.1.0"
17
18
  end
data/NOTICE CHANGED
@@ -1264,8 +1264,7 @@ Licensed under the Apache License 2.0 https://www.openssl.org/source/license.htm
1264
1264
  https://github.com/kateinoigakukun/wasi-vfs
1265
1265
 
1266
1266
  ```
1267
- Copyright (c) 2022 Yuta Saito. All rights reserved.
1268
- Licensed under the MIT License
1267
+ Licensed under the Apache License v2.0 with LLVM Exceptions
1269
1268
  ```
1270
1269
 
1271
1270
  ---
data/README.md CHANGED
@@ -23,7 +23,7 @@ Create and save `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.3-wasm-wasi@2.6.2/dist/browser.script.iife.js"></script>
26
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.1/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.3-wasm32-unknown-wasip1-full.tar.gz
44
- $ tar xfz ruby-3.3-wasm32-unknown-wasip1-full.tar.gz
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
45
45
 
46
46
  # Extract ruby binary not to pack itself
47
- $ mv ruby-3.3-wasm32-unknown-wasip1-full/usr/local/bin/ruby ruby.wasm
47
+ $ mv ruby-3.4-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.3-wasm32-unknown-wasip1-full/usr::/usr -o my-ruby-app.wasm
54
+ $ rbwasm pack ruby.wasm --dir ./src::/src --dir ./ruby-3.4-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-3.4-wasm-wasi">@ruby/3.4-wasm-wasi</a></td>
76
+ <td>CRuby 3.4 built on WASI with JS interop support</td>
77
+ <td><a href="https://www.npmjs.com/package/@ruby/3.4-wasm-wasi" rel="nofollow"><img src="https://badge.fury.io/js/@ruby%2F3.4-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.3-wasm-wasi">@ruby/3.3-wasm-wasi</a></td>
76
81
  <td>CRuby 3.3 built on WASI with JS interop support</td>
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.3 3.2 head]
12
+ BUILD_SOURCES = %w[3.4 3.3 3.2 head]
13
13
  BUILD_PROFILES = %w[full minimal]
14
14
 
15
15
  BUILDS =
@@ -28,20 +28,32 @@ NPM_PACKAGES = [
28
28
  {
29
29
  name: "ruby-head-wasm-wasi",
30
30
  ruby_version: "head",
31
- gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
31
+ gemfile: "packages/npm-packages/ruby-head-wasm-wasi/Gemfile",
32
32
  target: "wasm32-unknown-wasip1",
33
+ },
34
+ {
35
+ name: "ruby-head-wasm-wasip2",
36
+ ruby_version: "head",
37
+ gemfile: "packages/npm-packages/ruby-head-wasm-wasip2/Gemfile",
38
+ target: "wasm32-unknown-wasip2",
33
39
  enable_component_model: true,
34
40
  },
41
+ {
42
+ name: "ruby-3.4-wasm-wasi",
43
+ ruby_version: "3.4",
44
+ gemfile: "packages/npm-packages/ruby-3.3-wasm-wasi/Gemfile",
45
+ target: "wasm32-unknown-wasip1"
46
+ },
35
47
  {
36
48
  name: "ruby-3.3-wasm-wasi",
37
49
  ruby_version: "3.3",
38
- gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
50
+ gemfile: "packages/npm-packages/ruby-3.3-wasm-wasi/Gemfile",
39
51
  target: "wasm32-unknown-wasip1"
40
52
  },
41
53
  {
42
54
  name: "ruby-3.2-wasm-wasi",
43
55
  ruby_version: "3.2",
44
- gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
56
+ gemfile: "packages/npm-packages/ruby-3.2-wasm-wasi/Gemfile",
45
57
  target: "wasm32-unknown-wasip1"
46
58
  },
47
59
  { name: "ruby-wasm-wasi", target: "wasm32-unknown-wasip1" }
data/docs/api.md CHANGED
@@ -1,2 +1,2 @@
1
1
  - [Ruby API](https://ruby.github.io/ruby.wasm/JS.html)
2
- - [JavaScript API](https://github.com/ruby/ruby.wasm/blob/main/packages/npm-packages/ruby-wasm-wasi/README.md#API)
2
+ - [JavaScript API](https://ruby.github.io/ruby.wasm/npm/@ruby/wasm-wasi/)
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.3-wasm-wasi` and `@ruby/wasm-wasi` from npm:
11
+ To install the package, install `@ruby/3.4-wasm-wasi` and `@ruby/wasm-wasi` from npm:
12
12
 
13
13
  ```console
14
- npm install --save @ruby/3.3-wasm-wasi @ruby/wasm-wasi
14
+ npm install --save @ruby/3.4-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.3-wasm-wasi/dist/ruby.wasm");
23
+ const binary = await fs.readFile("./node_modules/@ruby/3.4-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.3-wasm-wasi@2.6.2/dist/browser.script.iife.js"></script>
41
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.1/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.6.2/dist/browser/+esm";
55
- const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.6.2/dist/ruby+stdlib.wasm");
54
+ import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.1/dist/browser/+esm";
55
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.1/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.6.2/dist/browser.umd.js"></script>
72
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.1/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.3-wasm-wasi@2.6.2/dist/ruby+stdlib.wasm");
76
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.1/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.3-wasm-wasi@2.6.2/dist/browser.script.iife.js"></script>
131
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.1/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.6.2/dist/browser/+esm";
147
- const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.6.2/dist/ruby+stdlib.wasm");
146
+ import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.1/dist/browser/+esm";
147
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.1/dist/ruby+stdlib.wasm");
148
148
  const module = await WebAssembly.compileStreaming(response);
149
149
  const { vm } = await DefaultRubyVM(module);
150
150
 
Binary file
Binary file
Binary file
Binary file
@@ -32,7 +32,7 @@ module RubyWasm
32
32
  end
33
33
 
34
34
  def make_args(crossruby)
35
- make_args = []
35
+ make_args = [] #: Array[String]
36
36
  make_args << "CC=#{@toolchain.cc}"
37
37
  make_args << "CXX=#{@toolchain.cc}"
38
38
  make_args << "LD=#{@toolchain.ld}"
@@ -71,14 +71,14 @@ module RubyWasm
71
71
  return
72
72
  end
73
73
  objdir = product_build_dir crossruby
74
- rbconfig_rb = Dir.glob(File.join(crossruby.dest_dir, "usr/local/lib/ruby/*/wasm32-wasi/rbconfig.rb")).first
74
+ rbconfig_rb = crossruby.rbconfig_rb
75
75
  raise "rbconfig.rb not found" unless rbconfig_rb
76
76
  extconf_args = [
77
77
  "-C", objdir,
78
78
  "#{@srcdir}/extconf.rb",
79
79
  "--target-rbconfig=#{rbconfig_rb}",
80
80
  ]
81
- extconf_args << "--enable-component-model" if @features.support_component_model?
81
+ extconf_args << "--disable-component-model" unless @features.support_component_model?
82
82
  executor.system crossruby.baseruby_path, *extconf_args
83
83
  end
84
84
 
@@ -90,10 +90,19 @@ module RubyWasm
90
90
  "--disable=gems",
91
91
  # HACK: top_srcdir is required to find ruby headers
92
92
  "-e",
93
- %Q($top_srcdir="#{source.src_dir}"),
93
+ %Q($top_srcdir=ENV["top_srcdir"]="#{source.src_dir}"),
94
94
  # HACK: extout is required to find config.h
95
95
  "-e",
96
- %Q($extout="#{crossruby.build_dir}/.ext"),
96
+ %Q($extout=ENV["extout"]="#{crossruby.build_dir}/.ext"),
97
+ ]
98
+ unless @features.support_component_model?
99
+ extconf_args.concat([
100
+ # HACK: skip have_devel check since ruby is not installed yet
101
+ "-e",
102
+ "$have_devel = true",
103
+ ])
104
+ end
105
+ extconf_args.concat([
97
106
  # HACK: force static ext build by imitating extmk
98
107
  "-e",
99
108
  "$static = true; trace_var(:$static) {|v| $static = true }",
@@ -110,8 +119,8 @@ module RubyWasm
110
119
  %Q(require "json"; File.write("#{metadata_json(crossruby)}", JSON.dump({target: $target}))),
111
120
  "-I#{crossruby.build_dir}",
112
121
  "--",
113
- ]
114
- extconf_args << "--enable-component-model" if @features.support_component_model?
122
+ ])
123
+ extconf_args << "--disable-component-model" unless @features.support_component_model?
115
124
  # Clear RUBYOPT to avoid loading unrelated bundle setup
116
125
  executor.system crossruby.baseruby_path,
117
126
  *extconf_args,
@@ -222,6 +231,10 @@ module RubyWasm
222
231
  end
223
232
  install_dir = File.join(build_dir, "install")
224
233
  if !File.exist?(install_dir) || remake || reconfigure
234
+ unless target.pic?
235
+ # HACK: force static linking for non-pic target
236
+ executor.rm_f File.join(build_dir, "ruby")
237
+ end
225
238
  executor.system "make",
226
239
  "-j#{executor.process_count}",
227
240
  "install",
@@ -301,6 +314,10 @@ module RubyWasm
301
314
  File.expand_path("../crossruby/extinit.c.erb", __FILE__)
302
315
  end
303
316
 
317
+ def rbconfig_rb
318
+ Dir.glob(File.join(dest_dir, "usr/local/lib/ruby/*/wasm32-wasi/rbconfig.rb")).first
319
+ end
320
+
304
321
  def baseruby_path
305
322
  File.join(@baseruby.install_dir, "bin/ruby")
306
323
  end
@@ -11,7 +11,7 @@ module RubyWasm
11
11
  @toolchain = toolchain
12
12
  end
13
13
  def system_triplet_args
14
- args = []
14
+ args = [] #: Array[String]
15
15
  case @target.triple
16
16
  when /^wasm32-unknown-wasi/
17
17
  args.concat(%W[--host wasm32-wasi])
@@ -24,7 +24,7 @@ module RubyWasm
24
24
  end
25
25
 
26
26
  def tools_args
27
- args = []
27
+ args = [] #: Array[String]
28
28
  args << "CC=#{@toolchain.cc}"
29
29
  args << "CXX=#{@toolchain.cxx}"
30
30
  args << "LD=#{@toolchain.ld}"
@@ -45,7 +45,7 @@ module RubyWasm
45
45
 
46
46
  %i[cc cxx ranlib ld ar].each do |name|
47
47
  define_method(name) do
48
- @tools_cache ||= {}
48
+ @tools_cache ||= {} #: Hash[String, String]
49
49
  @tools_cache[name] ||= find_tool(name)
50
50
  @tools_cache[name]
51
51
  end
data/lib/ruby_wasm/cli.rb CHANGED
@@ -242,6 +242,11 @@ module RubyWasm
242
242
  rev: "master",
243
243
  all_default_exts: RubyWasm::Packager::ALL_DEFAULT_EXTS,
244
244
  },
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",
249
+ },
245
250
  "3.3" => {
246
251
  type: "tarball",
247
252
  url: "https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.3.tar.gz",
@@ -310,7 +315,10 @@ module RubyWasm
310
315
 
311
316
  def derive_packager(options)
312
317
  __skip__ = definition = nil
313
- __skip__ = if defined?(Bundler) && !options[:disable_gems]
318
+ features = RubyWasm::FeatureSet.derive_from_env
319
+ # The head ruby & dynamic linking uses "bundle" command to build gems instead of in-process integration.
320
+ use_in_process_gem_building = !(options[:ruby_version] == "head" && features.support_dynamic_linking?)
321
+ __skip__ = if defined?(Bundler) && !options[:disable_gems] && use_in_process_gem_building
314
322
  begin
315
323
  # Silence Bundler UI if --print-ruby-cache-key is specified not to bother the JSON output.
316
324
  level = options[:print_ruby_cache_key] ? :silent : Bundler.ui.level
@@ -321,10 +329,10 @@ module RubyWasm
321
329
  Bundler.ui.level = old_level
322
330
  end
323
331
  end
324
- RubyWasm.logger.info "Using Gemfile: #{definition.gemfiles}" if definition
332
+ RubyWasm.logger.info "Using Gemfile: #{definition.gemfiles.map(&:to_s).join(", ")}" if definition
325
333
  RubyWasm::Packager.new(
326
334
  root, build_config(options), definition,
327
- features: RubyWasm::FeatureSet.derive_from_env
335
+ features: features,
328
336
  )
329
337
  end
330
338
 
@@ -332,6 +340,9 @@ module RubyWasm
332
340
  ruby_core_build = packager.ruby_core_build
333
341
  require "digest"
334
342
  digest = Digest::SHA256.new
343
+ # The build system key is used to invalidate the cache when the build system is updated.
344
+ build_system_key = 1
345
+ digest.update(build_system_key.to_s)
335
346
  ruby_core_build.cache_key(digest)
336
347
  hexdigest = digest.hexdigest
337
348
  require "json"
@@ -1,4 +1,5 @@
1
1
  require "forwardable"
2
+ require "pathname"
2
3
 
3
4
  class RubyWasm::Packager::Core
4
5
  def initialize(packager)
@@ -19,7 +20,6 @@ class RubyWasm::Packager::Core
19
20
  def build_strategy
20
21
  @build_strategy ||=
21
22
  begin
22
- has_exts = @packager.specs.any? { |spec| spec.extensions.any? }
23
23
  if @packager.features.support_dynamic_linking?
24
24
  DynamicLinking.new(@packager)
25
25
  else
@@ -59,14 +59,6 @@ class RubyWasm::Packager::Core
59
59
  end
60
60
  end
61
61
 
62
- def wasi_exec_model
63
- # TODO: Detect WASI exec-model from binary exports (_start or _initialize)
64
- use_js_gem = @packager.specs.any? do |spec|
65
- spec.name == "js"
66
- end
67
- use_js_gem ? "reactor" : "command"
68
- end
69
-
70
62
  def with_unbundled_env(&block)
71
63
  __skip__ = if defined?(Bundler)
72
64
  Bundler.with_unbundled_env(&block)
@@ -119,7 +111,7 @@ class RubyWasm::Packager::Core
119
111
  end
120
112
 
121
113
  def _link_gem_exts(executor, build, ruby_root, gem_home, module_bytes)
122
- libraries = []
114
+ libraries = [] #: Array[String]
123
115
 
124
116
  # TODO: Should be computed from dyinfo of ruby binary
125
117
  wasi_libc_shared_libs = [
@@ -138,12 +130,16 @@ class RubyWasm::Packager::Core
138
130
  wasi_sdk_path = toolchain.wasi_sdk_path
139
131
  libraries << File.join(wasi_sdk_path, "share/wasi-sysroot/lib/wasm32-wasi", lib)
140
132
  end
141
- wasi_adapter = RubyWasm::Packager::ComponentAdapter.wasi_snapshot_preview1(wasi_exec_model)
142
- adapters = [wasi_adapter]
143
- dl_openable_libs = []
133
+ dl_openable_libs = [] #: Array[[string, Array[String]]]
144
134
  dl_openable_libs << [File.dirname(ruby_root), Dir.glob(File.join(ruby_root, "lib", "ruby", "**", "*.so"))]
145
135
  dl_openable_libs << [gem_home, Dir.glob(File.join(gem_home, "**", "*.so"))]
146
136
 
137
+ has_js_so = dl_openable_libs.any? do |root, libs|
138
+ libs.any? { |lib| lib.end_with?("/js.so") }
139
+ end
140
+ wasi_adapter = RubyWasm::Packager::ComponentAdapter.wasi_snapshot_preview1(has_js_so ? "reactor" : "command")
141
+ adapters = [wasi_adapter]
142
+
147
143
  linker = RubyWasmExt::ComponentLink.new
148
144
  linker.use_built_in_libdl(true)
149
145
  linker.stub_missing_functions(false)
@@ -151,11 +147,13 @@ class RubyWasm::Packager::Core
151
147
 
152
148
  linker.library("ruby", module_bytes, false)
153
149
 
150
+ RubyWasm.logger.info "Linking Ruby with extensions"
151
+
154
152
  libraries.each do |lib|
155
153
  # Non-DL openable libraries should be referenced as base name
156
154
  lib_name = File.basename(lib)
157
155
  module_bytes = File.binread(lib)
158
- RubyWasm.logger.info "Linking #{lib_name} (#{module_bytes.size} bytes)"
156
+ RubyWasm.logger.debug "Linking #{lib_name} (#{module_bytes.size} bytes)"
159
157
  linker.library(lib_name, module_bytes, false)
160
158
  end
161
159
 
@@ -164,7 +162,7 @@ class RubyWasm::Packager::Core
164
162
  # DL openable lib_name should be a relative path from ruby_root
165
163
  lib_name = "/" + Pathname.new(lib).relative_path_from(Pathname.new(File.dirname(root))).to_s
166
164
  module_bytes = File.binread(lib)
167
- RubyWasm.logger.info "Linking #{lib_name} (#{module_bytes.size} bytes)"
165
+ RubyWasm.logger.debug "Linking #{lib_name} (#{module_bytes.size} bytes)"
168
166
  linker.library(lib_name, module_bytes, true)
169
167
  end
170
168
  end
@@ -174,7 +172,7 @@ class RubyWasm::Packager::Core
174
172
  # e.g. wasi_snapshot_preview1.command.wasm -> wasi_snapshot_preview1
175
173
  adapter_name = adapter_name.split(".")[0]
176
174
  module_bytes = File.binread(adapter)
177
- RubyWasm.logger.info "Linking adapter #{adapter_name}=#{adapter} (#{module_bytes.size} bytes)"
175
+ RubyWasm.logger.debug "Linking adapter #{adapter_name}=#{adapter} (#{module_bytes.size} bytes)"
178
176
  linker.adapter(adapter_name, module_bytes)
179
177
  end
180
178
  return linker.encode()
@@ -187,31 +185,43 @@ class RubyWasm::Packager::Core
187
185
  baseruby.build(executor)
188
186
  end
189
187
 
190
- exts = specs_with_extensions.flat_map do |spec, exts|
191
- exts.map do |ext|
192
- ext_feature = File.dirname(ext) # e.g. "ext/cgi/escape"
193
- ext_srcdir = File.join(spec.full_gem_path, ext_feature)
194
- ext_relative_path = File.join(spec.full_name, ext_feature)
195
- prod = RubyWasm::CrossRubyExtProduct.new(
196
- ext_srcdir,
197
- build.toolchain,
198
- features: @packager.features,
199
- ext_relative_path: ext_relative_path
200
- )
201
- [prod, spec]
202
- end
203
- end
188
+ crossruby = build.crossruby
189
+ rbconfig_rb = crossruby.rbconfig_rb
204
190
 
205
- exts.each do |prod, spec|
206
- libdir = File.join(gem_home, "gems", spec.full_name, spec.raw_require_paths.first)
207
- extra_mkargs = [
208
- "sitearchdir=#{libdir}",
209
- "sitelibdir=#{libdir}",
210
- ]
211
- executor.begin_section prod.class, prod.name, "Building"
212
- prod.build(executor, build.crossruby, extra_mkargs)
213
- executor.end_section prod.class, prod.name
214
- end
191
+ options = @packager.full_build_options
192
+ target_triplet = options[:target]
193
+
194
+ local_path = File.join("bundle", target_triplet)
195
+ env = {
196
+ "BUNDLE_APP_CONFIG" => File.join(".bundle", target_triplet),
197
+ "BUNDLE_PATH" => local_path,
198
+ "BUNDLE_WITHOUT" => "build",
199
+ # Do not auto-switch bundler version by Gemfile.lock
200
+ "BUNDLE_VERSION" => "system",
201
+ # FIXME: BUNDLE_PATH is set as a installation destination here, but
202
+ # it is also used as a source of gems to be loaded by RubyGems itself.
203
+ # RubyGems loads "psych" gem and if Gemfile includes "psych" gem,
204
+ # RubyGems tries to load "psych" gem from BUNDLE_PATH at the second
205
+ # time of "bundle install" command. But the extension of "psych" gem
206
+ # under BUNDLE_PATH is built for Wasm target, not for host platform,
207
+ # so it fails to load the extension.
208
+ #
209
+ # Thus we preload psych from the default LOAD_PATH here to avoid
210
+ # loading Wasm version of psych.so via `Kernel#require` patched by
211
+ # RubyGems.
212
+ "RUBYOPT" => "-rpsych",
213
+ }
214
+
215
+ args = [
216
+ File.join(baseruby.install_dir, "bin", "bundle"),
217
+ "install",
218
+ "--standalone",
219
+ "--target-rbconfig",
220
+ rbconfig_rb,
221
+ ]
222
+
223
+ executor.system(*args, env: env)
224
+ executor.cp_r(local_path, gem_home)
215
225
  end
216
226
 
217
227
  def cache_key(digest)
@@ -337,6 +347,14 @@ class RubyWasm::Packager::Core
337
347
  # No-op because we already built extensions as part of the Ruby build
338
348
  end
339
349
 
350
+ def wasi_exec_model
351
+ # TODO: Detect WASI exec-model from binary exports (_start or _initialize)
352
+ use_js_gem = @packager.specs.any? do |spec|
353
+ spec.name == "js"
354
+ end
355
+ use_js_gem ? "reactor" : "command"
356
+ end
357
+
340
358
  def link_gem_exts(executor, ruby_root, gem_home, module_bytes)
341
359
  return module_bytes unless @packager.features.support_component_model?
342
360
 
@@ -44,7 +44,6 @@ class RubyWasm::Packager::FileSystem
44
44
  when "enc"
45
45
  # Remove all encodings except for encdb.so and transdb.so
46
46
  enc_dir = File.join(@ruby_root, "lib", "ruby", ruby_version, "wasm32-wasi", "enc")
47
- puts File.join(enc_dir, "**/*.so")
48
47
  Dir.glob(File.join(enc_dir, "**/*.so")).each do |entry|
49
48
  next if entry.end_with?("encdb.so", "transdb.so")
50
49
  RubyWasm.logger.debug "Removing stdlib encoding: #{entry}"
@@ -34,7 +34,7 @@ class RubyWasm::Packager
34
34
 
35
35
  ruby_core.build_gem_exts(executor, fs.bundle_dir)
36
36
 
37
- fs.package_gems
37
+ fs.package_gems unless features.support_component_model?
38
38
  fs.remove_non_runtime_files(executor)
39
39
  if options[:stdlib]
40
40
  options[:without_stdlib_components].each do |component|
@@ -1,3 +1,3 @@
1
1
  module RubyWasm
2
- VERSION = "2.6.2"
2
+ VERSION = "2.7.1"
3
3
  end