rubygems-update 3.3.10 → 3.3.11
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 +4 -4
- data/CHANGELOG.md +14 -0
- data/Manifest.txt +14 -0
- data/bundler/CHANGELOG.md +11 -0
- data/bundler/exe/bundler +1 -1
- data/bundler/lib/bundler/build_metadata.rb +3 -3
- data/bundler/lib/bundler/cli/info.rb +1 -1
- data/bundler/lib/bundler/cli/init.rb +1 -1
- data/bundler/lib/bundler/cli/show.rb +1 -1
- data/bundler/lib/bundler/cli.rb +1 -1
- data/bundler/lib/bundler/installer.rb +2 -2
- data/bundler/lib/bundler/man/bundle-config.1 +3 -3
- data/bundler/lib/bundler/man/bundle-config.1.ronn +8 -6
- data/bundler/lib/bundler/shared_helpers.rb +4 -4
- data/bundler/lib/bundler/source/metadata.rb +1 -1
- data/bundler/lib/bundler/templates/Executable +2 -4
- data/bundler/lib/bundler/templates/Executable.bundler +1 -1
- data/bundler/lib/bundler/templates/Executable.standalone +2 -4
- data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +1 -1
- data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler.rb +1 -1
- data/lib/rubygems/commands/setup_command.rb +1 -1
- data/lib/rubygems/ext/builder.rb +3 -0
- data/lib/rubygems/ext/cargo_builder.rb +305 -0
- data/lib/rubygems/ext/ext_conf_builder.rb +1 -1
- data/lib/rubygems/ext.rb +1 -0
- data/lib/rubygems/gemcutter_utilities.rb +34 -5
- data/lib/rubygems/request.rb +1 -1
- data/lib/rubygems/source/git.rb +1 -0
- data/lib/rubygems.rb +2 -2
- data/rubygems-update.gemspec +1 -1
- data/setup.rb +1 -1
- data/test/rubygems/helper.rb +5 -5
- data/test/rubygems/test_gem.rb +1 -1
- data/test/rubygems/test_gem_command_manager.rb +1 -1
- data/test/rubygems/test_gem_commands_help_command.rb +1 -1
- data/test/rubygems/test_gem_commands_push_command.rb +5 -0
- data/test/rubygems/test_gem_commands_setup_command.rb +1 -1
- data/test/rubygems/test_gem_commands_signin_command.rb +100 -11
- data/test/rubygems/test_gem_dependency_installer.rb +2 -2
- data/test/rubygems/test_gem_ext_builder.rb +1 -1
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore +1 -0
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock +374 -0
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml +10 -0
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb +21 -0
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +10 -0
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs +30 -0
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore +1 -0
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +374 -0
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +10 -0
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb +21 -0
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec +8 -0
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs +42 -0
- data/test/rubygems/test_gem_ext_cargo_builder.rb +148 -0
- data/test/rubygems/test_gem_ext_cmake_builder.rb +2 -0
- data/test/rubygems/test_gem_gemcutter_utilities.rb +4 -2
- data/test/rubygems/test_gem_source_git.rb +1 -0
- data/test/rubygems/test_gem_specification.rb +1 -1
- data/test/rubygems/test_project_sanity.rb +1 -1
- data/test/rubygems/test_require.rb +1 -1
- data/test/test_changelog_generator.rb +1 -0
- metadata +17 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3f9f133a10adb0dca16feb1c6dd3d12c2da126c621dcf6ac086a5434f62cdecb
|
|
4
|
+
data.tar.gz: 0b48275de222559f54a44e6cdf9c1105e40ff156d57d26d2a5a246d1fcc50521
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ab1dc93b4c3748bc3580c8d4047ec956a52271b389fcb1c306ebecbf665670231648126aed8b84c711d7444025323a27cf665fefe801180bfeb3cc5d5a26ad25
|
|
7
|
+
data.tar.gz: 24d7c27ed7fdfff099d291b7524c377296ea4f3622c9c1880c3f2bd55b9fafcca79ee138df9d00138cc22dd5be5d5db376d6b145ec96566ccbc63dd7fd4cd507
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# 3.3.11 / 2022-04-07
|
|
2
|
+
|
|
3
|
+
## Enhancements:
|
|
4
|
+
|
|
5
|
+
* Enable mfa on specific keys during gem signin. Pull request #5305 by
|
|
6
|
+
aellispierce
|
|
7
|
+
* Prefer `__dir__` to `__FILE__`. Pull request #5444 by deivid-rodriguez
|
|
8
|
+
* Add cargo builder for rust extensions. Pull request #5175 by ianks
|
|
9
|
+
* Installs bundler 2.3.11 as a default gem.
|
|
10
|
+
|
|
11
|
+
## Documentation:
|
|
12
|
+
|
|
13
|
+
* Improve RDoc setup. Pull request #5398 by deivid-rodriguez
|
|
14
|
+
|
|
1
15
|
# 3.3.10 / 2022-03-23
|
|
2
16
|
|
|
3
17
|
## Enhancements:
|
data/Manifest.txt
CHANGED
|
@@ -382,6 +382,7 @@ lib/rubygems/exceptions.rb
|
|
|
382
382
|
lib/rubygems/ext.rb
|
|
383
383
|
lib/rubygems/ext/build_error.rb
|
|
384
384
|
lib/rubygems/ext/builder.rb
|
|
385
|
+
lib/rubygems/ext/cargo_builder.rb
|
|
385
386
|
lib/rubygems/ext/cmake_builder.rb
|
|
386
387
|
lib/rubygems/ext/configure_builder.rb
|
|
387
388
|
lib/rubygems/ext/ext_conf_builder.rb
|
|
@@ -635,6 +636,19 @@ test/rubygems/test_gem_dependency_list.rb
|
|
|
635
636
|
test/rubygems/test_gem_dependency_resolution_error.rb
|
|
636
637
|
test/rubygems/test_gem_doctor.rb
|
|
637
638
|
test/rubygems/test_gem_ext_builder.rb
|
|
639
|
+
test/rubygems/test_gem_ext_cargo_builder.rb
|
|
640
|
+
test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore
|
|
641
|
+
test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock
|
|
642
|
+
test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml
|
|
643
|
+
test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb
|
|
644
|
+
test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec
|
|
645
|
+
test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs
|
|
646
|
+
test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore
|
|
647
|
+
test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock
|
|
648
|
+
test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml
|
|
649
|
+
test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb
|
|
650
|
+
test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec
|
|
651
|
+
test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs
|
|
638
652
|
test/rubygems/test_gem_ext_cmake_builder.rb
|
|
639
653
|
test/rubygems/test_gem_ext_configure_builder.rb
|
|
640
654
|
test/rubygems/test_gem_ext_ext_conf_builder.rb
|
data/bundler/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
# 2.3.11 (April 7, 2022)
|
|
2
|
+
|
|
3
|
+
## Enhancements:
|
|
4
|
+
|
|
5
|
+
- Bump actions/checkout to 3 in bundler gem template [#5445](https://github.com/rubygems/rubygems/pull/5445)
|
|
6
|
+
- Prefer `__dir__` to `__FILE__` [#5444](https://github.com/rubygems/rubygems/pull/5444)
|
|
7
|
+
|
|
8
|
+
## Documentation:
|
|
9
|
+
|
|
10
|
+
- Update bundler documentation to reflect bundle config scope changes [#5441](https://github.com/rubygems/rubygems/pull/5441)
|
|
11
|
+
|
|
1
12
|
# 2.3.10 (March 23, 2022)
|
|
2
13
|
|
|
3
14
|
## Enhancements:
|
data/bundler/exe/bundler
CHANGED
|
@@ -4,8 +4,8 @@ module Bundler
|
|
|
4
4
|
# Represents metadata from when the Bundler gem was built.
|
|
5
5
|
module BuildMetadata
|
|
6
6
|
# begin ivars
|
|
7
|
-
@built_at = "2022-
|
|
8
|
-
@git_commit_sha = "
|
|
7
|
+
@built_at = "2022-04-07".freeze
|
|
8
|
+
@git_commit_sha = "9b6c5a801a".freeze
|
|
9
9
|
@release = true
|
|
10
10
|
# end ivars
|
|
11
11
|
|
|
@@ -29,7 +29,7 @@ module Bundler
|
|
|
29
29
|
|
|
30
30
|
# If Bundler has been installed without its .git directory and without a
|
|
31
31
|
# commit instance variable then we can't determine its commits SHA.
|
|
32
|
-
git_dir = File.
|
|
32
|
+
git_dir = File.expand_path("../../../.git", __dir__)
|
|
33
33
|
if File.directory?(git_dir)
|
|
34
34
|
return @git_commit_sha = Dir.chdir(git_dir) { `git rev-parse --short HEAD`.strip.freeze }
|
|
35
35
|
end
|
|
@@ -32,7 +32,7 @@ module Bundler
|
|
|
32
32
|
file << spec.to_gemfile
|
|
33
33
|
end
|
|
34
34
|
else
|
|
35
|
-
FileUtils.cp(File.expand_path("
|
|
35
|
+
FileUtils.cp(File.expand_path("../templates/#{gemfile}", __dir__), gemfile)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
puts "Writing new #{gemfile} to #{SharedHelpers.pwd}/#{gemfile}"
|
data/bundler/lib/bundler/cli.rb
CHANGED
|
@@ -610,7 +610,7 @@ module Bundler
|
|
|
610
610
|
private :gem
|
|
611
611
|
|
|
612
612
|
def self.source_root
|
|
613
|
-
File.expand_path(
|
|
613
|
+
File.expand_path("templates", __dir__)
|
|
614
614
|
end
|
|
615
615
|
|
|
616
616
|
desc "clean [OPTIONS]", "Cleans up unused gems in your bundler directory", :hide => true
|
|
@@ -119,7 +119,7 @@ module Bundler
|
|
|
119
119
|
relative_gemfile_path = relative_gemfile_path
|
|
120
120
|
ruby_command = Thor::Util.ruby_command
|
|
121
121
|
ruby_command = ruby_command
|
|
122
|
-
template_path = File.expand_path("
|
|
122
|
+
template_path = File.expand_path("templates/Executable", __dir__)
|
|
123
123
|
if spec.name == "bundler"
|
|
124
124
|
template_path += ".bundler"
|
|
125
125
|
spec.executables = %(bundle)
|
|
@@ -172,7 +172,7 @@ module Bundler
|
|
|
172
172
|
end
|
|
173
173
|
standalone_path = Bundler.root.join(path).relative_path_from(bin_path)
|
|
174
174
|
standalone_path = standalone_path
|
|
175
|
-
template = File.read(File.expand_path("
|
|
175
|
+
template = File.read(File.expand_path("templates/Executable.standalone", __dir__))
|
|
176
176
|
ruby_command = Thor::Util.ruby_command
|
|
177
177
|
ruby_command = ruby_command
|
|
178
178
|
|
|
@@ -36,13 +36,13 @@ Executing \fBbundle config list\fR with will print a list of all bundler configu
|
|
|
36
36
|
Executing \fBbundle config get <name>\fR will print the value of that configuration setting, and where it was set\.
|
|
37
37
|
.
|
|
38
38
|
.P
|
|
39
|
-
Executing \fBbundle config set <name> <value>\fR
|
|
39
|
+
Executing \fBbundle config set <name> <value>\fR defaults to setting \fBlocal\fR configuration if executing from within a local application, otherwise it will set \fBglobal\fR configuration\. See \fB\-\-local\fR and \fB\-\-global\fR options below\.
|
|
40
40
|
.
|
|
41
41
|
.P
|
|
42
|
-
Executing \fBbundle config set \-\-
|
|
42
|
+
Executing \fBbundle config set \-\-local <name> <value>\fR will set that configuration in the directory for the local application\. The configuration will be stored in \fB<project_root>/\.bundle/config\fR\. If \fBBUNDLE_APP_CONFIG\fR is set, the configuration will be stored in \fB$BUNDLE_APP_CONFIG/config\fR\.
|
|
43
43
|
.
|
|
44
44
|
.P
|
|
45
|
-
Executing \fBbundle config set \-\-
|
|
45
|
+
Executing \fBbundle config set \-\-global <name> <value>\fR will set that configuration to the value specified for all bundles executed as the current user\. The configuration will be stored in \fB~/\.bundle/config\fR\. If \fIname\fR already is set, \fIname\fR will be overridden and user will be warned\.
|
|
46
46
|
.
|
|
47
47
|
.P
|
|
48
48
|
Executing \fBbundle config unset <name>\fR will delete the configuration in both local and global sources\.
|
|
@@ -23,18 +23,20 @@ was set.
|
|
|
23
23
|
Executing `bundle config get <name>` will print the value of that configuration
|
|
24
24
|
setting, and where it was set.
|
|
25
25
|
|
|
26
|
-
Executing `bundle config set <name> <value>`
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
overridden and user will be warned.
|
|
30
|
-
|
|
31
|
-
Executing `bundle config set --global <name> <value>` works the same as above.
|
|
26
|
+
Executing `bundle config set <name> <value>` defaults to setting `local`
|
|
27
|
+
configuration if executing from within a local application, otherwise it will
|
|
28
|
+
set `global` configuration. See `--local` and `--global` options below.
|
|
32
29
|
|
|
33
30
|
Executing `bundle config set --local <name> <value>` will set that configuration
|
|
34
31
|
in the directory for the local application. The configuration will be stored in
|
|
35
32
|
`<project_root>/.bundle/config`. If `BUNDLE_APP_CONFIG` is set, the configuration
|
|
36
33
|
will be stored in `$BUNDLE_APP_CONFIG/config`.
|
|
37
34
|
|
|
35
|
+
Executing `bundle config set --global <name> <value>` will set that
|
|
36
|
+
configuration to the value specified for all bundles executed as the current
|
|
37
|
+
user. The configuration will be stored in `~/.bundle/config`. If <name> already
|
|
38
|
+
is set, <name> will be overridden and user will be warned.
|
|
39
|
+
|
|
38
40
|
Executing `bundle config unset <name>` will delete the configuration in both
|
|
39
41
|
local and global sources.
|
|
40
42
|
|
|
@@ -274,10 +274,10 @@ module Bundler
|
|
|
274
274
|
|
|
275
275
|
def set_bundle_variables
|
|
276
276
|
# bundler exe & lib folders have same root folder, typical gem installation
|
|
277
|
-
exe_file = File.expand_path("
|
|
277
|
+
exe_file = File.expand_path("../../exe/bundle", __dir__)
|
|
278
278
|
|
|
279
279
|
# for Ruby core repository testing
|
|
280
|
-
exe_file = File.expand_path("
|
|
280
|
+
exe_file = File.expand_path("../../libexec/bundle", __dir__) unless File.exist?(exe_file)
|
|
281
281
|
|
|
282
282
|
# bundler is a default gem, exe path is separate
|
|
283
283
|
exe_file = Bundler.rubygems.bin_path("bundler", "bundle", VERSION) unless File.exist?(exe_file)
|
|
@@ -309,7 +309,7 @@ module Bundler
|
|
|
309
309
|
end
|
|
310
310
|
|
|
311
311
|
def bundler_ruby_lib
|
|
312
|
-
|
|
312
|
+
File.expand_path("..", __dir__)
|
|
313
313
|
end
|
|
314
314
|
|
|
315
315
|
def clean_load_path
|
|
@@ -325,7 +325,7 @@ module Bundler
|
|
|
325
325
|
|
|
326
326
|
def resolve_path(path)
|
|
327
327
|
expanded = File.expand_path(path)
|
|
328
|
-
return expanded unless File.
|
|
328
|
+
return expanded unless File.exist?(expanded)
|
|
329
329
|
|
|
330
330
|
File.realpath(expanded)
|
|
331
331
|
end
|
|
@@ -22,7 +22,7 @@ module Bundler
|
|
|
22
22
|
s.summary = "The best way to manage your application's dependencies"
|
|
23
23
|
s.executables = %w[bundle]
|
|
24
24
|
# can't point to the actual gemspec or else the require paths will be wrong
|
|
25
|
-
s.loaded_from =
|
|
25
|
+
s.loaded_from = __dir__
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
if local_spec = Bundler.rubygems.find_bundler(VERSION)
|
|
@@ -8,11 +8,9 @@
|
|
|
8
8
|
# this file is here to facilitate running it.
|
|
9
9
|
#
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../<%= relative_gemfile_path %>",
|
|
13
|
-
Pathname.new(__FILE__).realpath)
|
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("<%= relative_gemfile_path %>", __dir__)
|
|
14
12
|
|
|
15
|
-
bundle_binstub = File.expand_path("
|
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
|
16
14
|
|
|
17
15
|
if File.file?(bundle_binstub)
|
|
18
16
|
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
# this file is here to facilitate running it.
|
|
7
7
|
#
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
path = Pathname.new(__FILE__)
|
|
11
|
-
$:.unshift File.expand_path "../<%= standalone_path %>", path.realpath
|
|
9
|
+
$:.unshift File.expand_path "<%= standalone_path %>", __dir__
|
|
12
10
|
|
|
13
11
|
require "bundler/setup"
|
|
14
|
-
load File.expand_path "
|
|
12
|
+
load File.expand_path "<%= executable_path %>", __dir__
|
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
|
|
25
25
|
# Specify which files should be added to the gem when it is released.
|
|
26
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
27
|
-
spec.files = Dir.chdir(
|
|
27
|
+
spec.files = Dir.chdir(__dir__) do
|
|
28
28
|
`git ls-files -z`.split("\x0").reject do |f|
|
|
29
29
|
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
30
30
|
end
|
data/bundler/lib/bundler.rb
CHANGED
|
@@ -341,7 +341,7 @@ By default, this RubyGems will install gem as:
|
|
|
341
341
|
|
|
342
342
|
fake_spec = Gem::Specification.new 'rubygems', Gem::VERSION
|
|
343
343
|
def fake_spec.full_gem_path
|
|
344
|
-
File.expand_path '
|
|
344
|
+
File.expand_path '../../..', __dir__
|
|
345
345
|
end
|
|
346
346
|
|
|
347
347
|
generate_ri = options[:document].include? 'ri'
|
data/lib/rubygems/ext/builder.rb
CHANGED
|
@@ -123,6 +123,9 @@ class Gem::Ext::Builder
|
|
|
123
123
|
Gem::Ext::RakeBuilder
|
|
124
124
|
when /CMakeLists.txt/ then
|
|
125
125
|
Gem::Ext::CmakeBuilder
|
|
126
|
+
when /Cargo.toml/ then
|
|
127
|
+
# We use the spec name here to ensure we invoke the correct init function later
|
|
128
|
+
Gem::Ext::CargoBuilder.new(@spec)
|
|
126
129
|
else
|
|
127
130
|
build_error("No builder for extension '#{extension}'")
|
|
128
131
|
end
|
|
@@ -0,0 +1,305 @@
|
|
|
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_reader :spec
|
|
8
|
+
|
|
9
|
+
def initialize(spec)
|
|
10
|
+
@spec = spec
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def build(_extension, dest_path, results, args = [], lib_dir = nil, cargo_dir = Dir.pwd)
|
|
14
|
+
require "rubygems/command"
|
|
15
|
+
require "fileutils"
|
|
16
|
+
require "shellwords"
|
|
17
|
+
|
|
18
|
+
build_crate(dest_path, results, args, cargo_dir)
|
|
19
|
+
ext_path = rename_cdylib_for_ruby_compatibility(dest_path)
|
|
20
|
+
finalize_directory(ext_path, dest_path, lib_dir, cargo_dir)
|
|
21
|
+
results
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def build_crate(dest_path, results, args, cargo_dir)
|
|
27
|
+
manifest = File.join(cargo_dir, "Cargo.toml")
|
|
28
|
+
|
|
29
|
+
given_ruby_static = ENV["RUBY_STATIC"]
|
|
30
|
+
|
|
31
|
+
ENV["RUBY_STATIC"] = "true" if ruby_static? && !given_ruby_static
|
|
32
|
+
|
|
33
|
+
cargo = ENV.fetch("CARGO", "cargo")
|
|
34
|
+
|
|
35
|
+
cmd = []
|
|
36
|
+
cmd += [cargo, "rustc"]
|
|
37
|
+
cmd += ["--target-dir", dest_path]
|
|
38
|
+
cmd += ["--manifest-path", manifest]
|
|
39
|
+
cmd += ["--lib", "--release", "--locked"]
|
|
40
|
+
cmd += ["--"]
|
|
41
|
+
cmd += [*cargo_rustc_args(dest_path)]
|
|
42
|
+
cmd += Gem::Command.build_args
|
|
43
|
+
cmd += args
|
|
44
|
+
|
|
45
|
+
self.class.run cmd, results, self.class.class_name, cargo_dir
|
|
46
|
+
results
|
|
47
|
+
ensure
|
|
48
|
+
ENV["RUBY_STATIC"] = given_ruby_static
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def cargo_rustc_args(dest_dir)
|
|
52
|
+
[
|
|
53
|
+
*linker_args,
|
|
54
|
+
*mkmf_libpath,
|
|
55
|
+
*rustc_dynamic_linker_flags(dest_dir),
|
|
56
|
+
*rustc_lib_flags(dest_dir),
|
|
57
|
+
*platform_specific_rustc_args(dest_dir),
|
|
58
|
+
*debug_flags,
|
|
59
|
+
]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def platform_specific_rustc_args(dest_dir, flags = [])
|
|
63
|
+
if mingw_target?
|
|
64
|
+
# On mingw platforms, mkmf adds libruby to the linker flags
|
|
65
|
+
flags += libruby_args(dest_dir)
|
|
66
|
+
|
|
67
|
+
# Make sure ALSR is used on mingw
|
|
68
|
+
# see https://github.com/rust-lang/rust/pull/75406/files
|
|
69
|
+
flags += ["-C", "link-arg=-Wl,--dynamicbase"]
|
|
70
|
+
flags += ["-C", "link-arg=-Wl,--disable-auto-image-base"]
|
|
71
|
+
|
|
72
|
+
# If the gem is installed on a host with build tools installed, but is
|
|
73
|
+
# run on one that isn't the missing libraries will cause the extension
|
|
74
|
+
# to fail on start.
|
|
75
|
+
flags += ["-C", "link-arg=-static-libgcc"]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
flags
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# We want to use the same linker that Ruby uses, so that the linker flags from
|
|
82
|
+
# mkmf work properly.
|
|
83
|
+
def linker_args
|
|
84
|
+
# Have to handle CC="cl /nologo" on mswin
|
|
85
|
+
cc_flag = Shellwords.split(makefile_config("CC"))
|
|
86
|
+
linker = cc_flag.shift
|
|
87
|
+
link_args = cc_flag.flat_map {|a| ["-C", "link-arg=#{a}"] }
|
|
88
|
+
|
|
89
|
+
["-C", "linker=#{linker}", *link_args]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def libruby_args(dest_dir)
|
|
93
|
+
libs = makefile_config(ruby_static? ? "LIBRUBYARG_STATIC" : "LIBRUBYARG_SHARED")
|
|
94
|
+
raw_libs = Shellwords.split(libs)
|
|
95
|
+
raw_libs.flat_map {|l| ldflag_to_link_modifier(l, dest_dir) }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def ruby_static?
|
|
99
|
+
return true if %w[1 true].include?(ENV["RUBY_STATIC"])
|
|
100
|
+
|
|
101
|
+
makefile_config("ENABLE_SHARED") == "no"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Ruby expects the dylib to follow a file name convention for loading
|
|
105
|
+
def rename_cdylib_for_ruby_compatibility(dest_path)
|
|
106
|
+
dylib_path = validate_cargo_build!(dest_path)
|
|
107
|
+
dlext_name = "#{spec.name}.#{makefile_config("DLEXT")}"
|
|
108
|
+
new_name = dylib_path.gsub(File.basename(dylib_path), dlext_name)
|
|
109
|
+
FileUtils.cp(dylib_path, new_name)
|
|
110
|
+
new_name
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def validate_cargo_build!(dir)
|
|
114
|
+
prefix = so_ext == "dll" ? "" : "lib"
|
|
115
|
+
dylib_path = File.join(dir, "release", "#{prefix}#{cargo_crate_name}.#{so_ext}")
|
|
116
|
+
|
|
117
|
+
raise DylibNotFoundError, dir unless File.exist?(dylib_path)
|
|
118
|
+
|
|
119
|
+
dylib_path
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def cargo_crate_name
|
|
123
|
+
spec.metadata.fetch('cargo_crate_name', spec.name).tr('-', '_')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def rustc_dynamic_linker_flags(dest_dir)
|
|
127
|
+
split_flags("DLDFLAGS")
|
|
128
|
+
.map {|arg| maybe_resolve_ldflag_variable(arg, dest_dir) }
|
|
129
|
+
.compact
|
|
130
|
+
.flat_map {|arg| ldflag_to_link_modifier(arg, dest_dir) }
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def rustc_lib_flags(dest_dir)
|
|
134
|
+
split_flags("LIBS").flat_map {|arg| ldflag_to_link_modifier(arg, dest_dir) }
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def split_flags(var)
|
|
138
|
+
Shellwords.split(RbConfig::CONFIG.fetch(var, ""))
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def ldflag_to_link_modifier(arg, dest_dir)
|
|
142
|
+
flag = arg[0..1]
|
|
143
|
+
val = arg[2..-1]
|
|
144
|
+
|
|
145
|
+
case flag
|
|
146
|
+
when "-L" then ["-L", "native=#{val}"]
|
|
147
|
+
when "-l" then ["-l", val.to_s]
|
|
148
|
+
when "-F" then ["-l", "framework=#{val}"]
|
|
149
|
+
else ["-C", "link_arg=#{arg}"]
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def link_flag(link_name)
|
|
154
|
+
# These are provided by the CRT with MSVC
|
|
155
|
+
# @see https://github.com/rust-lang/pkg-config-rs/blob/49a4ac189aafa365167c72e8e503565a7c2697c2/src/lib.rs#L622
|
|
156
|
+
return [] if msvc_target? && ["m", "c", "pthread"].include?(link_name)
|
|
157
|
+
|
|
158
|
+
if link_name.include?("ruby")
|
|
159
|
+
# Specify the lib kind and give it the name "ruby" for linking
|
|
160
|
+
kind = ruby_static? ? "static" : "dylib"
|
|
161
|
+
|
|
162
|
+
["-l", "#{kind}=ruby:#{link_name}"]
|
|
163
|
+
else
|
|
164
|
+
["-l", link_name]
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def msvc_target?
|
|
169
|
+
makefile_config("target_os").include?("msvc")
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def darwin_target?
|
|
173
|
+
makefile_config("target_os").include?("darwin")
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def mingw_target?
|
|
177
|
+
makefile_config("target_os").include?("mingw")
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def win_target?
|
|
181
|
+
target_platform = RbConfig::CONFIG["target_os"]
|
|
182
|
+
!!Gem::WIN_PATTERNS.find {|r| target_platform =~ r }
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Intepolate substition vars in the arg (i.e. $(DEFFILE))
|
|
186
|
+
def maybe_resolve_ldflag_variable(input_arg, dest_dir)
|
|
187
|
+
str = input_arg.gsub(/\$\((\w+)\)/) do |var_name|
|
|
188
|
+
case var_name
|
|
189
|
+
# On windows, it is assumed that mkmf has setup an exports file for the
|
|
190
|
+
# extension, so we have to to create one ourselves.
|
|
191
|
+
when "DEFFILE"
|
|
192
|
+
write_deffile(dest_dir)
|
|
193
|
+
else
|
|
194
|
+
RbConfig::CONFIG[var_name]
|
|
195
|
+
end
|
|
196
|
+
end.strip
|
|
197
|
+
|
|
198
|
+
str == "" ? nil : str
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def write_deffile(dest_dir)
|
|
202
|
+
deffile_path = File.join(dest_dir, "#{spec.name}-#{RbConfig::CONFIG["arch"]}.def")
|
|
203
|
+
export_prefix = makefile_config("EXPORT_PREFIX") || ""
|
|
204
|
+
|
|
205
|
+
File.open(deffile_path, "w") do |f|
|
|
206
|
+
f.puts "EXPORTS"
|
|
207
|
+
f.puts "#{export_prefix.strip}Init_#{spec.name}"
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
deffile_path
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# We have to basically reimplement RbConfig::CONFIG['SOEXT'] here to support
|
|
214
|
+
# Ruby < 2.5
|
|
215
|
+
#
|
|
216
|
+
# @see https://github.com/ruby/ruby/blob/c87c027f18c005460746a74c07cd80ee355b16e4/configure.ac#L3185
|
|
217
|
+
def so_ext
|
|
218
|
+
return RbConfig::CONFIG["SOEXT"] if RbConfig::CONFIG.key?("SOEXT")
|
|
219
|
+
|
|
220
|
+
if win_target?
|
|
221
|
+
"dll"
|
|
222
|
+
elsif darwin_target?
|
|
223
|
+
"dylib"
|
|
224
|
+
else
|
|
225
|
+
"so"
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Corresponds to $(LIBPATH) in mkmf
|
|
230
|
+
def mkmf_libpath
|
|
231
|
+
["-L", "native=#{makefile_config("libdir")}"]
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def makefile_config(var_name)
|
|
235
|
+
val = RbConfig::MAKEFILE_CONFIG[var_name]
|
|
236
|
+
|
|
237
|
+
return unless val
|
|
238
|
+
|
|
239
|
+
RbConfig.expand(val.dup)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Good balance between binary size and debugability
|
|
243
|
+
def debug_flags
|
|
244
|
+
["-C", "debuginfo=1"]
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Copied from ExtConfBuilder
|
|
248
|
+
def finalize_directory(ext_path, dest_path, lib_dir, extension_dir)
|
|
249
|
+
require "fileutils"
|
|
250
|
+
require "tempfile"
|
|
251
|
+
|
|
252
|
+
begin
|
|
253
|
+
tmp_dest = Dir.mktmpdir(".gem.", extension_dir)
|
|
254
|
+
|
|
255
|
+
# Some versions of `mktmpdir` return absolute paths, which will break make
|
|
256
|
+
# if the paths contain spaces. However, on Ruby 1.9.x on Windows, relative
|
|
257
|
+
# paths cause all C extension builds to fail.
|
|
258
|
+
#
|
|
259
|
+
# As such, we convert to a relative path unless we are using Ruby 1.9.x on
|
|
260
|
+
# Windows. This means that when using Ruby 1.9.x on Windows, paths with
|
|
261
|
+
# spaces do not work.
|
|
262
|
+
#
|
|
263
|
+
# Details: https://github.com/rubygems/rubygems/issues/977#issuecomment-171544940
|
|
264
|
+
tmp_dest_relative = get_relative_path(tmp_dest.clone, extension_dir)
|
|
265
|
+
|
|
266
|
+
if tmp_dest_relative
|
|
267
|
+
full_tmp_dest = File.join(extension_dir, tmp_dest_relative)
|
|
268
|
+
|
|
269
|
+
# TODO: remove in RubyGems 3
|
|
270
|
+
if Gem.install_extension_in_lib && lib_dir
|
|
271
|
+
FileUtils.mkdir_p lib_dir
|
|
272
|
+
FileUtils.cp_r ext_path, lib_dir, remove_destination: true
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
FileUtils::Entry_.new(full_tmp_dest).traverse do |ent|
|
|
276
|
+
destent = ent.class.new(dest_path, ent.rel)
|
|
277
|
+
destent.exist? || FileUtils.mv(ent.path, destent.path)
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
ensure
|
|
281
|
+
FileUtils.rm_rf tmp_dest if tmp_dest
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def get_relative_path(path, base)
|
|
286
|
+
path[0..base.length - 1] = "." if path.start_with?(base)
|
|
287
|
+
path
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Error raised when no cdylib artifact was created
|
|
291
|
+
class DylibNotFoundError < StandardError
|
|
292
|
+
def initialize(dir)
|
|
293
|
+
files = Dir.glob(File.join(dir, "**", "*")).map {|f| "- #{f}" }.join "\n"
|
|
294
|
+
|
|
295
|
+
super <<~MSG
|
|
296
|
+
Dynamic library not found for Rust extension (in #{dir})
|
|
297
|
+
|
|
298
|
+
Make sure you set "crate-type" in Cargo.toml to "cdylib"
|
|
299
|
+
|
|
300
|
+
Found files:
|
|
301
|
+
#{files}
|
|
302
|
+
MSG
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|