Skip to content

Commit f6880e7

Browse files
build: Introduce BuildExecutor to manage actual command invocation
1 parent 4fc94c1 commit f6880e7

File tree

9 files changed

+132
-87
lines changed

9 files changed

+132
-87
lines changed

lib/ruby_wasm/build.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,34 @@
33
require_relative "build/toolchain"
44

55
module RubyWasm
6+
# Build executor to run the actual build commands.
7+
class BuildExecutor
8+
def system(*args, **kwargs)
9+
Kernel.system(*args, **kwargs)
10+
end
11+
12+
def rm_rf(list)
13+
FileUtils.rm_rf(list)
14+
end
15+
16+
def rm_f(list)
17+
FileUtils.rm_f(list)
18+
end
19+
20+
def cp_r(src, dest)
21+
FileUtils.cp_r(src, dest)
22+
end
23+
24+
def mv(src, dest)
25+
FileUtils.mv(src, dest)
26+
end
27+
28+
def mkdir_p(list)
29+
FileUtils.mkdir_p(list)
30+
end
31+
32+
def write(path, data)
33+
File.write(path, data)
34+
end
35+
end
636
end

lib/ruby_wasm/build/product/baseruby.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ def name
2020
"baseruby-#{@channel}"
2121
end
2222

23-
def build
24-
FileUtils.mkdir_p product_build_dir
25-
@source.build
23+
def build(executor)
24+
executor.mkdir_p product_build_dir
25+
@source.build(executor)
2626
return if Dir.exist?(install_dir)
2727
Dir.chdir(product_build_dir) do
28-
system "#{@source.configure_file} --prefix=#{install_dir} --disable-install-doc"
29-
system "make install"
28+
executor.system "#{@source.configure_file} --prefix=#{install_dir} --disable-install-doc"
29+
executor.system "make install"
3030
end
3131
end
3232
end

lib/ruby_wasm/build/product/crossruby.rb

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,22 @@ def make_args(crossruby)
2727
make_args
2828
end
2929

30-
def build(crossruby)
30+
def build(executor, crossruby)
3131
lib = @name
3232
objdir = product_build_dir crossruby
33-
FileUtils.mkdir_p objdir
34-
do_extconf crossruby
35-
system %Q(make -C "#{objdir}" #{make_args(crossruby).join(" ")} #{lib}.a)
33+
executor.mkdir_p objdir
34+
do_extconf executor, crossruby
35+
executor.system %Q(make -C "#{objdir}" #{make_args(crossruby).join(" ")} #{lib}.a)
3636
# A ext can provide link args by link.filelist. It contains only built archive file by default.
3737
unless File.exist?(linklist(crossruby))
38-
File.write(linklist(crossruby), Dir.glob("#{objdir}/*.a").join("\n"))
38+
executor.write(
39+
linklist(crossruby),
40+
Dir.glob("#{objdir}/*.a").join("\n")
41+
)
3942
end
4043
end
4144

42-
def do_extconf(crossruby)
45+
def do_extconf(executor, crossruby)
4346
objdir = product_build_dir crossruby
4447
source = crossruby.source
4548
extconf_args = [
@@ -63,14 +66,14 @@ def do_extconf(crossruby)
6366
"-I#{crossruby.build_dir}"
6467
]
6568
# Clear RUBYOPT to avoid loading unrelated bundle setup
66-
system ({ "RUBYOPT" => "" }),
67-
"#{crossruby.baseruby_path} #{extconf_args.join(" ")}",
68-
chdir: objdir
69+
executor.system ({ "RUBYOPT" => "" }),
70+
"#{crossruby.baseruby_path} #{extconf_args.join(" ")}",
71+
chdir: objdir
6972
end
7073

71-
def do_install_rb(crossruby)
74+
def do_install_rb(executor, crossruby)
7275
objdir = product_build_dir crossruby
73-
system %Q(make -C "#{objdir}" #{make_args(crossruby).join(" ")} install-rb)
76+
executor.system %Q(make -C "#{objdir}" #{make_args(crossruby).join(" ")} install-rb)
7477
end
7578

7679
def cache_key(digest)
@@ -123,45 +126,48 @@ def initialize(
123126
super(@params.target, @toolchain)
124127
end
125128

126-
def configure(reconfigure: false)
129+
def configure(executor, reconfigure: false)
127130
if !File.exist?("#{build_dir}/Makefile") || reconfigure
128131
args = configure_args(RbConfig::CONFIG["host"], toolchain)
129-
system "#{source.configure_file} #{args.join(" ")}", chdir: build_dir
132+
executor.system "#{source.configure_file} #{args.join(" ")}",
133+
chdir: build_dir
130134
end
131135
# NOTE: we need rbconfig.rb at configuration time to build user given extensions with mkmf
132-
system "make rbconfig.rb", chdir: build_dir
136+
executor.system "make rbconfig.rb", chdir: build_dir
133137
end
134138

135-
def build_exts
136-
@user_exts.each { |prod| prod.build(self) }
137-
FileUtils.mkdir_p File.dirname(extinit_obj)
138-
system %Q(ruby #{extinit_c_erb} #{@user_exts.map(&:name).join(" ")} | #{toolchain.cc} -c -x c - -o #{extinit_obj})
139+
def build_exts(executor)
140+
@user_exts.each { |prod| prod.build(executor, self) }
141+
executor.mkdir_p File.dirname(extinit_obj)
142+
executor.system %Q(ruby #{extinit_c_erb} #{@user_exts.map(&:name).join(" ")} | #{toolchain.cc} -c -x c - -o #{extinit_obj})
139143
end
140144

141-
def build(remake: false, reconfigure: false)
142-
FileUtils.mkdir_p dest_dir
143-
FileUtils.mkdir_p build_dir
145+
def build(executor, remake: false, reconfigure: false)
146+
executor.mkdir_p dest_dir
147+
executor.mkdir_p build_dir
144148
@toolchain.install
145-
[@source, @baseruby, @libyaml, @zlib, @openssl, @wasi_vfs].each(&:build)
146-
configure(reconfigure: reconfigure)
147-
build_exts
149+
[@source, @baseruby, @libyaml, @zlib, @openssl, @wasi_vfs].each do |prod|
150+
prod.build(executor)
151+
end
152+
configure(executor, reconfigure: reconfigure)
153+
build_exts(executor)
148154

149155
install_dir = File.join(build_dir, "install")
150156
if !File.exist?(install_dir) || remake || reconfigure
151-
system "make install DESTDIR=#{install_dir}", chdir: build_dir
157+
executor.system "make install DESTDIR=#{install_dir}", chdir: build_dir
152158
end
153159

154-
FileUtils.rm_rf dest_dir
155-
FileUtils.cp_r install_dir, dest_dir
156-
@user_exts.each { |ext| ext.do_install_rb(self) }
157-
system "tar cfz #{artifact} -C rubies #{name}"
160+
executor.rm_rf dest_dir
161+
executor.cp_r install_dir, dest_dir
162+
@user_exts.each { |ext| ext.do_install_rb(executor, self) }
163+
executor.system "tar cfz #{artifact} -C rubies #{name}"
158164
end
159165

160-
def clean
161-
FileUtils.rm_rf dest_dir
162-
FileUtils.rm_rf build_dir
163-
FileUtils.rm_rf ext_build_dir
164-
FileUtils.rm_f artifact
166+
def clean(executor)
167+
executor.rm_rf dest_dir
168+
executor.rm_rf build_dir
169+
executor.rm_rf ext_build_dir
170+
executor.rm_f artifact
165171
end
166172

167173
def name

lib/ruby_wasm/build/product/libyaml.rb

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,22 @@ def name
2828
product_build_dir
2929
end
3030

31-
def build
31+
def build(executor)
3232
return if Dir.exist?(install_root)
3333

34-
FileUtils.mkdir_p File.dirname(product_build_dir)
35-
FileUtils.rm_rf product_build_dir
36-
system "curl -L https://github.com/yaml/libyaml/releases/download/#{LIBYAML_VERSION}/yaml-#{LIBYAML_VERSION}.tar.gz | tar xz",
37-
chdir: File.dirname(product_build_dir)
34+
executor.mkdir_p File.dirname(product_build_dir)
35+
executor.rm_rf product_build_dir
36+
executor.system "curl -L https://github.com/yaml/libyaml/releases/download/#{LIBYAML_VERSION}/yaml-#{LIBYAML_VERSION}.tar.gz | tar xz",
37+
chdir: File.dirname(product_build_dir)
3838

3939
# obtain the latest config.guess and config.sub for Emscripten and WASI triple support
40-
system "curl -o #{product_build_dir}/config/config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'"
41-
system "curl -o #{product_build_dir}/config/config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'"
40+
executor.system "curl -o #{product_build_dir}/config/config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'"
41+
executor.system "curl -o #{product_build_dir}/config/config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'"
4242

43-
system "./configure #{configure_args.join(" ")}", chdir: product_build_dir
44-
system "make install DESTDIR=#{destdir}", chdir: product_build_dir
43+
executor.system "./configure #{configure_args.join(" ")}",
44+
chdir: product_build_dir
45+
executor.system "make install DESTDIR=#{destdir}",
46+
chdir: product_build_dir
4547
end
4648
end
4749
end

lib/ruby_wasm/build/product/openssl.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,20 @@ def configure_args
5454
args + tools_args
5555
end
5656

57-
def build
57+
def build(executor)
5858
return if Dir.exist?(install_root)
5959

60-
FileUtils.mkdir_p File.dirname(product_build_dir)
61-
FileUtils.rm_rf product_build_dir
62-
system "curl -L https://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz | tar xz",
63-
chdir: File.dirname(product_build_dir)
60+
executor.mkdir_p File.dirname(product_build_dir)
61+
executor.rm_rf product_build_dir
62+
executor.system "curl -L https://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz | tar xz",
63+
chdir: File.dirname(product_build_dir)
6464

65-
system "./Configure #{configure_args.join(" ")}", chdir: product_build_dir
65+
executor.system "./Configure #{configure_args.join(" ")}",
66+
chdir: product_build_dir
6667
# Use "install_sw" instead of "install" because it tries to install docs and it's very slow.
6768
# OpenSSL build system doesn't have well support for parallel build, so force -j1.
68-
system "make -j1 install_sw DESTDIR=#{destdir}", chdir: product_build_dir
69+
executor.system "make -j1 install_sw DESTDIR=#{destdir}",
70+
chdir: product_build_dir
6971
end
7072
end
7173
end

lib/ruby_wasm/build/product/ruby_source.rb

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,37 +31,39 @@ def configure_file
3131
File.join(src_dir, "configure")
3232
end
3333

34-
def fetch
34+
def fetch(executor)
3535
case @params[:type]
3636
when "github"
3737
repo_url = "https://github.com/#{@params[:repo]}.git"
38-
FileUtils.mkdir_p src_dir
39-
system "git init", chdir: src_dir
40-
system "git remote add origin #{repo_url}", chdir: src_dir
41-
system(
38+
executor.mkdir_p src_dir
39+
executor.system "git init", chdir: src_dir
40+
executor.system "git remote add origin #{repo_url}", chdir: src_dir
41+
executor.system(
4242
"git fetch --depth 1 origin #{@params[:rev]}:origin/#{@params[:rev]}",
4343
chdir: src_dir
4444
) or raise "failed to clone #{repo_url}"
45-
system("git checkout origin/#{@params[:rev]}", chdir: src_dir) or
46-
raise "failed to checkout #{@params[:rev]}"
45+
executor.system(
46+
"git checkout origin/#{@params[:rev]}",
47+
chdir: src_dir
48+
) or raise "failed to checkout #{@params[:rev]}"
4749
when "local"
48-
FileUtils.mkdir_p File.dirname(src_dir)
49-
FileUtils.cp_r @params[:src], src_dir
50+
executor.mkdir_p File.dirname(src_dir)
51+
executor.cp_r @params[:src], src_dir
5052
else
5153
raise "unknown source type: #{@params[:type]}"
5254
end
5355
(@params[:patches] || []).each do |patch_path|
54-
system "patch -p1 < #{patch_path}", chdir: src_dir
56+
executor.system "patch -p1 < #{patch_path}", chdir: src_dir
5557
end
5658
end
5759

58-
def build
59-
fetch unless File.exist?(src_dir)
60+
def build(executor)
61+
fetch(executor) unless File.exist?(src_dir)
6062
unless File.exist?(configure_file)
6163
Dir.chdir(src_dir) do
62-
system "ruby tool/downloader.rb -d tool -e gnu config.guess config.sub" or
64+
executor.system "ruby tool/downloader.rb -d tool -e gnu config.guess config.sub" or
6365
raise "failed to download config.guess and config.sub"
64-
system "./autogen.sh" or raise "failed to run autogen.sh"
66+
executor.system "./autogen.sh" or raise "failed to run autogen.sh"
6567
end
6668
end
6769
end

lib/ruby_wasm/build/product/wasi_vfs.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,16 @@ def name
4040
lib_product_build_dir
4141
end
4242

43-
def build
43+
def build(executor)
4444
return if !@need_fetch_lib || File.exist?(lib_wasi_vfs_a)
4545
require "tmpdir"
4646
lib_wasi_vfs_url =
4747
"https://github.com/kateinoigakukun/wasi-vfs/releases/download/v#{WASI_VFS_VERSION}/libwasi_vfs-wasm32-unknown-unknown.zip"
4848
Dir.mktmpdir do |tmpdir|
49-
system "curl -L #{lib_wasi_vfs_url} -o #{tmpdir}/libwasi_vfs.zip"
50-
system "unzip #{tmpdir}/libwasi_vfs.zip -d #{tmpdir}"
51-
FileUtils.mkdir_p File.dirname(lib_wasi_vfs_a)
52-
FileUtils.mv File.join(tmpdir, "libwasi_vfs.a"), lib_wasi_vfs_a
49+
executor.system "curl -L #{lib_wasi_vfs_url} -o #{tmpdir}/libwasi_vfs.zip"
50+
executor.system "unzip #{tmpdir}/libwasi_vfs.zip -d #{tmpdir}"
51+
executor.mkdir_p File.dirname(lib_wasi_vfs_a)
52+
executor.mv File.join(tmpdir, "libwasi_vfs.a"), lib_wasi_vfs_a
5353
end
5454
end
5555

lib/ruby_wasm/build/product/zlib.rb

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,20 @@ def configure_args
3434
args + tools_args
3535
end
3636

37-
def build
37+
def build(executor)
3838
return if Dir.exist?(install_root)
3939

40-
FileUtils.mkdir_p File.dirname(product_build_dir)
41-
FileUtils.rm_rf product_build_dir
40+
executor.mkdir_p File.dirname(product_build_dir)
41+
executor.rm_rf product_build_dir
4242

43-
system "curl -L https://zlib.net/zlib-#{ZLIB_VERSION}.tar.gz | tar xz",
44-
chdir: File.dirname(product_build_dir),
45-
exception: true
43+
executor.system "curl -L https://zlib.net/zlib-#{ZLIB_VERSION}.tar.gz | tar xz",
44+
chdir: File.dirname(product_build_dir),
45+
exception: true
4646

47-
system "#{configure_args.join(" ")} ./configure --static",
48-
chdir: product_build_dir
49-
system "make install DESTDIR=#{destdir}", chdir: product_build_dir
47+
executor.system "#{configure_args.join(" ")} ./configure --static",
48+
chdir: product_build_dir
49+
executor.system "make install DESTDIR=#{destdir}",
50+
chdir: product_build_dir
5051
end
5152
end
5253
end

lib/ruby_wasm/rake_task.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,22 @@ def initialize(
7171
@crossruby.with_wasi_vfs @wasi_vfs
7272
@crossruby.with_openssl @openssl
7373

74+
executor = RubyWasm::BuildExecutor.new
75+
7476
desc "Cross-build Ruby for #{@target}"
7577
task name do
7678
next if File.exist? @crossruby.artifact
77-
@crossruby.build
79+
@crossruby.build(executor)
7880
end
7981
namespace name do
8082
task :remake do
81-
@crossruby.build(remake: true)
83+
@crossruby.build(executor, remake: true)
8284
end
8385
task :reconfigure do
84-
@crossruby.build(reconfigure: true)
86+
@crossruby.build(executor, reconfigure: true)
8587
end
8688
task :clean do
87-
@crossruby.clean
89+
@crossruby.clean(executor)
8890
end
8991
end
9092
end

0 commit comments

Comments
 (0)