Skip to content

Commit

Permalink
build: Add experimental PIC support for WASI target
Browse files Browse the repository at this point in the history
  • Loading branch information
kateinoigakukun committed Feb 6, 2024
1 parent 150c74e commit 0ca28b0
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 15 deletions.
2 changes: 1 addition & 1 deletion lib/ruby_wasm/build/product/crossruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def configure_args(build_triple, toolchain)
xldflags = @xldflags.dup

args = self.system_triplet_args + ["--build", build_triple]
args << "--with-static-linked-ext"
args << "--with-static-linked-ext" unless @params.target.pic?
args << %Q(--with-ext=#{default_exts})
args << %Q(--with-libyaml-dir=#{@libyaml.install_root})
args << %Q(--with-zlib-dir=#{@zlib.install_root})
Expand Down
2 changes: 2 additions & 0 deletions lib/ruby_wasm/build/product/libyaml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ def build(executor)
"#{product_build_dir}/config/config.sub",
"https://cdn.jsdelivr.net/gh/gcc-mirror/gcc@master/config.sub"

configure_args = self.configure_args.dup
configure_args << "CFLAGS=-fPIC" if target.pic?
executor.system "./configure", *configure_args, chdir: product_build_dir
executor.system "make",
"install",
Expand Down
5 changes: 5 additions & 0 deletions lib/ruby_wasm/build/product/openssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ def configure_args
-DHAVE_FORK=0
]
end

if @target.pic?
args << "-fPIC"
end

args + tools_args
end

Expand Down
2 changes: 2 additions & 0 deletions lib/ruby_wasm/build/product/zlib.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ def build(executor)
product_build_dir,
"--strip-components=1"

configure_args = self.configure_args.dup
configure_args << "CFLAGS=-fPIC" if target.pic?
executor.system "env",
*configure_args,
"./configure",
Expand Down
2 changes: 1 addition & 1 deletion lib/ruby_wasm/packager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def package(executor, dest_dir, options)
fs.remove_non_runtime_files(executor)
fs.remove_stdlib(executor) unless options[:stdlib]

if full_build_options[:target] == "wasm32-unknown-wasi"
if full_build_options[:target] == "wasm32-unknown-wasi" && !support_dynamic_linking?
# wasi-vfs supports only WASI target
wasi_vfs = RubyWasmExt::WasiVfs.new
wasi_vfs.map_dir("/bundle", fs.bundle_dir)
Expand Down
96 changes: 95 additions & 1 deletion lib/ruby_wasm/packager/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,100 @@ def artifact
end

class DynamicLinking < BuildStrategy
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]

do_build =
proc do
build.crossruby.build(
executor,
remake: options[:remake],
reconfigure: options[:reconfigure]
)
end

__skip__ =
if defined?(Bundler)
Bundler.with_unbundled_env(&do_build)
else
do_build.call
end
build.crossruby.artifact
end

def build_exts(build)
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,
ext_relative_path: ext_relative_path
)
end
end
end

def cache_key(digest)
derive_build.cache_key(digest)
end

def artifact
derive_build.crossruby.artifact
end

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

def derive_build
return @build if @build
__skip__ =
build ||= RubyWasm::Build.new(
name, **@packager.full_build_options,
target: target,
# NOTE: We don't need linking libwasi_vfs because we use wasi-virt instead.
wasi_vfs: nil
)
build.crossruby.cflags = %w[-fPIC -fvisibility=default]
if @packager.full_build_options[:target] != "wasm32-unknown-emscripten"
build.crossruby.debugflags = %w[-g]
build.crossruby.wasmoptflags = %w[-O3 -g]
build.crossruby.ldflags = %w[
-Xlinker
--stack-first
-Xlinker
-z
-Xlinker
stack-size=16777216
]
build.crossruby.xldflags = %w[
-Xlinker -shared
-Xlinker --export-dynamic
-Xlinker --export-all
-Xlinker --experimental-pic
-Xlinker -export-if-defined=__main_argc_argv
]
end
@build = build
build
end

def name
require "digest"
options = @packager.full_build_options
src_channel = options[:src][:name]
target_triplet = options[:target]
"ruby-#{src_channel}-#{target_triplet}-pic#{options[:suffix]}"
end
end

class StaticLinking < BuildStrategy
Expand Down Expand Up @@ -100,7 +194,7 @@ def artifact
end

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

def derive_build
Expand Down
14 changes: 2 additions & 12 deletions sig/ruby_wasm/build.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -314,19 +314,9 @@ module RubyWasm
end

class BuildTask
@build_dir: String
@rubies_dir: String
@openssl: OpenSSLProduct

@build: Build
attr_accessor name: String
attr_reader source: BuildSource
attr_reader target: String
attr_reader toolchain: Toolchain
attr_reader libyaml: LibYAMLProduct
attr_reader zlib: ZlibProduct
attr_reader wasi_vfs: WasiVfsProduct
attr_reader baseruby: BaseRubyProduct
attr_reader crossruby: CrossRubyProduct

def initialize: (String name, target: String, src: untyped, ?toolchain: Toolchain?, ?build_dir: String?, ?rubies_dir: String?, **untyped) -> void
def hexdigest: -> String
end
Expand Down
3 changes: 3 additions & 0 deletions sig/ruby_wasm/packager.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class RubyWasm::Packager
end

class DynamicLinking < RubyWasm::Packager::Core::BuildStrategy
@build: RubyWasm::Build
def derive_build: () -> RubyWasm::Build
def name: () -> string
end

class StaticLinking < RubyWasm::Packager::Core::BuildStrategy
Expand Down

0 comments on commit 0ca28b0

Please sign in to comment.