ruby_wasm 2.5.0-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.clang-format +8 -0
- data/CONTRIBUTING.md +126 -0
- data/Gemfile +17 -0
- data/LICENSE +21 -0
- data/NOTICE +1293 -0
- data/README.md +153 -0
- data/Rakefile +163 -0
- data/Steepfile +24 -0
- data/benchmarks/vm_deep_call.rb +55 -0
- data/builders/wasm32-unknown-emscripten/Dockerfile +43 -0
- data/builders/wasm32-unknown-emscripten/entrypoint.sh +7 -0
- data/builders/wasm32-unknown-wasi/Dockerfile +47 -0
- data/builders/wasm32-unknown-wasi/entrypoint.sh +7 -0
- data/docs/api.md +2 -0
- data/docs/cheat_sheet.md +195 -0
- data/docs/faq.md +25 -0
- data/exe/rbwasm +7 -0
- data/ext/.gitignore +2 -0
- data/ext/README.md +11 -0
- data/ext/extinit.c.erb +32 -0
- data/lib/ruby_wasm/3.0/ruby_wasm.so +0 -0
- data/lib/ruby_wasm/build/build_params.rb +3 -0
- data/lib/ruby_wasm/build/downloader.rb +18 -0
- data/lib/ruby_wasm/build/executor.rb +187 -0
- data/lib/ruby_wasm/build/product/baseruby.rb +37 -0
- data/lib/ruby_wasm/build/product/crossruby.rb +330 -0
- data/lib/ruby_wasm/build/product/libyaml.rb +68 -0
- data/lib/ruby_wasm/build/product/openssl.rb +88 -0
- data/lib/ruby_wasm/build/product/product.rb +39 -0
- data/lib/ruby_wasm/build/product/ruby_source.rb +103 -0
- data/lib/ruby_wasm/build/product/wasi_vfs.rb +45 -0
- data/lib/ruby_wasm/build/product/zlib.rb +68 -0
- data/lib/ruby_wasm/build/product.rb +8 -0
- data/lib/ruby_wasm/build/toolchain/wit_bindgen.rb +31 -0
- data/lib/ruby_wasm/build/toolchain.rb +193 -0
- data/lib/ruby_wasm/build.rb +88 -0
- data/lib/ruby_wasm/cli.rb +217 -0
- data/lib/ruby_wasm/packager/core.rb +156 -0
- data/lib/ruby_wasm/packager/file_system.rb +158 -0
- data/lib/ruby_wasm/packager.rb +159 -0
- data/lib/ruby_wasm/rake_task.rb +59 -0
- data/lib/ruby_wasm/util.rb +15 -0
- data/lib/ruby_wasm/version.rb +3 -0
- data/lib/ruby_wasm.rb +33 -0
- data/package-lock.json +9500 -0
- data/package.json +12 -0
- data/rakelib/check.rake +37 -0
- data/rakelib/ci.rake +152 -0
- data/rakelib/doc.rake +29 -0
- data/rakelib/format.rake +35 -0
- data/rakelib/gem.rake +22 -0
- data/rakelib/packaging.rake +151 -0
- data/rakelib/version.rake +40 -0
- data/sig/open_uri.rbs +4 -0
- data/sig/ruby_wasm/build.rbs +318 -0
- data/sig/ruby_wasm/cli.rbs +27 -0
- data/sig/ruby_wasm/ext.rbs +13 -0
- data/sig/ruby_wasm/packager.rbs +91 -0
- data/sig/ruby_wasm/util.rbs +5 -0
- data/tools/clang-format-diff.sh +18 -0
- data/tools/exe/rbminify +12 -0
- data/tools/lib/syntax_tree/minify_ruby.rb +63 -0
- metadata +112 -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
|