Skip to content

Commit 7b26fbe

Browse files
Allow out-of-source build (#43)
* move deps intermediate build directories to build/{triplet} * reduce use of base_dir * find extinit.c.erb by relative reference from the current file * remove unnecessary CrossRubyExtProduct.new * inject ext source directory from outside * reduce use of base_dir * reduce use of base_dir * remove use of install_dir * parameterize build_dir and rubies_dir * install baseruby inside its product build dir
1 parent fc56a37 commit 7b26fbe

File tree

7 files changed

+104
-89
lines changed

7 files changed

+104
-89
lines changed

Rakefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,16 @@ BUILDS = [
4343
{ src: "head", target: "wasm32-unknown-emscripten", profile: "full" },
4444
]
4545

46+
LIB_ROOT = File.dirname(__FILE__)
47+
4648
namespace :build do
4749
BUILDS.each do |params|
4850
name = "#{params[:src]}-#{params[:target]}-#{params[:profile]}"
4951
source = BUILD_SOURCES[params[:src]].merge(name: params[:src])
5052
toolchain = RubyWasm::Toolchain.get params[:target]
5153
user_exts = BUILD_PROFILES[params[:profile]][:user_exts].map do |ext|
52-
RubyWasm::CrossRubyExtProduct.new(ext, toolchain)
54+
srcdir = File.join(LIB_ROOT, "ext", ext)
55+
RubyWasm::CrossRubyExtProduct.new(srcdir, toolchain)
5356
end
5457
options = params
5558
.merge(BUILD_PROFILES[params[:profile]])

lib/ruby_wasm/build_system/product/baseruby.rb

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,41 @@
33

44
module RubyWasm
55
class BaseRubyProduct < BuildProduct
6-
attr_reader :base_dir, :source, :install_task
6+
attr_reader :source, :install_task
77

8-
def initialize(channel, base_dir, source)
9-
@channel = channel
10-
@base_dir = base_dir
8+
def initialize(build_dir, source)
9+
@build_dir = build_dir
1110
@source = source
11+
@channel = source.name
12+
end
13+
14+
def product_build_dir
15+
File.join(@build_dir, RbConfig::CONFIG["host"], "baseruby-#{@channel}")
1216
end
1317

1418
def install_dir
15-
File.join(
16-
base_dir,
17-
"/build/deps/#{RbConfig::CONFIG["host"]}/opt/baseruby-#{@channel}"
18-
)
19+
File.join(product_build_dir, "opt")
1920
end
2021

2122
def name
2223
"baseruby-#{@channel}"
2324
end
2425

2526
def define_task
26-
baseruby_build_dir =
27-
File.join(
28-
base_dir,
29-
"/build/deps/#{RbConfig::CONFIG["host"]}/baseruby-#{@channel}"
30-
)
3127

32-
directory baseruby_build_dir
28+
directory product_build_dir
3329

3430
desc "build baseruby #{@channel}"
3531
@install_task =
3632
task name => [
3733
source.src_dir,
3834
source.configure_file,
39-
baseruby_build_dir
35+
product_build_dir
4036
] do
4137
next if Dir.exist?(install_dir)
4238
sh "#{source.configure_file} --prefix=#{install_dir} --disable-install-doc",
43-
chdir: baseruby_build_dir
44-
sh "make install", chdir: baseruby_build_dir
39+
chdir: product_build_dir
40+
sh "make install", chdir: product_build_dir
4541
end
4642
end
4743
end

lib/ruby_wasm/build_system/product/crossruby.rb

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33

44
module RubyWasm
55
class CrossRubyExtProduct < BuildProduct
6-
attr_reader :name, :toolchain
7-
def initialize(name, toolchain)
8-
@name, @toolchain = name, toolchain
6+
attr_reader :name, :srcdir
7+
def initialize(srcdir, toolchain, name: nil)
8+
@srcdir, @toolchain = srcdir, toolchain
9+
@name = name || File.basename(srcdir)
910
end
1011

1112
def define_task(crossruby)
1213
task "#{crossruby.name}-ext-#{@name}" => [crossruby.configure] do
1314
make_args = []
14-
make_args << "CC=#{toolchain.cc}"
15-
make_args << "RANLIB=#{toolchain.ranlib}"
16-
make_args << "LD=#{toolchain.ld}"
17-
make_args << "AR=#{toolchain.ar}"
15+
make_args << "CC=#{@toolchain.cc}"
16+
make_args << "LD=#{@toolchain.ld}"
17+
make_args << "AR=#{@toolchain.ar}"
18+
make_args << "RANLIB=#{@toolchain.ranlib}"
1819

1920
lib = @name
2021
source = crossruby.source
2122
objdir = "#{crossruby.ext_build_dir}/#{lib}"
2223
FileUtils.mkdir_p objdir
23-
srcdir = "#{crossruby.base_dir}/ext/#{lib}"
2424
extconf_args = [
2525
"--disable=gems",
2626
# HACK: top_srcdir is required to find ruby headers
@@ -36,9 +36,9 @@ def define_task(crossruby)
3636
# and we want to insert some hacks before it. But -e and $0 cannot be
3737
# used together, so we rewrite $0 in -e.
3838
"-e",
39-
%Q('$0="#{srcdir}/extconf.rb"'),
39+
%Q('$0="#{@srcdir}/extconf.rb"'),
4040
"-e",
41-
%Q('require_relative "#{srcdir}/extconf.rb"'),
41+
%Q('require_relative "#{@srcdir}/extconf.rb"'),
4242
"-I#{crossruby.build_dir}"
4343
]
4444
sh "#{crossruby.baseruby_path} #{extconf_args.join(" ")}", chdir: objdir
@@ -56,11 +56,12 @@ def define_task(crossruby)
5656
end
5757

5858
class CrossRubyProduct < BuildProduct
59-
attr_reader :base_dir, :source, :toolchain, :build, :configure
59+
attr_reader :source, :toolchain, :build, :configure
6060

61-
def initialize(params, base_dir, baseruby, source, toolchain)
61+
def initialize(params, build_dir, rubies_dir, baseruby, source, toolchain)
6262
@params = params
63-
@base_dir = base_dir
63+
@rubies_dir = rubies_dir
64+
@build_dir = build_dir
6465
@baseruby = baseruby
6566
@source = source
6667
@toolchain = toolchain
@@ -89,14 +90,14 @@ def define_task
8990
user_ext_products = @params.user_exts
9091
user_ext_tasks = user_ext_products.map { |prod| prod.define_task(self) }
9192
user_ext_names = user_ext_products.map(&:name)
92-
user_exts =
93-
task "#{name}-libs" => [@configure] + user_ext_tasks do
93+
extinit_task =
94+
task extinit_obj => [@configure, extinit_c_erb] + user_ext_tasks do
9495
mkdir_p File.dirname(extinit_obj)
95-
sh %Q(ruby #{base_dir}/ext/extinit.c.erb #{user_ext_names.join(" ")} | #{toolchain.cc} -c -x c - -o #{extinit_obj})
96+
sh %Q(ruby #{extinit_c_erb} #{user_ext_names.join(" ")} | #{toolchain.cc} -c -x c - -o #{extinit_obj})
9697
end
9798

9899
install =
99-
task "#{name}-install" => [@configure, user_exts, dest_dir] do
100+
task "#{name}-install" => [@configure, extinit_task, dest_dir] do
100101
next if File.exist?("#{dest_dir}-install")
101102
sh "make install DESTDIR=#{dest_dir}-install", chdir: build_dir
102103
end
@@ -110,10 +111,11 @@ def define_task
110111
ruby_api_version =
111112
`#{baseruby_path} -e 'print RbConfig::CONFIG["ruby_version"]'`
112113
# TODO: move copying logic to ext product
113-
user_ext_names.each do |lib|
114-
next unless File.exist?("ext/#{lib}/lib")
114+
user_ext_products.each do |ext|
115+
ext_lib = File.join(ext.srcdir, "lib")
116+
next unless File.exist?(ext_lib)
115117
cp_r(
116-
File.join(base_dir, "ext/#{lib}/lib/."),
118+
File.join(ext_lib, "."),
117119
File.join(dest_dir, "usr/local/lib/ruby/#{ruby_api_version}")
118120
)
119121
end
@@ -126,11 +128,11 @@ def name
126128
end
127129

128130
def build_dir
129-
"#{@base_dir}/build/build/#{name}"
131+
File.join(@build_dir, @params.target, name)
130132
end
131133

132134
def ext_build_dir
133-
"#{@base_dir}/build/ext-build/#{name}"
135+
File.join(@build_dir, @params.target, name + "-ext")
134136
end
135137

136138
def with_libyaml(libyaml)
@@ -144,13 +146,18 @@ def with_zlib(zlib)
144146
end
145147

146148
def dest_dir
147-
"#{@base_dir}/rubies/#{name}"
149+
File.join(@rubies_dir, name)
148150
end
149151

150152
def extinit_obj
151153
"#{ext_build_dir}/extinit.o"
152154
end
153155

156+
def extinit_c_erb
157+
lib_root = File.expand_path("../../../../..", __FILE__)
158+
File.join(lib_root, "ext", "extinit.c.erb")
159+
end
160+
154161
def baseruby_path
155162
File.join(@baseruby.install_dir, "bin/ruby")
156163
end

lib/ruby_wasm/build_system/product/libyaml.rb

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,49 @@
33

44
module RubyWasm
55
class LibYAMLProduct < AutoconfProduct
6-
attr_reader :base_dir, :install_dir, :target, :install_task
6+
attr_reader :target, :install_task
77

8-
def initialize(base_dir, install_dir, target, toolchain)
9-
@base_dir = base_dir
10-
@install_dir = install_dir
8+
LIBYAML_VERSION = "0.2.5"
9+
10+
def initialize(build_dir, target, toolchain)
11+
@build_dir = build_dir
1112
@target = target
1213
super(target, toolchain)
1314
end
1415

16+
def product_build_dir
17+
File.join(@build_dir, target, "yaml-#{LIBYAML_VERSION}")
18+
end
19+
20+
def destdir
21+
File.join(product_build_dir, "opt")
22+
end
23+
1524
def install_root
16-
File.join(install_dir, "usr/local")
25+
File.join(destdir, "usr", "local")
1726
end
1827

1928
def name
2029
"libyaml-#{target}"
2130
end
2231

2332
def define_task
24-
libyaml_version = "0.2.5"
25-
desc "build libyaml #{libyaml_version} for #{target}"
33+
desc "build libyaml #{LIBYAML_VERSION} for #{target}"
2634
@install_task =
2735
task(name) do
2836
next if Dir.exist?(install_root)
2937

30-
build_dir =
31-
File.join(base_dir, "/build/deps/#{target}/yaml-#{libyaml_version}")
32-
mkdir_p File.dirname(build_dir)
33-
rm_rf build_dir
34-
sh "curl -L https://github.com/yaml/libyaml/releases/download/#{libyaml_version}/yaml-#{libyaml_version}.tar.gz | tar xz",
35-
chdir: File.dirname(build_dir)
38+
mkdir_p File.dirname(product_build_dir)
39+
rm_rf product_build_dir
40+
sh "curl -L https://github.com/yaml/libyaml/releases/download/#{LIBYAML_VERSION}/yaml-#{LIBYAML_VERSION}.tar.gz | tar xz",
41+
chdir: File.dirname(product_build_dir)
3642

3743
# obtain the latest config.guess and config.sub for Emscripten and WASI triple support
38-
sh "curl -o #{build_dir}/config/config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'"
39-
sh "curl -o #{build_dir}/config/config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'"
44+
sh "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'"
45+
sh "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'"
4046

41-
sh "./configure #{configure_args.join(" ")}", chdir: build_dir
42-
sh "make install DESTDIR=#{install_dir}", chdir: build_dir
47+
sh "./configure #{configure_args.join(" ")}", chdir: product_build_dir
48+
sh "make install DESTDIR=#{destdir}", chdir: product_build_dir
4349
end
4450
end
4551
end

lib/ruby_wasm/build_system/product/ruby_source.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33

44
module RubyWasm
55
class BuildSource < BuildProduct
6-
def initialize(params, base_dir)
6+
def initialize(params, build_dir)
77
@params = params
8-
@base_dir = base_dir
8+
@build_dir = build_dir
99
end
1010

1111
def name
1212
@params[:name]
1313
end
1414

1515
def src_dir
16-
"#{@base_dir}/build/src/#{@params[:name]}"
16+
File.join(@build_dir, "checkouts", @params[:name])
1717
end
1818

1919
def configure_file
20-
"#{src_dir}/configure"
20+
File.join(src_dir, "configure")
2121
end
2222

2323
def fetch

lib/ruby_wasm/build_system/product/zlib.rb

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,47 @@
33

44
module RubyWasm
55
class ZlibProduct < AutoconfProduct
6-
attr_reader :base_dir, :install_dir, :target, :install_task
6+
attr_reader :target, :install_task
77

8-
def initialize(base_dir, install_dir, target, toolchain)
9-
@base_dir = base_dir
10-
@install_dir = install_dir
8+
ZLIB_VERSION = "1.2.12"
9+
10+
def initialize(build_dir, target, toolchain)
11+
@build_dir = build_dir
1112
@target = target
1213
super(target, toolchain)
1314
end
1415

16+
def product_build_dir
17+
File.join(@build_dir, target, "zlib-#{ZLIB_VERSION}")
18+
end
19+
20+
def destdir
21+
File.join(product_build_dir, "opt")
22+
end
23+
1524
def install_root
16-
File.join(install_dir, "zlib")
25+
File.join(destdir, "usr", "local")
1726
end
1827

1928
def name
2029
"zlib-#{target}"
2130
end
2231

2332
def define_task
24-
zlib_version = "1.2.12"
25-
desc "build zlib #{zlib_version} for #{target}"
33+
desc "build zlib #{ZLIB_VERSION} for #{target}"
2634
@install_task =
2735
task(name) do
2836
next if Dir.exist?(install_root)
2937

30-
build_dir =
31-
File.join(base_dir, "/build/deps/#{target}/zlib-#{zlib_version}")
32-
mkdir_p File.dirname(build_dir)
33-
rm_rf build_dir
38+
mkdir_p File.dirname(product_build_dir)
39+
rm_rf product_build_dir
3440

35-
sh "curl -L https://zlib.net/zlib-#{zlib_version}.tar.gz | tar xz",
36-
chdir: File.dirname(build_dir)
41+
sh "curl -L https://zlib.net/zlib-#{ZLIB_VERSION}.tar.gz | tar xz",
42+
chdir: File.dirname(product_build_dir)
3743

38-
sh "#{tools_args.join(" ")} ./configure --prefix=#{install_root} --static",
39-
chdir: build_dir
40-
sh "make install", chdir: build_dir
44+
sh "#{tools_args.join(" ")} ./configure --static",
45+
chdir: product_build_dir
46+
sh "make install DESTDIR=#{destdir}", chdir: product_build_dir
4147
end
4248
end
4349
end

lib/ruby_wasm/rake_task.rb

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,24 @@
33

44
class RubyWasm::BuildTask < ::Rake::TaskLib
55

6-
def initialize(name, target:, src:, extensions: [], toolchain: nil, **options, &task_block)
7-
base_dir = Dir.pwd
8-
install_dir = File.join(base_dir, "/build/deps/#{target}/opt")
6+
def initialize(name, target:, src:, extensions: [], toolchain: nil, build_dir: nil, rubies_dir: nil, **options, &task_block)
7+
build_dir ||= File.join(Dir.pwd, "build")
8+
rubies_dir ||= File.join(Dir.pwd, "rubies")
99
toolchain ||= RubyWasm::Toolchain.get target
1010

11-
libyaml = add_product RubyWasm::LibYAMLProduct.new(base_dir, install_dir, target, toolchain)
12-
zlib = add_product RubyWasm::ZlibProduct.new(base_dir, install_dir, target, toolchain)
11+
libyaml = add_product RubyWasm::LibYAMLProduct.new(build_dir, target, toolchain)
12+
zlib = add_product RubyWasm::ZlibProduct.new(build_dir, target, toolchain)
1313

14-
source = add_product RubyWasm::BuildSource.new(src, base_dir)
15-
baseruby = add_product RubyWasm::BaseRubyProduct.new(name, base_dir, source)
14+
source = add_product RubyWasm::BuildSource.new(src, build_dir)
15+
baseruby = add_product RubyWasm::BaseRubyProduct.new(build_dir, source)
1616

1717
build_params = RubyWasm::BuildParams.new(
1818
options.merge(
1919
name: name, src: source, target: target, user_exts: extensions
2020
)
2121
)
2222

23-
exts = extensions.map do |ext|
24-
RubyWasm::CrossRubyExtProduct.new(ext, toolchain)
25-
end
26-
product = RubyWasm::CrossRubyProduct.new(build_params, base_dir, baseruby, source, toolchain)
23+
product = RubyWasm::CrossRubyProduct.new(build_params, build_dir, rubies_dir, baseruby, source, toolchain)
2724
product.with_libyaml libyaml
2825
product.with_zlib zlib
2926
product.define_task

0 commit comments

Comments
 (0)