Skip to content

Commit 39714d3

Browse files
Fix rake ci:* tasks
1 parent ed134ad commit 39714d3

File tree

8 files changed

+148
-49
lines changed

8 files changed

+148
-49
lines changed

Rakefile

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,26 +63,51 @@ BUILDS
6363
TOOLCHAINS[toolchain.name] = toolchain
6464
end
6565

66+
class BuildTask < Struct.new(:name, :target, :build_command)
67+
def ruby_cache_key
68+
return @key if @key
69+
require "open3"
70+
cmd = build_command + ["--print-ruby-cache-key"]
71+
stdout, status = Open3.capture2(*cmd)
72+
unless status.success?
73+
raise "Command failed with status (#{status.exitstatus}): #{cmd.join ""}"
74+
end
75+
require "json"
76+
@key = JSON.parse(stdout)
77+
end
78+
79+
def hexdigest
80+
ruby_cache_key["hexdigest"]
81+
end
82+
def artifact
83+
ruby_cache_key["artifact"]
84+
end
85+
end
86+
6687
namespace :build do
6788
BUILD_TASKS =
6889
BUILDS.map do |src, target, profile|
6990
name = "#{src}-#{target}-#{profile}"
7091

71-
desc "Cross-build Ruby for #{@target}"
92+
build_command = [
93+
"exe/rbwasm",
94+
"build",
95+
"--ruby-version",
96+
src,
97+
"--target",
98+
target,
99+
"--build-profile",
100+
profile,
101+
"--disable-gems",
102+
"-o",
103+
"/dev/null"
104+
]
105+
desc "Cross-build Ruby for #{target}"
72106
task name do
73-
sh *[
74-
"exe/rbwasm",
75-
"build",
76-
"--ruby-version",
77-
src,
78-
"--target",
79-
target,
80-
"--build-profile",
81-
profile,
82-
"-o",
83-
"/dev/null"
84-
]
107+
sh *build_command
85108
end
109+
110+
BuildTask.new(name, target, build_command)
86111
end
87112

88113
desc "Clean build directories"

lib/ruby_wasm/build.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ def initialize(
5151
@openssl = RubyWasm::OpenSSLProduct.new(@build_dir, @target, @toolchain)
5252

5353
build_params =
54-
RubyWasm::BuildParams.new(options.merge(name: name, target: target))
54+
RubyWasm::BuildParams.new(
55+
name: name,
56+
target: target,
57+
default_exts: options[:default_exts]
58+
)
5559

5660
@crossruby =
5761
RubyWasm::CrossRubyProduct.new(

lib/ruby_wasm/build/product/crossruby.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ def dest_dir
257257
end
258258

259259
def artifact
260-
File.join(@rubies_dir, "ruby-#{name}.tar.gz")
260+
File.join(@rubies_dir, "#{name}.tar.gz")
261261
end
262262

263263
def extinit_obj

lib/ruby_wasm/cli.rb

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ def build(args)
4848
ruby_version: "3.3",
4949
target_triplet: "wasm32-unknown-wasi",
5050
profile: "full",
51-
stdlib: true
51+
stdlib: true,
52+
disable_gems: false
5253
}
5354
OptionParser
5455
.new do |opts|
@@ -90,11 +91,29 @@ def build(args)
9091
opts.on("--[no-]stdlib", "Include stdlib") do |stdlib|
9192
options[:stdlib] = stdlib
9293
end
94+
95+
opts.on("--disable-gems", "Disable gems") do
96+
options[:disable_gems] = true
97+
end
98+
99+
opts.on("--format FORMAT", "Output format") do |format|
100+
options[:format] = format
101+
end
102+
103+
opts.on("--print-ruby-cache-key", "Print Ruby cache key") do
104+
options[:print_ruby_cache_key] = true
105+
end
93106
end
94107
.parse!(args)
95108

96109
verbose = RubyWasm.logger.level == :debug
97110
executor = RubyWasm::BuildExecutor.new(verbose: verbose)
111+
packager = self.derive_packager(options)
112+
113+
if options[:print_ruby_cache_key]
114+
self.do_print_ruby_cache_key(packager)
115+
exit
116+
end
98117

99118
unless options[:output]
100119
@stderr.puts "Output file is not specified"
@@ -105,11 +124,13 @@ def build(args)
105124

106125
if options[:save_temps]
107126
tmpdir = Dir.mktmpdir
108-
self.do_build(executor, tmpdir, options)
127+
self.do_build(executor, tmpdir, packager, options)
109128
@stderr.puts "Temporary files are saved to #{tmpdir}"
110129
exit
111130
else
112-
Dir.mktmpdir { |tmpdir| self.do_build(executor, tmpdir, options) }
131+
Dir.mktmpdir do |tmpdir|
132+
self.do_build(executor, tmpdir, packager, options)
133+
end
113134
end
114135
end
115136

@@ -119,20 +140,39 @@ def build_config(options)
119140
config = { target: options[:target_triplet], src: options[:ruby_version] }
120141
case options[:profile]
121142
when "full"
122-
config[:profile] = RubyWasm::Packager::ALL_DEFAULT_EXTS
143+
config[:default_exts] = RubyWasm::Packager::ALL_DEFAULT_EXTS
123144
when "minimal"
124-
config[:profile] = ""
145+
config[:default_exts] = ""
125146
else
126147
RubyWasm.logger.error "Unknown profile: #{options[:profile]} (available: full, minimal)"
127148
exit 1
128149
end
150+
config[:suffix] = "-#{options[:profile]}"
151+
config
152+
end
153+
154+
def derive_packager(options)
155+
if defined?(Bundler) && !options[:disable_gems]
156+
definition = Bundler.definition
157+
end
158+
RubyWasm::Packager.new(build_config(options), definition)
159+
end
160+
161+
def do_print_ruby_cache_key(packager)
162+
ruby_core_build = packager.ruby_core_build
163+
require "digest"
164+
digest = Digest::SHA256.new
165+
ruby_core_build.cache_key(digest)
166+
hexdigest = digest.hexdigest
167+
require "json"
168+
@stdout.puts JSON.generate(
169+
hexdigest: hexdigest,
170+
artifact: ruby_core_build.artifact
171+
)
129172
end
130173

131-
def do_build(executor, tmp_dir, options)
132-
definition = Bundler.definition if defined?(Bundler)
133-
packager =
134-
RubyWasm::Packager.new(tmp_dir, options[:target_triplet], definition)
135-
wasm_bytes = packager.package(executor, options)
174+
def do_build(executor, tmpdir, packager, options)
175+
wasm_bytes = packager.package(executor, tmpdir, options)
136176
@stderr.puts "Size: #{SizeFormatter.format(wasm_bytes.size)}"
137177
case options[:output]
138178
when "-"

lib/ruby_wasm/packager.rb

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,24 @@
22
class RubyWasm::Packager
33
# Initializes a new instance of the RubyWasm::Packager class.
44
#
5-
# @param dest_dir [String] The destination used to construct the filesystem.
65
# @param config [Hash] The build config used for building Ruby.
76
# @param definition [Bundler::Definition] The Bundler definition.
8-
def initialize(dest_dir, config = nil, definition = nil)
9-
@dest_dir = dest_dir
7+
def initialize(config = nil, definition = nil)
108
@definition = definition
119
@config = config
1210
end
1311

1412
# Packages the Ruby code into a Wasm binary. (including extensions)
1513
#
1614
# @param executor [RubyWasm::BuildExecutor] The executor for building the Wasm binary.
15+
# @param dest_dir [String] The destination used to construct the filesystem.
1716
# @param options [Hash] The packaging options.
1817
# @return [Array<Integer>] The bytes of the packaged Wasm binary.
19-
def package(executor, options)
20-
ruby_core = RubyWasm::Packager::Core.new(self)
18+
def package(executor, dest_dir, options)
19+
ruby_core = self.ruby_core_build()
2120
tarball = ruby_core.build(executor, options)
2221

23-
fs = RubyWasm::Packager::FileSystem.new(@dest_dir, self)
22+
fs = RubyWasm::Packager::FileSystem.new(dest_dir, self)
2423
fs.package_ruby_root(tarball, executor)
2524

2625
ruby_wasm_bin = File.expand_path("bin/ruby", fs.ruby_root)
@@ -40,6 +39,10 @@ def package(executor, options)
4039
wasm_bytes
4140
end
4241

42+
def ruby_core_build
43+
@ruby_core_build ||= RubyWasm::Packager::Core.new(self)
44+
end
45+
4346
# The list of excluded gems from the Bundler definition.
4447
EXCLUDED_GEMS = %w[ruby_wasm bundler]
4548

@@ -120,8 +123,7 @@ def build_options
120123
src: "3.3",
121124
default_exts: ALL_DEFAULT_EXTS
122125
}
123-
override = {}
124-
override = @config["build_options"] || {} if @config
126+
override = @config || {}
125127
# Merge the default options with the config options
126128
default.merge(override)
127129
end

lib/ruby_wasm/packager/core.rb

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require "forwardable"
2+
13
class RubyWasm::Packager::Core
24
def initialize(packager)
35
@packager = packager
@@ -8,6 +10,10 @@ def build(executor, options)
810
strategy.build(executor, options)
911
end
1012

13+
extend Forwardable
14+
15+
def_delegators :build_strategy, :cache_key, :artifact
16+
1117
private
1218

1319
def build_strategy
@@ -44,13 +50,42 @@ def specs_with_extensions
4450
[spec, exts]
4551
end
4652
end
53+
54+
def cache_key(digest)
55+
raise NotImplementedError
56+
end
57+
58+
def artifact
59+
raise NotImplementedError
60+
end
4761
end
4862

4963
class DynamicLinking < BuildStrategy
5064
end
5165

5266
class StaticLinking < BuildStrategy
5367
def build(executor, options)
68+
build = derive_build
69+
if defined?(Bundler)
70+
Bundler.with_unbundled_env do
71+
build.crossruby.build(executor, remake: options[:remake])
72+
end
73+
else
74+
build.crossruby.build(executor, remake: options[:remake])
75+
end
76+
build.crossruby.artifact
77+
end
78+
79+
def cache_key(digest)
80+
derive_build.cache_key(digest)
81+
end
82+
83+
def artifact
84+
derive_build.crossruby.artifact
85+
end
86+
87+
def derive_build
88+
return @build if @build
5489
@build ||= RubyWasm::Build.new(name, **@packager.full_build_options)
5590
@build.crossruby.user_exts = user_exts
5691
@build.crossruby.debugflags = %w[-g]
@@ -63,14 +98,7 @@ def build(executor, options)
6398
-Xlinker
6499
stack-size=16777216
65100
]
66-
if defined?(Bundler)
67-
Bundler.with_unbundled_env do
68-
@build.crossruby.build(executor, remake: options[:remake])
69-
end
70-
else
71-
@build.crossruby.build(executor, remake: options[:remake])
72-
end
73-
@build.crossruby.artifact
101+
@build
74102
end
75103

76104
def user_exts
@@ -94,7 +122,7 @@ def name
94122
options = @packager.full_build_options
95123
src_channel = options[:src][:name]
96124
target_triplet = options[:target]
97-
base = "ruby-#{src_channel}-static-#{target_triplet}"
125+
base = "ruby-#{src_channel}-#{target_triplet}#{options[:suffix]}"
98126
exts = specs_with_extensions.sort
99127
hash = ::Digest::MD5.new
100128
specs_with_extensions.each { |spec, _| hash << spec.full_name }

tasks/ci.rake

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,8 @@ def rake_task_matrix
5454
{
5555
task: "build:#{build.name}",
5656
artifact:
57-
Pathname
58-
.new(build.crossruby.artifact)
59-
.relative_path_from(LIB_ROOT)
60-
.to_s,
61-
artifact_name: File.basename(build.crossruby.artifact, ".tar.gz"),
57+
Pathname.new(build.artifact).relative_path_from(LIB_ROOT).to_s,
58+
artifact_name: File.basename(build.artifact, ".tar.gz"),
6259
builder: build.target,
6360
rubies_cache_key: ruby_cache_keys[build.name]
6461
}

tasks/gem.rake

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ Rake::TestTask.new(:test) do |t|
77
t.test_files = FileList["test/**/test_*.rb"]
88
end
99

10-
require "rb_sys/extensiontask"
10+
begin
11+
require "rb_sys/extensiontask"
1112

12-
RbSys::ExtensionTask.new("ruby_wasm") { |ext| ext.lib_dir = "lib/ruby_wasm" }
13+
RbSys::ExtensionTask.new("ruby_wasm") { |ext| ext.lib_dir = "lib/ruby_wasm" }
14+
rescue LoadError
15+
end

0 commit comments

Comments
 (0)