ruby_wasm 2.5.1-aarch64-linux-musl
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 +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
|