From 1e1f70c3710542f04b0f97065d470ea49e7cbbef Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Wed, 11 May 2022 05:18:01 +0000 Subject: [PATCH] build: build with baseruby that is compiled from the same source The system installed Ruby (especially Debian) can override `Gem.default_dir` to lookup gems installed by the OS package managers. And `rbinstall.rb` respects `Gem.default_dir` to select install directory of gems under `DESTDIR`. So it installs gems in `DESTDIR/var/lib/gems/3.2.0+1` where the Debian's `operating_system.rb` specifies. However, `Gem.default_dir` is not overridden at runtime on Wasm, so it lookups `DESTDIR/usr/local/lib/ruby/gems/3.2.0+1` instead. The mismatch of `default_dir` between install-time and runtime causes the failure of gem lookup. To fix this mismatch, stop using system packaged ruby to avoid loading `operating_system.rb`, and use self-built ruby, which doesn't patch `Gem.default_dir`. This change also makes our build compatible with cross-compilation prerequisite: https://bugs.ruby-lang.org/projects/ruby/wiki/DeveloperHowto#prerequisite --- Rakefile | 25 +++++++++++++++++-- builders/wasm32-unknown-emscripten/Dockerfile | 2 +- builders/wasm32-unknown-wasi/Dockerfile | 2 +- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Rakefile b/Rakefile index 0033b6b54..f975b7af7 100644 --- a/Rakefile +++ b/Rakefile @@ -105,9 +105,17 @@ class BuildPlan "#{ext_build_dir}/extinit.o" end + def baseruby_name + "baseruby-#{@params[:src]}" + end + + def baseruby_path + "#{@base_dir}/build/deps/#{RbConfig::CONFIG["host"]}/opt/#{baseruby_name}/bin/ruby" + end + def dep_tasks - return [] if @params[:profile] == "minimal" - ["deps:libyaml-#{@params[:target]}"] + return [baseruby_name] if @params[:profile] == "minimal" + [baseruby_name, "deps:libyaml-#{@params[:target]}"] end def check_deps @@ -149,6 +157,7 @@ class BuildPlan args << "--with-static-linked-ext" args << %Q(--with-ext="#{default_exts}") args << %Q(--with-libyaml-dir="#{deps_install_dir}/libyaml/usr/local") + args << %Q(--with-baseruby="#{baseruby_path}") case target when "wasm32-unknown-wasi" @@ -226,6 +235,18 @@ namespace :build do file source.configure_file => [source.src_dir] do sh "./autogen.sh", chdir: source.src_dir end + + baseruby_install_dir = File.join(Dir.pwd, "/build/deps/#{RbConfig::CONFIG["host"]}/opt/baseruby-#{name}") + baseruby_build_dir = File.join(Dir.pwd, "/build/deps/#{RbConfig::CONFIG["host"]}/baseruby-#{name}") + + directory baseruby_build_dir + + desc "build baseruby #{name}" + task "baseruby-#{name}" => [source.src_dir, source.configure_file, baseruby_build_dir] do + next if Dir.exist?(baseruby_install_dir) + sh "#{source.configure_file} --prefix=#{baseruby_install_dir} --disable-install-doc", chdir: baseruby_build_dir + sh "make install", chdir: baseruby_build_dir + end end BUILDS.each do |params| diff --git a/builders/wasm32-unknown-emscripten/Dockerfile b/builders/wasm32-unknown-emscripten/Dockerfile index 601659690..c14de5de9 100644 --- a/builders/wasm32-unknown-emscripten/Dockerfile +++ b/builders/wasm32-unknown-emscripten/Dockerfile @@ -2,7 +2,7 @@ FROM emscripten/emsdk:2.0.13 RUN set -eux; \ apt-get update; \ - apt-get install ruby bison make autoconf git curl -y; \ + apt-get install ruby bison make autoconf git curl build-essential libyaml-dev -y; \ curl -fsSL https://deb.nodesource.com/setup_16.x | bash -; \ apt-get install nodejs -y; \ apt-get clean; \ diff --git a/builders/wasm32-unknown-wasi/Dockerfile b/builders/wasm32-unknown-wasi/Dockerfile index c7b527339..3b924380e 100644 --- a/builders/wasm32-unknown-wasi/Dockerfile +++ b/builders/wasm32-unknown-wasi/Dockerfile @@ -17,7 +17,7 @@ ENV WASI_SDK_PATH="/opt/wasi-sdk" RUN set -eux; \ apt-get update; \ - apt-get install ruby bison make autoconf git curl -y; \ + apt-get install ruby bison make autoconf git curl build-essential libyaml-dev -y; \ curl -fsSL https://deb.nodesource.com/setup_16.x | bash -; \ apt-get install nodejs -y; \ apt-get clean; \