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