Class: RubyWasm::Packager::Core::StaticLinking

Inherits:
BuildStrategy show all
Defined in:
lib/ruby_wasm/packager/core.rb

Instance Method Summary collapse

Methods inherited from BuildStrategy

#initialize, #specs_with_extensions, #with_unbundled_env

Constructor Details

This class inherits a constructor from RubyWasm::Packager::Core::BuildStrategy

Instance Method Details

#artifactObject



309
310
311
# File 'lib/ruby_wasm/packager/core.rb', line 309

def artifact
  derive_build.crossruby.artifact
end

#build(executor, options) ⇒ Object



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/ruby_wasm/packager/core.rb', line 282

def build(executor, options)
  build = derive_build
  force_rebuild =
    options[:remake] || options[:clean] || options[:reconfigure]
  if File.exist?(build.crossruby.artifact) && !force_rebuild
    return build.crossruby.artifact
  end
  build.crossruby.clean(executor) if options[:clean]

  self.with_unbundled_env do
    build.crossruby.build(
      executor,
      remake: options[:remake],
      reconfigure: options[:reconfigure]
    )
  end

  build.crossruby.artifact
end

#build_gem_exts(executor, gem_home) ⇒ Object



346
347
348
# File 'lib/ruby_wasm/packager/core.rb', line 346

def build_gem_exts(executor, gem_home)
  # No-op because we already built extensions as part of the Ruby build
end

#cache_key(digest) ⇒ Object



302
303
304
305
306
307
# File 'lib/ruby_wasm/packager/core.rb', line 302

def cache_key(digest)
  derive_build.cache_key(digest)
  if enabled = @packager.features.support_component_model?
    digest << enabled.to_s
  end
end

#derive_buildObject



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/ruby_wasm/packager/core.rb', line 317

def derive_build
  return @build if @build
  __skip__ = build ||= RubyWasm::Build.new(
    name, **@packager.full_build_options, target: target,
  )
  build.crossruby.user_exts = user_exts(build)
  # Emscripten uses --global-base=1024 by default, but it conflicts with
  # --stack-first and -z stack-size since global-base 1024 is smaller than
  # the large stack size.
  # Also -g produces some warnings on Emscripten and it confuses the configure
  # script of Ruby.
  if @packager.full_build_options[:target] != "wasm32-unknown-emscripten"
    build.crossruby.debugflags = %w[-g]
    # We assume that imported functions provided through WASI will not change
    # asyncify state, so we ignore them.
    build.crossruby.wasmoptflags = %w[-O3 -g --pass-arg=asyncify-ignore-imports]
    build.crossruby.ldflags = %w[
      -Xlinker
      --stack-first
      -Xlinker
      -z
      -Xlinker
      stack-size=16777216
    ]
  end
  @build = build
  build
end


358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/ruby_wasm/packager/core.rb', line 358

def link_gem_exts(executor, ruby_root, gem_home, module_bytes)
  return module_bytes unless @packager.features.support_component_model?

  linker = RubyWasmExt::ComponentEncode.new
  linker.validate(ENV["RUBYWASM_SKIP_LINKER_VALIDATION"] != "1")
  linker.module(module_bytes)
  linker.adapter(
    "wasi_snapshot_preview1",
    File.binread(RubyWasm::Packager::ComponentAdapter.wasi_snapshot_preview1(wasi_exec_model))
  )

  linker.encode()
end

#nameObject



389
390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/ruby_wasm/packager/core.rb', line 389

def name
  require "digest"
  options = @packager.full_build_options
  src_channel = options[:src][:name]
  target_triplet = options[:target]
  base = "ruby-#{src_channel}-#{target_triplet}#{options[:suffix]}"
  exts = specs_with_extensions.sort
  hash = ::Digest::MD5.new
  specs_with_extensions.each { |spec, _| hash << spec.full_name }
  if enabled = @packager.features.support_component_model?
    hash << enabled.to_s
  end
  exts.empty? ? base : "#{base}-#{hash.hexdigest}"
end

#targetObject



313
314
315
# File 'lib/ruby_wasm/packager/core.rb', line 313

def target
  RubyWasm::Target.new(@packager.full_build_options[:target])
end

#user_exts(build) ⇒ Object



372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/ruby_wasm/packager/core.rb', line 372

def user_exts(build)
  @user_exts ||=
    specs_with_extensions.flat_map do |spec, exts|
      exts.map do |ext|
        ext_feature = File.dirname(ext) # e.g. "ext/cgi/escape"
        ext_srcdir = File.join(spec.full_gem_path, ext_feature)
        ext_relative_path = File.join(spec.full_name, ext_feature)
        RubyWasm::CrossRubyExtProduct.new(
          ext_srcdir,
          build.toolchain,
          features: @packager.features,
          ext_relative_path: ext_relative_path
        )
      end
    end
end

#wasi_exec_modelObject



350
351
352
353
354
355
356
# File 'lib/ruby_wasm/packager/core.rb', line 350

def wasi_exec_model
  # TODO: Detect WASI exec-model from binary exports (_start or _initialize)
  use_js_gem = @packager.specs.any? do |spec|
    spec.name == "js"
  end
  use_js_gem ? "reactor" : "command"
end