ruby_wasm 2.5.0-x86_64-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 +126 -0
 - data/Gemfile +17 -0
 - data/LICENSE +21 -0
 - data/NOTICE +1293 -0
 - data/README.md +153 -0
 - data/Rakefile +163 -0
 - data/Steepfile +24 -0
 - data/benchmarks/vm_deep_call.rb +55 -0
 - data/builders/wasm32-unknown-emscripten/Dockerfile +43 -0
 - data/builders/wasm32-unknown-emscripten/entrypoint.sh +7 -0
 - data/builders/wasm32-unknown-wasi/Dockerfile +47 -0
 - data/builders/wasm32-unknown-wasi/entrypoint.sh +7 -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.0/ruby_wasm.so +0 -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/build/build_params.rb +3 -0
 - data/lib/ruby_wasm/build/downloader.rb +18 -0
 - data/lib/ruby_wasm/build/executor.rb +187 -0
 - data/lib/ruby_wasm/build/product/baseruby.rb +37 -0
 - data/lib/ruby_wasm/build/product/crossruby.rb +330 -0
 - data/lib/ruby_wasm/build/product/libyaml.rb +68 -0
 - data/lib/ruby_wasm/build/product/openssl.rb +88 -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 +68 -0
 - data/lib/ruby_wasm/build/product.rb +8 -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 +88 -0
 - data/lib/ruby_wasm/cli.rb +217 -0
 - data/lib/ruby_wasm/packager/core.rb +156 -0
 - data/lib/ruby_wasm/packager/file_system.rb +158 -0
 - data/lib/ruby_wasm/packager.rb +159 -0
 - data/lib/ruby_wasm/rake_task.rb +59 -0
 - data/lib/ruby_wasm/util.rb +15 -0
 - data/lib/ruby_wasm/version.rb +3 -0
 - data/lib/ruby_wasm.rb +33 -0
 - data/package-lock.json +9500 -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 +151 -0
 - data/rakelib/version.rake +40 -0
 - data/sig/open_uri.rbs +4 -0
 - data/sig/ruby_wasm/build.rbs +318 -0
 - data/sig/ruby_wasm/cli.rbs +27 -0
 - data/sig/ruby_wasm/ext.rbs +13 -0
 - data/sig/ruby_wasm/packager.rbs +91 -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,68 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative "./product"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RubyWasm
         
     | 
| 
      
 4 
     | 
    
         
            +
              class ZlibProduct < AutoconfProduct
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :target
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                ZLIB_VERSION = "1.3.1"
         
     | 
| 
      
 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, "zlib-#{ZLIB_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 
     | 
    
         
            +
                  "zlib-#{ZLIB_VERSION}-#{target}"
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def configure_args
         
     | 
| 
      
 32 
     | 
    
         
            +
                  args = %w[CHOST=linux]
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  args + tools_args
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def build(executor)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  return if Dir.exist?(install_root)
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  executor.mkdir_p File.dirname(product_build_dir)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  executor.rm_rf product_build_dir
         
     | 
| 
      
 42 
     | 
    
         
            +
                  executor.mkdir_p product_build_dir
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  tarball_path = File.join(product_build_dir, "zlib-#{ZLIB_VERSION}.tar.gz")
         
     | 
| 
      
 45 
     | 
    
         
            +
                  executor.system "curl",
         
     | 
| 
      
 46 
     | 
    
         
            +
                                  "-o",
         
     | 
| 
      
 47 
     | 
    
         
            +
                                  tarball_path,
         
     | 
| 
      
 48 
     | 
    
         
            +
                                  "-L",
         
     | 
| 
      
 49 
     | 
    
         
            +
                                  "https://github.com/madler/zlib/releases/download/v#{ZLIB_VERSION}/zlib-#{ZLIB_VERSION}.tar.gz"
         
     | 
| 
      
 50 
     | 
    
         
            +
                  executor.system "tar",
         
     | 
| 
      
 51 
     | 
    
         
            +
                                  "xzf",
         
     | 
| 
      
 52 
     | 
    
         
            +
                                  tarball_path,
         
     | 
| 
      
 53 
     | 
    
         
            +
                                  "-C",
         
     | 
| 
      
 54 
     | 
    
         
            +
                                  product_build_dir,
         
     | 
| 
      
 55 
     | 
    
         
            +
                                  "--strip-components=1"
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  executor.system "env",
         
     | 
| 
      
 58 
     | 
    
         
            +
                                  *configure_args,
         
     | 
| 
      
 59 
     | 
    
         
            +
                                  "./configure",
         
     | 
| 
      
 60 
     | 
    
         
            +
                                  "--static",
         
     | 
| 
      
 61 
     | 
    
         
            +
                                  chdir: product_build_dir
         
     | 
| 
      
 62 
     | 
    
         
            +
                  executor.system "make",
         
     | 
| 
      
 63 
     | 
    
         
            +
                                  "install",
         
     | 
| 
      
 64 
     | 
    
         
            +
                                  "DESTDIR=#{destdir}",
         
     | 
| 
      
 65 
     | 
    
         
            +
                                  chdir: product_build_dir
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,8 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative "product/product"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative "product/ruby_source"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "product/baseruby"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "product/zlib"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative "product/libyaml"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative "product/openssl"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require_relative "product/wasi_vfs"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative "product/crossruby"
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RubyWasm
         
     | 
| 
      
 2 
     | 
    
         
            +
              class WitBindgen
         
     | 
| 
      
 3 
     | 
    
         
            +
                attr_reader :bin_path
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize(
         
     | 
| 
      
 6 
     | 
    
         
            +
                  build_dir:,
         
     | 
| 
      
 7 
     | 
    
         
            +
                  revision: "251e84b89121751f79ac268629e9285082b2596d"
         
     | 
| 
      
 8 
     | 
    
         
            +
                )
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @build_dir = build_dir
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @tool_dir = File.join(@build_dir, "toolchain", "wit-bindgen")
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @bin_path = File.join(@tool_dir, "bin", "wit-bindgen")
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @revision = revision
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def install
         
     | 
| 
      
 16 
     | 
    
         
            +
                  return if File.exist?(@bin_path)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  RubyWasm::Toolchain.check_executable("cargo")
         
     | 
| 
      
 18 
     | 
    
         
            +
                  Kernel.system(
         
     | 
| 
      
 19 
     | 
    
         
            +
                    "cargo",
         
     | 
| 
      
 20 
     | 
    
         
            +
                    "install",
         
     | 
| 
      
 21 
     | 
    
         
            +
                    "--git",
         
     | 
| 
      
 22 
     | 
    
         
            +
                    "https://github.com/bytecodealliance/wit-bindgen",
         
     | 
| 
      
 23 
     | 
    
         
            +
                    "--rev",
         
     | 
| 
      
 24 
     | 
    
         
            +
                    @revision,
         
     | 
| 
      
 25 
     | 
    
         
            +
                    "--root",
         
     | 
| 
      
 26 
     | 
    
         
            +
                    @tool_dir,
         
     | 
| 
      
 27 
     | 
    
         
            +
                    "wit-bindgen-cli"
         
     | 
| 
      
 28 
     | 
    
         
            +
                  )
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,193 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative "./toolchain/wit_bindgen"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RubyWasm
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Toolchain
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :name
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @tools = {}
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def find_tool(name)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  raise "not implemented"
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def check_envvar(name)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  raise "missing environment variable: #{name}" if ENV[name].nil?
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def self.get(target, build_dir = nil)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  case target
         
     | 
| 
      
 21 
     | 
    
         
            +
                  when "wasm32-unknown-wasi"
         
     | 
| 
      
 22 
     | 
    
         
            +
                    return RubyWasm::WASISDK.new(build_dir: build_dir)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  when "wasm32-unknown-emscripten"
         
     | 
| 
      
 24 
     | 
    
         
            +
                    return RubyWasm::Emscripten.new
         
     | 
| 
      
 25 
     | 
    
         
            +
                  else
         
     | 
| 
      
 26 
     | 
    
         
            +
                    raise "unknown target: #{target}"
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def self.find_path(command)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  (ENV["PATH"] || "")
         
     | 
| 
      
 32 
     | 
    
         
            +
                    .split(File::PATH_SEPARATOR)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    .each do |path_dir|
         
     | 
| 
      
 34 
     | 
    
         
            +
                      bin_path = File.join(path_dir, command)
         
     | 
| 
      
 35 
     | 
    
         
            +
                      return bin_path if File.executable?(bin_path)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def self.check_executable(command)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  tool = find_path(command)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  raise "missing executable: #{command}" unless tool
         
     | 
| 
      
 43 
     | 
    
         
            +
                  tool
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                %i[cc ranlib ld ar].each do |name|
         
     | 
| 
      
 47 
     | 
    
         
            +
                  define_method(name) do
         
     | 
| 
      
 48 
     | 
    
         
            +
                    @tools_cache ||= {}
         
     | 
| 
      
 49 
     | 
    
         
            +
                    @tools_cache[name] ||= find_tool(name)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    @tools_cache[name]
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              class WASISDK < Toolchain
         
     | 
| 
      
 56 
     | 
    
         
            +
                def initialize(
         
     | 
| 
      
 57 
     | 
    
         
            +
                  wasi_sdk_path = ENV["WASI_SDK_PATH"],
         
     | 
| 
      
 58 
     | 
    
         
            +
                  build_dir: nil,
         
     | 
| 
      
 59 
     | 
    
         
            +
                  version_major: 20,
         
     | 
| 
      
 60 
     | 
    
         
            +
                  version_minor: 0,
         
     | 
| 
      
 61 
     | 
    
         
            +
                  binaryen_version: 108
         
     | 
| 
      
 62 
     | 
    
         
            +
                )
         
     | 
| 
      
 63 
     | 
    
         
            +
                  @wasm_opt_path = Toolchain.find_path("wasm-opt")
         
     | 
| 
      
 64 
     | 
    
         
            +
                  @need_fetch_wasi_sdk = wasi_sdk_path.nil?
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @need_fetch_binaryen = @wasm_opt_path.nil?
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  if @need_fetch_wasi_sdk
         
     | 
| 
      
 68 
     | 
    
         
            +
                    if build_dir.nil?
         
     | 
| 
      
 69 
     | 
    
         
            +
                      raise "build_dir is required when WASI_SDK_PATH is not set"
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
                    wasi_sdk_path = File.join(build_dir, "toolchain", "wasi-sdk")
         
     | 
| 
      
 72 
     | 
    
         
            +
                    @version_major = version_major
         
     | 
| 
      
 73 
     | 
    
         
            +
                    @version_minor = version_minor
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  if @need_fetch_binaryen
         
     | 
| 
      
 77 
     | 
    
         
            +
                    if build_dir.nil?
         
     | 
| 
      
 78 
     | 
    
         
            +
                      raise "build_dir is required when wasm-opt not installed in PATH"
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
                    @binaryen_path = File.join(build_dir, "toolchain", "binaryen")
         
     | 
| 
      
 81 
     | 
    
         
            +
                    @binaryen_version = binaryen_version
         
     | 
| 
      
 82 
     | 
    
         
            +
                    @wasm_opt_path = File.join(@binaryen_path, "bin", "wasm-opt")
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                  @tools = {
         
     | 
| 
      
 86 
     | 
    
         
            +
                    cc: "#{wasi_sdk_path}/bin/clang",
         
     | 
| 
      
 87 
     | 
    
         
            +
                    ld: "#{wasi_sdk_path}/bin/clang",
         
     | 
| 
      
 88 
     | 
    
         
            +
                    ar: "#{wasi_sdk_path}/bin/llvm-ar",
         
     | 
| 
      
 89 
     | 
    
         
            +
                    ranlib: "#{wasi_sdk_path}/bin/llvm-ranlib"
         
     | 
| 
      
 90 
     | 
    
         
            +
                  }
         
     | 
| 
      
 91 
     | 
    
         
            +
                  @wasi_sdk_path = wasi_sdk_path
         
     | 
| 
      
 92 
     | 
    
         
            +
                  @name = "wasi-sdk"
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                def find_tool(name)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  if !File.exist?(@tools[name]) && !ENV["WASI_SDK_PATH"].nil?
         
     | 
| 
      
 97 
     | 
    
         
            +
                    raise "missing tool '#{name}' at #{@tools[name]}"
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
                  @tools[name]
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                def wasm_opt
         
     | 
| 
      
 103 
     | 
    
         
            +
                  @wasm_opt_path
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                def wasi_sdk_path
         
     | 
| 
      
 107 
     | 
    
         
            +
                  @wasi_sdk_path
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                def download_url(version_major, version_minor)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  version = "#{version_major}.#{version_minor}"
         
     | 
| 
      
 112 
     | 
    
         
            +
                  assets = [
         
     | 
| 
      
 113 
     | 
    
         
            +
                    [/x86_64-linux/, "wasi-sdk-#{version}-linux.tar.gz"],
         
     | 
| 
      
 114 
     | 
    
         
            +
                    [/(arm64e?|x86_64)-darwin/, "wasi-sdk-#{version}-macos.tar.gz"]
         
     | 
| 
      
 115 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 116 
     | 
    
         
            +
                  asset = assets.find { |os, _| os =~ RUBY_PLATFORM }&.at(1)
         
     | 
| 
      
 117 
     | 
    
         
            +
                  if asset.nil?
         
     | 
| 
      
 118 
     | 
    
         
            +
                    raise "unsupported platform for fetching WASI SDK: #{RUBY_PLATFORM}"
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
                  "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-#{version_major}/#{asset}"
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                def binaryen_download_url(version)
         
     | 
| 
      
 124 
     | 
    
         
            +
                  assets = [
         
     | 
| 
      
 125 
     | 
    
         
            +
                    [
         
     | 
| 
      
 126 
     | 
    
         
            +
                      /x86_64-linux/,
         
     | 
| 
      
 127 
     | 
    
         
            +
                      "binaryen-version_#{@binaryen_version}-x86_64-linux.tar.gz"
         
     | 
| 
      
 128 
     | 
    
         
            +
                    ],
         
     | 
| 
      
 129 
     | 
    
         
            +
                    [
         
     | 
| 
      
 130 
     | 
    
         
            +
                      /x86_64-darwin/,
         
     | 
| 
      
 131 
     | 
    
         
            +
                      "binaryen-version_#{@binaryen_version}-x86_64-macos.tar.gz"
         
     | 
| 
      
 132 
     | 
    
         
            +
                    ],
         
     | 
| 
      
 133 
     | 
    
         
            +
                    [
         
     | 
| 
      
 134 
     | 
    
         
            +
                      /arm64e?-darwin/,
         
     | 
| 
      
 135 
     | 
    
         
            +
                      "binaryen-version_#{@binaryen_version}-arm64-macos.tar.gz"
         
     | 
| 
      
 136 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 137 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 138 
     | 
    
         
            +
                  asset = assets.find { |os, _| os =~ RUBY_PLATFORM }&.at(1)
         
     | 
| 
      
 139 
     | 
    
         
            +
                  if asset.nil?
         
     | 
| 
      
 140 
     | 
    
         
            +
                    raise "unsupported platform for fetching Binaryen: #{RUBY_PLATFORM}"
         
     | 
| 
      
 141 
     | 
    
         
            +
                  end
         
     | 
| 
      
 142 
     | 
    
         
            +
                  "https://github.com/WebAssembly/binaryen/releases/download/version_#{@binaryen_version}/#{asset}"
         
     | 
| 
      
 143 
     | 
    
         
            +
                end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                def install_wasi_sdk
         
     | 
| 
      
 146 
     | 
    
         
            +
                  return unless @need_fetch_wasi_sdk
         
     | 
| 
      
 147 
     | 
    
         
            +
                  wasi_sdk_tarball =
         
     | 
| 
      
 148 
     | 
    
         
            +
                    File.join(File.dirname(@wasi_sdk_path), "wasi-sdk.tar.gz")
         
     | 
| 
      
 149 
     | 
    
         
            +
                  unless File.exist? wasi_sdk_tarball
         
     | 
| 
      
 150 
     | 
    
         
            +
                    FileUtils.mkdir_p File.dirname(wasi_sdk_tarball)
         
     | 
| 
      
 151 
     | 
    
         
            +
                    system "curl -L -o #{wasi_sdk_tarball} #{self.download_url(@version_major, @version_minor)}"
         
     | 
| 
      
 152 
     | 
    
         
            +
                  end
         
     | 
| 
      
 153 
     | 
    
         
            +
                  unless File.exist? @wasi_sdk_path
         
     | 
| 
      
 154 
     | 
    
         
            +
                    FileUtils.mkdir_p @wasi_sdk_path
         
     | 
| 
      
 155 
     | 
    
         
            +
                    system "tar -C #{@wasi_sdk_path} --strip-component 1 -xzf #{wasi_sdk_tarball}"
         
     | 
| 
      
 156 
     | 
    
         
            +
                  end
         
     | 
| 
      
 157 
     | 
    
         
            +
                end
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                def install_binaryen
         
     | 
| 
      
 160 
     | 
    
         
            +
                  return unless @need_fetch_binaryen
         
     | 
| 
      
 161 
     | 
    
         
            +
                  binaryen_tarball = File.expand_path("../binaryen.tar.gz", @binaryen_path)
         
     | 
| 
      
 162 
     | 
    
         
            +
                  unless File.exist? binaryen_tarball
         
     | 
| 
      
 163 
     | 
    
         
            +
                    FileUtils.mkdir_p File.dirname(binaryen_tarball)
         
     | 
| 
      
 164 
     | 
    
         
            +
                    system "curl -L -o #{binaryen_tarball} #{self.binaryen_download_url(@binaryen_version)}"
         
     | 
| 
      
 165 
     | 
    
         
            +
                  end
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                  unless File.exist? @binaryen_path
         
     | 
| 
      
 168 
     | 
    
         
            +
                    FileUtils.mkdir_p @binaryen_path
         
     | 
| 
      
 169 
     | 
    
         
            +
                    system "tar -C #{@binaryen_path} --strip-component 1 -xzf #{binaryen_tarball}"
         
     | 
| 
      
 170 
     | 
    
         
            +
                  end
         
     | 
| 
      
 171 
     | 
    
         
            +
                end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                def install
         
     | 
| 
      
 174 
     | 
    
         
            +
                  install_wasi_sdk
         
     | 
| 
      
 175 
     | 
    
         
            +
                  install_binaryen
         
     | 
| 
      
 176 
     | 
    
         
            +
                end
         
     | 
| 
      
 177 
     | 
    
         
            +
              end
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
              class Emscripten < Toolchain
         
     | 
| 
      
 180 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 181 
     | 
    
         
            +
                  @tools = { cc: "emcc", ld: "emcc", ar: "emar", ranlib: "emranlib" }
         
     | 
| 
      
 182 
     | 
    
         
            +
                  @name = "emscripten"
         
     | 
| 
      
 183 
     | 
    
         
            +
                end
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                def install
         
     | 
| 
      
 186 
     | 
    
         
            +
                end
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                def find_tool(name)
         
     | 
| 
      
 189 
     | 
    
         
            +
                  Toolchain.check_executable(@tools[name])
         
     | 
| 
      
 190 
     | 
    
         
            +
                  @tools[name]
         
     | 
| 
      
 191 
     | 
    
         
            +
                end
         
     | 
| 
      
 192 
     | 
    
         
            +
              end
         
     | 
| 
      
 193 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,88 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative "build/build_params"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative "build/product"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "build/toolchain"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "build/executor"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class RubyWasm::Build
         
     | 
| 
      
 7 
     | 
    
         
            +
              # Source to build from.
         
     | 
| 
      
 8 
     | 
    
         
            +
              attr_reader :source
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              # Target to build for.
         
     | 
| 
      
 11 
     | 
    
         
            +
              attr_reader :target
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              # Toolchain for the build.
         
     | 
| 
      
 14 
     | 
    
         
            +
              # Defaults to the Toolchain.get for the target.
         
     | 
| 
      
 15 
     | 
    
         
            +
              attr_reader :toolchain
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              # LibYAML product to build.
         
     | 
| 
      
 18 
     | 
    
         
            +
              attr_reader :libyaml
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              # zlib product to build.
         
     | 
| 
      
 21 
     | 
    
         
            +
              attr_reader :zlib
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              # wasi-vfs product used by the crossruby.
         
     | 
| 
      
 24 
     | 
    
         
            +
              attr_reader :wasi_vfs
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              # BaseRuby product to build.
         
     | 
| 
      
 27 
     | 
    
         
            +
              attr_reader :baseruby
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              # CrossRuby product to build.
         
     | 
| 
      
 30 
     | 
    
         
            +
              attr_reader :crossruby
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              def initialize(
         
     | 
| 
      
 33 
     | 
    
         
            +
                name,
         
     | 
| 
      
 34 
     | 
    
         
            +
                target:,
         
     | 
| 
      
 35 
     | 
    
         
            +
                src:,
         
     | 
| 
      
 36 
     | 
    
         
            +
                toolchain:,
         
     | 
| 
      
 37 
     | 
    
         
            +
                build_dir:,
         
     | 
| 
      
 38 
     | 
    
         
            +
                rubies_dir:,
         
     | 
| 
      
 39 
     | 
    
         
            +
                **options
         
     | 
| 
      
 40 
     | 
    
         
            +
              )
         
     | 
| 
      
 41 
     | 
    
         
            +
                @target = target
         
     | 
| 
      
 42 
     | 
    
         
            +
                @build_dir = build_dir
         
     | 
| 
      
 43 
     | 
    
         
            +
                @rubies_dir = rubies_dir
         
     | 
| 
      
 44 
     | 
    
         
            +
                @toolchain = (toolchain || RubyWasm::Toolchain.get(target, @build_dir))
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                @libyaml = RubyWasm::LibYAMLProduct.new(@build_dir, @target, @toolchain)
         
     | 
| 
      
 47 
     | 
    
         
            +
                @zlib = RubyWasm::ZlibProduct.new(@build_dir, @target, @toolchain)
         
     | 
| 
      
 48 
     | 
    
         
            +
                @wasi_vfs = RubyWasm::WasiVfsProduct.new(@build_dir)
         
     | 
| 
      
 49 
     | 
    
         
            +
                @source = RubyWasm::BuildSource.new(src, @build_dir)
         
     | 
| 
      
 50 
     | 
    
         
            +
                @baseruby = RubyWasm::BaseRubyProduct.new(@build_dir, @source)
         
     | 
| 
      
 51 
     | 
    
         
            +
                @openssl = RubyWasm::OpenSSLProduct.new(@build_dir, @target, @toolchain)
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                build_params =
         
     | 
| 
      
 54 
     | 
    
         
            +
                  RubyWasm::BuildParams.new(
         
     | 
| 
      
 55 
     | 
    
         
            +
                    name: name,
         
     | 
| 
      
 56 
     | 
    
         
            +
                    target: target,
         
     | 
| 
      
 57 
     | 
    
         
            +
                    default_exts: options[:default_exts]
         
     | 
| 
      
 58 
     | 
    
         
            +
                  )
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                @crossruby =
         
     | 
| 
      
 61 
     | 
    
         
            +
                  RubyWasm::CrossRubyProduct.new(
         
     | 
| 
      
 62 
     | 
    
         
            +
                    build_params,
         
     | 
| 
      
 63 
     | 
    
         
            +
                    @build_dir,
         
     | 
| 
      
 64 
     | 
    
         
            +
                    @rubies_dir,
         
     | 
| 
      
 65 
     | 
    
         
            +
                    @baseruby,
         
     | 
| 
      
 66 
     | 
    
         
            +
                    @source,
         
     | 
| 
      
 67 
     | 
    
         
            +
                    @toolchain
         
     | 
| 
      
 68 
     | 
    
         
            +
                  )
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                @crossruby.with_libyaml @libyaml
         
     | 
| 
      
 71 
     | 
    
         
            +
                @crossruby.with_zlib @zlib
         
     | 
| 
      
 72 
     | 
    
         
            +
                @crossruby.with_wasi_vfs @wasi_vfs
         
     | 
| 
      
 73 
     | 
    
         
            +
                @crossruby.with_openssl @openssl
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              def cache_key(digest)
         
     | 
| 
      
 77 
     | 
    
         
            +
                @source.cache_key(digest)
         
     | 
| 
      
 78 
     | 
    
         
            +
                @crossruby.cache_key(digest)
         
     | 
| 
      
 79 
     | 
    
         
            +
                digest << @build_dir
         
     | 
| 
      
 80 
     | 
    
         
            +
                digest << @rubies_dir
         
     | 
| 
      
 81 
     | 
    
         
            +
                digest << @target
         
     | 
| 
      
 82 
     | 
    
         
            +
                digest << @toolchain.name
         
     | 
| 
      
 83 
     | 
    
         
            +
                digest << @libyaml.name
         
     | 
| 
      
 84 
     | 
    
         
            +
                digest << @zlib.name
         
     | 
| 
      
 85 
     | 
    
         
            +
                digest << @openssl.name
         
     | 
| 
      
 86 
     | 
    
         
            +
                digest << @wasi_vfs.name
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,217 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "optparse"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "rbconfig"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module RubyWasm
         
     | 
| 
      
 5 
     | 
    
         
            +
              class CLI
         
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(stdout:, stderr:)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @stdout = stdout
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @stderr = stderr
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def run(args)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  available_commands = %w[build pack]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  parser =
         
     | 
| 
      
 14 
     | 
    
         
            +
                    OptionParser.new do |opts|
         
     | 
| 
      
 15 
     | 
    
         
            +
                      opts.banner = <<~USAGE
         
     | 
| 
      
 16 
     | 
    
         
            +
                      Usage: rbwasm [options...] [command]
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                      Available commands: #{available_commands.join(", ")}
         
     | 
| 
      
 19 
     | 
    
         
            +
                    USAGE
         
     | 
| 
      
 20 
     | 
    
         
            +
                      opts.version = RubyWasm::VERSION
         
     | 
| 
      
 21 
     | 
    
         
            +
                      opts.on("-h", "--help", "Prints this help") do
         
     | 
| 
      
 22 
     | 
    
         
            +
                        @stderr.puts opts
         
     | 
| 
      
 23 
     | 
    
         
            +
                        exit
         
     | 
| 
      
 24 
     | 
    
         
            +
                      end
         
     | 
| 
      
 25 
     | 
    
         
            +
                      opts.on("--log-level LEVEL", "Log level") do |level|
         
     | 
| 
      
 26 
     | 
    
         
            +
                        RubyWasm.log_level = level.to_sym
         
     | 
| 
      
 27 
     | 
    
         
            +
                      end
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
                  parser.order!(args)
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  command = args.shift
         
     | 
| 
      
 32 
     | 
    
         
            +
                  case command
         
     | 
| 
      
 33 
     | 
    
         
            +
                  when "build"
         
     | 
| 
      
 34 
     | 
    
         
            +
                    build(args)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  when "pack"
         
     | 
| 
      
 36 
     | 
    
         
            +
                    pack(args)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  else
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @stderr.puts "Unknown command: #{command}"
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @stderr.puts parser
         
     | 
| 
      
 40 
     | 
    
         
            +
                    exit
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def build(args)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  # @type var options: Hash[Symbol, untyped]
         
     | 
| 
      
 46 
     | 
    
         
            +
                  options = {
         
     | 
| 
      
 47 
     | 
    
         
            +
                    save_temps: false,
         
     | 
| 
      
 48 
     | 
    
         
            +
                    optimize: false,
         
     | 
| 
      
 49 
     | 
    
         
            +
                    remake: false,
         
     | 
| 
      
 50 
     | 
    
         
            +
                    reconfigure: false,
         
     | 
| 
      
 51 
     | 
    
         
            +
                    clean: false,
         
     | 
| 
      
 52 
     | 
    
         
            +
                    ruby_version: "3.3",
         
     | 
| 
      
 53 
     | 
    
         
            +
                    target_triplet: "wasm32-unknown-wasi",
         
     | 
| 
      
 54 
     | 
    
         
            +
                    profile: "full",
         
     | 
| 
      
 55 
     | 
    
         
            +
                    stdlib: true,
         
     | 
| 
      
 56 
     | 
    
         
            +
                    disable_gems: false
         
     | 
| 
      
 57 
     | 
    
         
            +
                  }
         
     | 
| 
      
 58 
     | 
    
         
            +
                  OptionParser
         
     | 
| 
      
 59 
     | 
    
         
            +
                    .new do |opts|
         
     | 
| 
      
 60 
     | 
    
         
            +
                      opts.banner = "Usage: rbwasm componentize [options]"
         
     | 
| 
      
 61 
     | 
    
         
            +
                      opts.on("-h", "--help", "Prints this help") do
         
     | 
| 
      
 62 
     | 
    
         
            +
                        @stdout.puts opts
         
     | 
| 
      
 63 
     | 
    
         
            +
                        exit
         
     | 
| 
      
 64 
     | 
    
         
            +
                      end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                      opts.on("--save-temps", "Save temporary files") do
         
     | 
| 
      
 67 
     | 
    
         
            +
                        options[:save_temps] = true
         
     | 
| 
      
 68 
     | 
    
         
            +
                      end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                      opts.on("--ruby-version VERSION", "Ruby version") do |version|
         
     | 
| 
      
 71 
     | 
    
         
            +
                        options[:ruby_version] = version
         
     | 
| 
      
 72 
     | 
    
         
            +
                      end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                      opts.on("--target TRIPLET", "Target triplet") do |triplet|
         
     | 
| 
      
 75 
     | 
    
         
            +
                        options[:target_triplet] = triplet
         
     | 
| 
      
 76 
     | 
    
         
            +
                      end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                      opts.on(
         
     | 
| 
      
 79 
     | 
    
         
            +
                        "--build-profile PROFILE",
         
     | 
| 
      
 80 
     | 
    
         
            +
                        "Build profile. full or minimal"
         
     | 
| 
      
 81 
     | 
    
         
            +
                      ) { |profile| options[:profile] = profile }
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                      opts.on("--optimize", "Optimize the output") do
         
     | 
| 
      
 84 
     | 
    
         
            +
                        options[:optimize] = true
         
     | 
| 
      
 85 
     | 
    
         
            +
                      end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                      opts.on("--remake", "Re-execute make for Ruby") do
         
     | 
| 
      
 88 
     | 
    
         
            +
                        options[:remake] = true
         
     | 
| 
      
 89 
     | 
    
         
            +
                      end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                      opts.on("--reconfigure", "Re-execute configure for Ruby") do
         
     | 
| 
      
 92 
     | 
    
         
            +
                        options[:reconfigure] = true
         
     | 
| 
      
 93 
     | 
    
         
            +
                      end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                      opts.on("--clean", "Clean build artifacts") { options[:clean] = true }
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                      opts.on("-o", "--output FILE", "Output file") do |file|
         
     | 
| 
      
 98 
     | 
    
         
            +
                        options[:output] = file
         
     | 
| 
      
 99 
     | 
    
         
            +
                      end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                      opts.on("--[no-]stdlib", "Include stdlib") do |stdlib|
         
     | 
| 
      
 102 
     | 
    
         
            +
                        options[:stdlib] = stdlib
         
     | 
| 
      
 103 
     | 
    
         
            +
                      end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                      opts.on("--disable-gems", "Disable gems") do
         
     | 
| 
      
 106 
     | 
    
         
            +
                        options[:disable_gems] = true
         
     | 
| 
      
 107 
     | 
    
         
            +
                      end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                      opts.on("--format FORMAT", "Output format") do |format|
         
     | 
| 
      
 110 
     | 
    
         
            +
                        options[:format] = format
         
     | 
| 
      
 111 
     | 
    
         
            +
                      end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                      opts.on("--print-ruby-cache-key", "Print Ruby cache key") do
         
     | 
| 
      
 114 
     | 
    
         
            +
                        options[:print_ruby_cache_key] = true
         
     | 
| 
      
 115 
     | 
    
         
            +
                      end
         
     | 
| 
      
 116 
     | 
    
         
            +
                    end
         
     | 
| 
      
 117 
     | 
    
         
            +
                    .parse!(args)
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                  verbose = RubyWasm.logger.level == :debug
         
     | 
| 
      
 120 
     | 
    
         
            +
                  executor = RubyWasm::BuildExecutor.new(verbose: verbose)
         
     | 
| 
      
 121 
     | 
    
         
            +
                  packager = self.derive_packager(options)
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                  if options[:print_ruby_cache_key]
         
     | 
| 
      
 124 
     | 
    
         
            +
                    self.do_print_ruby_cache_key(packager)
         
     | 
| 
      
 125 
     | 
    
         
            +
                    exit
         
     | 
| 
      
 126 
     | 
    
         
            +
                  end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                  unless options[:output]
         
     | 
| 
      
 129 
     | 
    
         
            +
                    @stderr.puts "Output file is not specified"
         
     | 
| 
      
 130 
     | 
    
         
            +
                    exit 1
         
     | 
| 
      
 131 
     | 
    
         
            +
                  end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                  require "tmpdir"
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                  if options[:save_temps]
         
     | 
| 
      
 136 
     | 
    
         
            +
                    tmpdir = Dir.mktmpdir
         
     | 
| 
      
 137 
     | 
    
         
            +
                    self.do_build(executor, tmpdir, packager, options)
         
     | 
| 
      
 138 
     | 
    
         
            +
                    @stderr.puts "Temporary files are saved to #{tmpdir}"
         
     | 
| 
      
 139 
     | 
    
         
            +
                    exit
         
     | 
| 
      
 140 
     | 
    
         
            +
                  else
         
     | 
| 
      
 141 
     | 
    
         
            +
                    Dir.mktmpdir do |tmpdir|
         
     | 
| 
      
 142 
     | 
    
         
            +
                      self.do_build(executor, tmpdir, packager, options)
         
     | 
| 
      
 143 
     | 
    
         
            +
                    end
         
     | 
| 
      
 144 
     | 
    
         
            +
                  end
         
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                def pack(args)
         
     | 
| 
      
 148 
     | 
    
         
            +
                  self.require_extension
         
     | 
| 
      
 149 
     | 
    
         
            +
                  RubyWasmExt::WasiVfs.run_cli([$0, "pack", *args])
         
     | 
| 
      
 150 
     | 
    
         
            +
                end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                private
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                def build_config(options)
         
     | 
| 
      
 155 
     | 
    
         
            +
                  config = { target: options[:target_triplet], src: options[:ruby_version] }
         
     | 
| 
      
 156 
     | 
    
         
            +
                  case options[:profile]
         
     | 
| 
      
 157 
     | 
    
         
            +
                  when "full"
         
     | 
| 
      
 158 
     | 
    
         
            +
                    config[:default_exts] = RubyWasm::Packager::ALL_DEFAULT_EXTS
         
     | 
| 
      
 159 
     | 
    
         
            +
                    env_additional_exts = ENV["RUBY_WASM_ADDITIONAL_EXTS"] || ""
         
     | 
| 
      
 160 
     | 
    
         
            +
                    unless env_additional_exts.empty?
         
     | 
| 
      
 161 
     | 
    
         
            +
                      config[:default_exts] += "," + env_additional_exts
         
     | 
| 
      
 162 
     | 
    
         
            +
                    end
         
     | 
| 
      
 163 
     | 
    
         
            +
                  when "minimal"
         
     | 
| 
      
 164 
     | 
    
         
            +
                    config[:default_exts] = ""
         
     | 
| 
      
 165 
     | 
    
         
            +
                  else
         
     | 
| 
      
 166 
     | 
    
         
            +
                    RubyWasm.logger.error "Unknown profile: #{options[:profile]} (available: full, minimal)"
         
     | 
| 
      
 167 
     | 
    
         
            +
                    exit 1
         
     | 
| 
      
 168 
     | 
    
         
            +
                  end
         
     | 
| 
      
 169 
     | 
    
         
            +
                  config[:suffix] = "-#{options[:profile]}"
         
     | 
| 
      
 170 
     | 
    
         
            +
                  config
         
     | 
| 
      
 171 
     | 
    
         
            +
                end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                def derive_packager(options)
         
     | 
| 
      
 174 
     | 
    
         
            +
                  __skip__ =
         
     | 
| 
      
 175 
     | 
    
         
            +
                    if defined?(Bundler) && !options[:disable_gems]
         
     | 
| 
      
 176 
     | 
    
         
            +
                      definition = Bundler.definition
         
     | 
| 
      
 177 
     | 
    
         
            +
                    end
         
     | 
| 
      
 178 
     | 
    
         
            +
                  RubyWasm::Packager.new(build_config(options), definition)
         
     | 
| 
      
 179 
     | 
    
         
            +
                end
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
                def do_print_ruby_cache_key(packager)
         
     | 
| 
      
 182 
     | 
    
         
            +
                  ruby_core_build = packager.ruby_core_build
         
     | 
| 
      
 183 
     | 
    
         
            +
                  require "digest"
         
     | 
| 
      
 184 
     | 
    
         
            +
                  digest = Digest::SHA256.new
         
     | 
| 
      
 185 
     | 
    
         
            +
                  ruby_core_build.cache_key(digest)
         
     | 
| 
      
 186 
     | 
    
         
            +
                  hexdigest = digest.hexdigest
         
     | 
| 
      
 187 
     | 
    
         
            +
                  require "json"
         
     | 
| 
      
 188 
     | 
    
         
            +
                  @stdout.puts JSON.generate(
         
     | 
| 
      
 189 
     | 
    
         
            +
                                 hexdigest: hexdigest,
         
     | 
| 
      
 190 
     | 
    
         
            +
                                 artifact: ruby_core_build.artifact
         
     | 
| 
      
 191 
     | 
    
         
            +
                               )
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                def do_build(executor, tmpdir, packager, options)
         
     | 
| 
      
 195 
     | 
    
         
            +
                  self.require_extension
         
     | 
| 
      
 196 
     | 
    
         
            +
                  wasm_bytes = packager.package(executor, tmpdir, options)
         
     | 
| 
      
 197 
     | 
    
         
            +
                  RubyWasm.logger.info "Size: #{SizeFormatter.format(wasm_bytes.size)}"
         
     | 
| 
      
 198 
     | 
    
         
            +
                  case options[:output]
         
     | 
| 
      
 199 
     | 
    
         
            +
                  when "-"
         
     | 
| 
      
 200 
     | 
    
         
            +
                    @stdout.write wasm_bytes.pack("C*")
         
     | 
| 
      
 201 
     | 
    
         
            +
                  else
         
     | 
| 
      
 202 
     | 
    
         
            +
                    File.binwrite(options[:output], wasm_bytes.pack("C*"))
         
     | 
| 
      
 203 
     | 
    
         
            +
                    RubyWasm.logger.debug "Wrote #{options[:output]}"
         
     | 
| 
      
 204 
     | 
    
         
            +
                  end
         
     | 
| 
      
 205 
     | 
    
         
            +
                end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                def require_extension
         
     | 
| 
      
 208 
     | 
    
         
            +
                  # Tries to require the extension for the given Ruby version first
         
     | 
| 
      
 209 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 210 
     | 
    
         
            +
                    RUBY_VERSION =~ /(\d+\.\d+)/
         
     | 
| 
      
 211 
     | 
    
         
            +
                    require_relative "#{Regexp.last_match(1)}/ruby_wasm.so"
         
     | 
| 
      
 212 
     | 
    
         
            +
                  rescue LoadError
         
     | 
| 
      
 213 
     | 
    
         
            +
                    require_relative "ruby_wasm.so"
         
     | 
| 
      
 214 
     | 
    
         
            +
                  end
         
     | 
| 
      
 215 
     | 
    
         
            +
                end
         
     | 
| 
      
 216 
     | 
    
         
            +
              end
         
     | 
| 
      
 217 
     | 
    
         
            +
            end
         
     |