rb_sys1 0.1.0
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/bin/console +15 -0
- data/bin/setup +8 -0
- data/certs/ianks.pem +21 -0
- data/lib/rb_sys/mkmf.rb +81 -0
- data/lib/rb_sys/version.rb +5 -0
- data/lib/rb_sys.rb +8 -0
- data/sig/rb_sys.rbs +4 -0
- data/vendor/rubygems/ext/cargo_builder/link_flag_converter.rb +23 -0
- data/vendor/rubygems/ext/cargo_builder.rb +330 -0
- metadata +53 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5fa473b69ad2496084571b1f592c94a1b2c2928ff98211b94961b489ff1e5392
|
4
|
+
data.tar.gz: 519bf8fb1a5a6420d3c146e29885f6e583918653f9bee99f7b02a7beea4c4159
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 67227d00cc8c812876b944a62604441946906a6913708133e5d449e2bedb181680c3b8cc6f6423c67f37d25a26eaf6ea0328042c7448e1b7685ef768dd7dec3e
|
7
|
+
data.tar.gz: bc7def6f80d2e0f5e888bf572701c171e76f4def3b7e428b9825f163c36a2888d4f7ec31e2c59ee78cf519b56b91a43aac1fb39a0127123e1995ed630bbc10d4
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "rb_sys"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/certs/ianks.pem
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDfDCCAmSgAwIBAgIBATANBgkqhkiG9w0BAQUFADBCMRQwEgYDVQQDDAtpLmtl
|
3
|
+
cnNleW1lcjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYD
|
4
|
+
Y29tMB4XDTIyMDQxMzE5NTY1MVoXDTIzMDQxMzE5NTY1MVowQjEUMBIGA1UEAwwL
|
5
|
+
aS5rZXJzZXltZXIxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixk
|
6
|
+
ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMJ2pG+er4cP
|
7
|
+
PasxsMIKL9/tmLL4gh80EMuF3SCS0qZoh+Oo8dkvRYxW8NXdwEIcp3cCNgE+5G+J
|
8
|
+
TCMOVF8S15n1Z1P7xxXiXxa/BIofKKbtatVRngm14uR/6pjdkvLXqlrWdS57bNwv
|
9
|
+
7LtpzYVfDHfsl/qRWaEi4jq00PNCRSWjcva8teqswjBg8KlwGtyygpezPbVSWP8Y
|
10
|
+
vzWZmVF7fqRBXU78Ah0+pNOhslBXDTvI3xJdN4hQ3H7rLjpD/qxKWq/8o+Qvx6cX
|
11
|
+
dNZ3ugH/Pr3BAsqt4JFLXin9AK7PO9GDMH5JXJrUb+hAt2VNIZqpz9VlKA6BA0jN
|
12
|
+
eWGea+yCZkECAwEAAaN9MHswCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
|
13
|
+
BBYEFOkrF6hsocaIMOjR/K3JBzyXCLJPMCAGA1UdEQQZMBeBFWkua2Vyc2V5bWVy
|
14
|
+
QGdtYWlsLmNvbTAgBgNVHRIEGTAXgRVpLmtlcnNleW1lckBnbWFpbC5jb20wDQYJ
|
15
|
+
KoZIhvcNAQEFBQADggEBADHnvHbZn5nldcpArIQcFF9URCBloCBZHqLFMhlGj5BX
|
16
|
+
bFvuoq4CBmEFiJpTazeoEaxPlsmIK1+4CqBXwg8lHEMC9RV5g9QtJHQry2eFE/8U
|
17
|
+
WrgCbqdxb8HBl9ayOHRcdfcv0RHBlmBHwBOoQ+hXMlInjssjfIX4BS39mTYefclE
|
18
|
+
zxOFntl+vb4kluo0j9/BGzdnGCo7iE+GfGSENFdOn2J38RCDLUzgOCmCtxzSvldq
|
19
|
+
Rl+ASkq2/1i07TkBpCf+2hq66+h/hx+/Y/KrUzXfe0jtvil0WESkJT2kqRqHWNhD
|
20
|
+
9GKBxaQlXokNDtWCm1/gl6cD8WRZ0N5S4ZGJT1FLLsA=
|
21
|
+
-----END CERTIFICATE-----
|
data/lib/rb_sys/mkmf.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubygems/ext"
|
4
|
+
require "shellwords"
|
5
|
+
require_relative "./../../vendor/rubygems/ext/cargo_builder"
|
6
|
+
|
7
|
+
# Root module
|
8
|
+
module RbSys
|
9
|
+
# Helpers for creating a Ruby compatible makefile for Rust
|
10
|
+
module Mkmf
|
11
|
+
def create_rust_makefile(target, srcprefix = nil)
|
12
|
+
if target.include?("/")
|
13
|
+
target_prefix, target = File.split(target)
|
14
|
+
target_prefix[0, 0] = "/"
|
15
|
+
else
|
16
|
+
target_prefix = ""
|
17
|
+
end
|
18
|
+
|
19
|
+
spec = Struct.new(:name, :metadata).new(target, {})
|
20
|
+
builder = Gem::Ext::CargoBuilder.new(spec)
|
21
|
+
srcprefix ||= "$(srcdir)/#{srcprefix}".chomp("/")
|
22
|
+
RbConfig.expand(srcdir = srcprefix.dup)
|
23
|
+
|
24
|
+
# rubocop:disable Style/GlobalVars
|
25
|
+
make_install = <<~MAKE
|
26
|
+
target_prefix = #{target_prefix}
|
27
|
+
CARGO_PROFILE = release
|
28
|
+
CLEANLIBS = target/ $(RUSTLIB) $(DLLIB)
|
29
|
+
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
30
|
+
RUSTLIB = #{dllib_path(builder)}
|
31
|
+
TARGET = #{target}
|
32
|
+
DLLIB = $(TARGET).#{RbConfig::CONFIG["DLEXT"]}
|
33
|
+
|
34
|
+
#{base_makefile(srcdir)}
|
35
|
+
|
36
|
+
#{env_vars(builder)}
|
37
|
+
|
38
|
+
FORCE: ;
|
39
|
+
|
40
|
+
$(DLLIB): FORCE
|
41
|
+
\t#{cargo_command(srcdir, builder)}
|
42
|
+
\t$(COPY) "$(RUSTLIB)" $@
|
43
|
+
|
44
|
+
install: $(DLLIB)
|
45
|
+
\t$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
46
|
+
|
47
|
+
all: #{$extout ? "install" : "$(DLLIB)"}
|
48
|
+
MAKE
|
49
|
+
|
50
|
+
File.write("Makefile", make_install)
|
51
|
+
end
|
52
|
+
# rubocop:enable Style/GlobalVars
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def base_makefile(cargo_dir)
|
57
|
+
base_makefile = dummy_makefile(__dir__).join("\n")
|
58
|
+
base_makefile.gsub!("all install static install-so install-rb", "all static install-so install-rb")
|
59
|
+
base_makefile.gsub!("clean-so::", "clean-so:\n\t-$(Q)$(RM) $(DLLIB)\n")
|
60
|
+
base_makefile.gsub!(/^srcdir = .*$/, "srcdir = #{cargo_dir}")
|
61
|
+
base_makefile
|
62
|
+
end
|
63
|
+
|
64
|
+
def cargo_command(cargo_dir, builder)
|
65
|
+
dest_path = File.join(Dir.pwd, "target")
|
66
|
+
args = []
|
67
|
+
cargo_cmd = builder.cargo_command(cargo_dir, dest_path, args)
|
68
|
+
Shellwords.join(cargo_cmd).gsub("\\=", "=")
|
69
|
+
end
|
70
|
+
|
71
|
+
def env_vars(builder)
|
72
|
+
builder.build_env.map { |k, v| %($(DLLIB): export #{k} = #{v.gsub("\n", '\n')}) }.join("\n")
|
73
|
+
end
|
74
|
+
|
75
|
+
def dllib_path(builder)
|
76
|
+
builder.cargo_dylib_path(File.join(Dir.pwd, "target"))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
include RbSys::Mkmf # rubocop:disable Style/MixinUsage
|
data/lib/rb_sys.rb
ADDED
data/sig/rb_sys.rbs
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Gem::Ext::CargoBuilder < Gem::Ext::Builder
|
4
|
+
# Converts Ruby link flags into something cargo understands
|
5
|
+
class LinkFlagConverter
|
6
|
+
def self.convert(arg)
|
7
|
+
case arg.chomp
|
8
|
+
when /^-L\s*(.+)$/
|
9
|
+
["-L", "native=#{$1}"]
|
10
|
+
when /^--library=(\w+\S+)$/, /^-l\s*(\w+\S+)$/
|
11
|
+
["-l", $1]
|
12
|
+
when /^-l\s*:lib(\S+).a$/
|
13
|
+
["-l", "static=#{$1}"]
|
14
|
+
when /^-l\s*:lib(\S+).(so|dylib|dll)$/
|
15
|
+
["-l", "dylib=#{$1}"]
|
16
|
+
when /^-F\s*(.*)$/
|
17
|
+
["-l", "framework=#{$1}"]
|
18
|
+
else
|
19
|
+
["-C", "link_arg=#{arg}"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,330 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This class is used by rubygems to build Rust extensions. It is a thin-wrapper
|
4
|
+
# over the `cargo rustc` command which takes care of building Rust code in a way
|
5
|
+
# that Ruby can use.
|
6
|
+
class Gem::Ext::CargoBuilder < Gem::Ext::Builder
|
7
|
+
attr_accessor :spec, :runner, :profile
|
8
|
+
|
9
|
+
def initialize(spec)
|
10
|
+
require "rubygems/command"
|
11
|
+
require_relative "cargo_builder/link_flag_converter"
|
12
|
+
|
13
|
+
@spec = spec
|
14
|
+
@runner = self.class.method(:run)
|
15
|
+
@profile = :release
|
16
|
+
end
|
17
|
+
|
18
|
+
def build(_extension, dest_path, results, args = [], lib_dir = nil, cargo_dir = Dir.pwd)
|
19
|
+
require "fileutils"
|
20
|
+
require "shellwords"
|
21
|
+
|
22
|
+
build_crate(dest_path, results, args, cargo_dir)
|
23
|
+
validate_cargo_build!(dest_path)
|
24
|
+
rename_cdylib_for_ruby_compatibility(dest_path)
|
25
|
+
finalize_directory(dest_path, lib_dir, cargo_dir)
|
26
|
+
results
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_crate(dest_path, results, args, cargo_dir)
|
30
|
+
env = build_env
|
31
|
+
cmd = cargo_command(cargo_dir, dest_path, args)
|
32
|
+
runner.call cmd, results, "cargo", cargo_dir, env
|
33
|
+
|
34
|
+
results
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_env
|
38
|
+
build_env = rb_config_env
|
39
|
+
build_env["RUBY_STATIC"] = "true" if ruby_static? && ENV.key?("RUBY_STATIC")
|
40
|
+
build_env
|
41
|
+
end
|
42
|
+
|
43
|
+
def cargo_command(cargo_dir, dest_path, args = [])
|
44
|
+
manifest = File.join(cargo_dir, "Cargo.toml")
|
45
|
+
cargo = ENV.fetch("CARGO", "cargo")
|
46
|
+
|
47
|
+
cmd = []
|
48
|
+
cmd += [cargo, "rustc"]
|
49
|
+
cmd += ["--target", ENV["CARGO_BUILD_TARGET"]] if ENV["CARGO_BUILD_TARGET"]
|
50
|
+
cmd += ["--target-dir", dest_path]
|
51
|
+
cmd += ["--manifest-path", manifest]
|
52
|
+
cmd += ["--lib"]
|
53
|
+
cmd += ["--profile", profile.to_s]
|
54
|
+
cmd += ["--locked"] if profile == :release
|
55
|
+
cmd += Gem::Command.build_args
|
56
|
+
cmd += args
|
57
|
+
cmd += ["--"]
|
58
|
+
cmd += [*cargo_rustc_args(dest_path)]
|
59
|
+
cmd
|
60
|
+
end
|
61
|
+
|
62
|
+
def cargo_dylib_path(dest_path)
|
63
|
+
prefix = so_ext == "dll" ? "" : "lib"
|
64
|
+
path_parts = [dest_path]
|
65
|
+
path_parts << ENV["CARGO_BUILD_TARGET"] if ENV["CARGO_BUILD_TARGET"]
|
66
|
+
path_parts += [profile_target_directory, "#{prefix}#{cargo_crate_name}.#{so_ext}"]
|
67
|
+
File.join(*path_parts)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def rb_config_env
|
73
|
+
result = {}
|
74
|
+
RbConfig::CONFIG.each { |k, v| result["RBCONFIG_#{k}"] = v }
|
75
|
+
result
|
76
|
+
end
|
77
|
+
|
78
|
+
def cargo_rustc_args(dest_dir)
|
79
|
+
[
|
80
|
+
*linker_args,
|
81
|
+
*mkmf_libpath,
|
82
|
+
*rustc_dynamic_linker_flags(dest_dir),
|
83
|
+
*rustc_lib_flags(dest_dir),
|
84
|
+
*platform_specific_rustc_args(dest_dir),
|
85
|
+
*debug_flags
|
86
|
+
]
|
87
|
+
end
|
88
|
+
|
89
|
+
def platform_specific_rustc_args(dest_dir, flags = [])
|
90
|
+
if mingw_target?
|
91
|
+
# On mingw platforms, mkmf adds libruby to the linker flags
|
92
|
+
flags += libruby_args(dest_dir)
|
93
|
+
|
94
|
+
# Make sure ALSR is used on mingw
|
95
|
+
# see https://github.com/rust-lang/rust/pull/75406/files
|
96
|
+
flags += ["-C", "link-arg=-Wl,--dynamicbase"]
|
97
|
+
flags += ["-C", "link-arg=-Wl,--disable-auto-image-base"]
|
98
|
+
|
99
|
+
# If the gem is installed on a host with build tools installed, but is
|
100
|
+
# run on one that isn't the missing libraries will cause the extension
|
101
|
+
# to fail on start.
|
102
|
+
flags += ["-C", "link-arg=-static-libgcc"]
|
103
|
+
end
|
104
|
+
|
105
|
+
flags
|
106
|
+
end
|
107
|
+
|
108
|
+
# We want to use the same linker that Ruby uses, so that the linker flags from
|
109
|
+
# mkmf work properly.
|
110
|
+
def linker_args
|
111
|
+
# Have to handle CC="cl /nologo" on mswin
|
112
|
+
cc_flag = Shellwords.split(makefile_config("CC"))
|
113
|
+
linker = cc_flag.shift
|
114
|
+
link_args = cc_flag.flat_map { |a| ["-C", "link-arg=#{a}"] }
|
115
|
+
|
116
|
+
["-C", "linker=#{linker}", *link_args]
|
117
|
+
end
|
118
|
+
|
119
|
+
def libruby_args(dest_dir)
|
120
|
+
libs = makefile_config(ruby_static? ? "LIBRUBYARG_STATIC" : "LIBRUBYARG_SHARED")
|
121
|
+
raw_libs = Shellwords.split(libs)
|
122
|
+
raw_libs.flat_map { |l| ldflag_to_link_modifier(l) }
|
123
|
+
end
|
124
|
+
|
125
|
+
def ruby_static?
|
126
|
+
return true if %w[1 true].include?(ENV["RUBY_STATIC"])
|
127
|
+
|
128
|
+
makefile_config("ENABLE_SHARED") == "no"
|
129
|
+
end
|
130
|
+
|
131
|
+
# Ruby expects the dylib to follow a file name convention for loading
|
132
|
+
def rename_cdylib_for_ruby_compatibility(dest_path)
|
133
|
+
new_path = final_extension_path(dest_path)
|
134
|
+
FileUtils.cp(cargo_dylib_path(dest_path), new_path)
|
135
|
+
new_path
|
136
|
+
end
|
137
|
+
|
138
|
+
def validate_cargo_build!(dir)
|
139
|
+
dylib_path = cargo_dylib_path(dir)
|
140
|
+
|
141
|
+
raise DylibNotFoundError, dir unless File.exist?(dylib_path)
|
142
|
+
|
143
|
+
dylib_path
|
144
|
+
end
|
145
|
+
|
146
|
+
def final_extension_path(dest_path)
|
147
|
+
dylib_path = cargo_dylib_path(dest_path)
|
148
|
+
dlext_name = "#{spec.name}.#{makefile_config("DLEXT")}"
|
149
|
+
dylib_path.gsub(File.basename(dylib_path), dlext_name)
|
150
|
+
end
|
151
|
+
|
152
|
+
def cargo_crate_name
|
153
|
+
spec.metadata.fetch("cargo_crate_name", spec.name).tr("-", "_")
|
154
|
+
end
|
155
|
+
|
156
|
+
def rustc_dynamic_linker_flags(dest_dir)
|
157
|
+
split_flags("DLDFLAGS")
|
158
|
+
.map { |arg| maybe_resolve_ldflag_variable(arg, dest_dir) }
|
159
|
+
.compact
|
160
|
+
.flat_map { |arg| ldflag_to_link_modifier(arg) }
|
161
|
+
end
|
162
|
+
|
163
|
+
def rustc_lib_flags(dest_dir)
|
164
|
+
split_flags("LIBS").flat_map { |arg| ldflag_to_link_modifier(arg) }
|
165
|
+
end
|
166
|
+
|
167
|
+
def split_flags(var)
|
168
|
+
Shellwords.split(RbConfig::CONFIG.fetch(var, ""))
|
169
|
+
end
|
170
|
+
|
171
|
+
def ldflag_to_link_modifier(arg)
|
172
|
+
LinkFlagConverter.convert(arg)
|
173
|
+
end
|
174
|
+
|
175
|
+
def msvc_target?
|
176
|
+
makefile_config("target_os").include?("msvc")
|
177
|
+
end
|
178
|
+
|
179
|
+
def darwin_target?
|
180
|
+
makefile_config("target_os").include?("darwin")
|
181
|
+
end
|
182
|
+
|
183
|
+
def mingw_target?
|
184
|
+
makefile_config("target_os").include?("mingw")
|
185
|
+
end
|
186
|
+
|
187
|
+
def win_target?
|
188
|
+
target_platform = RbConfig::CONFIG["target_os"]
|
189
|
+
!!Gem::WIN_PATTERNS.find { |r| target_platform =~ r }
|
190
|
+
end
|
191
|
+
|
192
|
+
# Interpolate substition vars in the arg (i.e. $(DEFFILE))
|
193
|
+
def maybe_resolve_ldflag_variable(input_arg, dest_dir)
|
194
|
+
var_matches = input_arg.match(/\$\((\w+)\)/)
|
195
|
+
|
196
|
+
return input_arg unless var_matches
|
197
|
+
|
198
|
+
var_name = var_matches[1]
|
199
|
+
|
200
|
+
return input_arg if var_name.nil? || var_name.chomp.empty?
|
201
|
+
|
202
|
+
case var_name
|
203
|
+
# On windows, it is assumed that mkmf has setup an exports file for the
|
204
|
+
# extension, so we have to to create one ourselves.
|
205
|
+
when "DEFFILE"
|
206
|
+
write_deffile(dest_dir)
|
207
|
+
else
|
208
|
+
RbConfig::CONFIG[var_name]
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def write_deffile(dest_path)
|
213
|
+
dest_dir = File.dirname(final_extension_path(dest_path))
|
214
|
+
FileUtils.mkdir_p(dest_dir)
|
215
|
+
deffile_path = File.join(dest_dir, "#{spec.name}-#{RbConfig::CONFIG["arch"]}.def")
|
216
|
+
export_prefix = makefile_config("EXPORT_PREFIX") || ""
|
217
|
+
|
218
|
+
File.open(deffile_path, "w") do |f|
|
219
|
+
f.puts "EXPORTS"
|
220
|
+
f.puts "#{export_prefix.strip}Init_#{spec.name}"
|
221
|
+
end
|
222
|
+
|
223
|
+
deffile_path
|
224
|
+
end
|
225
|
+
|
226
|
+
# We have to basically reimplement RbConfig::CONFIG['SOEXT'] here to support
|
227
|
+
# Ruby < 2.5
|
228
|
+
#
|
229
|
+
# @see https://github.com/ruby/ruby/blob/c87c027f18c005460746a74c07cd80ee355b16e4/configure.ac#L3185
|
230
|
+
def so_ext
|
231
|
+
return RbConfig::CONFIG["SOEXT"] if RbConfig::CONFIG.key?("SOEXT")
|
232
|
+
|
233
|
+
if win_target?
|
234
|
+
"dll"
|
235
|
+
elsif darwin_target?
|
236
|
+
"dylib"
|
237
|
+
else
|
238
|
+
"so"
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# Corresponds to $(LIBPATH) in mkmf
|
243
|
+
def mkmf_libpath
|
244
|
+
["-L", "native=#{makefile_config("libdir")}"]
|
245
|
+
end
|
246
|
+
|
247
|
+
def makefile_config(var_name)
|
248
|
+
val = RbConfig::MAKEFILE_CONFIG[var_name]
|
249
|
+
|
250
|
+
return unless val
|
251
|
+
|
252
|
+
RbConfig.expand(val.dup)
|
253
|
+
end
|
254
|
+
|
255
|
+
# Good balance between binary size and debugability
|
256
|
+
def debug_flags
|
257
|
+
return [] if profile == :dev
|
258
|
+
|
259
|
+
["-C", "debuginfo=1"]
|
260
|
+
end
|
261
|
+
|
262
|
+
# Copied from ExtConfBuilder
|
263
|
+
def finalize_directory(dest_path, lib_dir, extension_dir)
|
264
|
+
require "fileutils"
|
265
|
+
require "tempfile"
|
266
|
+
|
267
|
+
ext_path = final_extension_path(dest_path)
|
268
|
+
|
269
|
+
begin
|
270
|
+
tmp_dest = Dir.mktmpdir(".gem.", extension_dir)
|
271
|
+
|
272
|
+
# Some versions of `mktmpdir` return absolute paths, which will break make
|
273
|
+
# if the paths contain spaces. However, on Ruby 1.9.x on Windows, relative
|
274
|
+
# paths cause all C extension builds to fail.
|
275
|
+
#
|
276
|
+
# As such, we convert to a relative path unless we are using Ruby 1.9.x on
|
277
|
+
# Windows. This means that when using Ruby 1.9.x on Windows, paths with
|
278
|
+
# spaces do not work.
|
279
|
+
#
|
280
|
+
# Details: https://github.com/rubygems/rubygems/issues/977#issuecomment-171544940
|
281
|
+
tmp_dest_relative = get_relative_path(tmp_dest.clone, extension_dir)
|
282
|
+
|
283
|
+
if tmp_dest_relative
|
284
|
+
full_tmp_dest = File.join(extension_dir, tmp_dest_relative)
|
285
|
+
|
286
|
+
# TODO: remove in RubyGems 3
|
287
|
+
if Gem.install_extension_in_lib && lib_dir
|
288
|
+
FileUtils.mkdir_p lib_dir
|
289
|
+
FileUtils.cp_r ext_path, lib_dir, remove_destination: true
|
290
|
+
end
|
291
|
+
|
292
|
+
FileUtils::Entry_.new(full_tmp_dest).traverse do |ent|
|
293
|
+
destent = ent.class.new(dest_path, ent.rel)
|
294
|
+
destent.exist? || FileUtils.mv(ent.path, destent.path)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
ensure
|
298
|
+
FileUtils.rm_rf tmp_dest if tmp_dest
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
def get_relative_path(path, base)
|
303
|
+
path[0..base.length - 1] = "." if path.start_with?(base)
|
304
|
+
path
|
305
|
+
end
|
306
|
+
|
307
|
+
def profile_target_directory
|
308
|
+
case profile
|
309
|
+
when :release then "release"
|
310
|
+
when :dev then "debug"
|
311
|
+
else raise "unknown target directory for profile: #{profile}"
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
# Error raised when no cdylib artifact was created
|
316
|
+
class DylibNotFoundError < StandardError
|
317
|
+
def initialize(dir)
|
318
|
+
files = Dir.glob(File.join(dir, "**", "*")).map { |f| "- #{f}" }.join "\n"
|
319
|
+
|
320
|
+
super <<~MSG
|
321
|
+
Dynamic library not found for Rust extension (in #{dir})
|
322
|
+
|
323
|
+
Make sure you set "crate-type" in Cargo.toml to "cdylib"
|
324
|
+
|
325
|
+
Found files:
|
326
|
+
#{files}
|
327
|
+
MSG
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rb_sys1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ian Ker-Seymer
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-04-21 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- i.kerseymer@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/console
|
21
|
+
- bin/setup
|
22
|
+
- certs/ianks.pem
|
23
|
+
- lib/rb_sys.rb
|
24
|
+
- lib/rb_sys/mkmf.rb
|
25
|
+
- lib/rb_sys/version.rb
|
26
|
+
- sig/rb_sys.rbs
|
27
|
+
- vendor/rubygems/ext/cargo_builder.rb
|
28
|
+
- vendor/rubygems/ext/cargo_builder/link_flag_converter.rb
|
29
|
+
homepage: https://github.com/oxidize-rb/rb-sys
|
30
|
+
licenses:
|
31
|
+
- MIT
|
32
|
+
metadata:
|
33
|
+
rubygems_mfa_required: 'true'
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 2.4.0
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubygems_version: 3.3.12
|
50
|
+
signing_key:
|
51
|
+
specification_version: 4
|
52
|
+
summary: Helpers for compiling Rust extensions for ruby
|
53
|
+
test_files: []
|