Skip to content

Commit

Permalink
set required_rubygems_version for linux libc platforms
Browse files Browse the repository at this point in the history
If rake-compiler is building a linux native gem that specifies a libc
in its platform object, then we add ">= 3.3.22" to the
required_rubygems_version requirement.

Rubygems does not correctly recognize `-musl` or `-gnu` platform
suffixes until v3.3.22.

https://github.com/rubygems/rubygems/blob/master/CHANGELOG.md#3322--2022-09-07
  • Loading branch information
flavorjones committed Jan 30, 2024
1 parent 322cf97 commit fa8097d
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 0 deletions.
10 changes: 10 additions & 0 deletions lib/rake/extensiontask.rb
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,16 @@ def define_native_tasks(for_platform = nil, ruby_ver = RUBY_VERSION, callback =
"< #{ruby_api_version(sorted_ruby_versions.last).succ}.dev"
]

# set rubygems version constraints
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new("3.3.22") &&
spec.platform.os == "linux" && !spec.platform.version.nil?
if spec.required_rubygems_version == Gem::Requirement.default
spec.required_rubygems_version = [">= 3.3.22"]
else
spec.required_rubygems_version = Gem::Requirement.new(gem_spec.required_rubygems_version, ">= 3.3.22")
end
end

# clear the extensions defined in the specs
spec.extensions.clear

Expand Down
88 changes: 88 additions & 0 deletions spec/lib/rake/extensiontask_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,94 @@
spec.metadata['allowed_push_host'].should eq 'http://test'
end

it "should set required_rubygems_version when building a gem for `-linux-gnu` or `-linux-musl`" do
platforms = ["arm64-darwin", "arm-linux", "arm-linux-gnu", "arm-linux-musl"]
ruby_cc_versions = ["3.3.0"]
ENV["RUBY_CC_VERSION"] = ruby_cc_versions.join(":")

ruby_cc_versions.each do |ruby_cc_version|
platforms.each do |platform|
rbconf = "/rubies/#{ruby_cc_version}/rbconfig.rb"
allow_any_instance_of(Rake::CompilerConfig).to(
receive(:find)
.with(ruby_cc_version, platform)
.and_return(rbconf)
)
end
end

allow(Gem).to receive_message_chain(:configuration, :verbose=).and_return(true)

spec = Gem::Specification.new do |s|
s.name = 'my_gem'
s.platform = Gem::Platform::RUBY
s.extensions = ['ext/somegem/extconf.rb']
end

cross_specs = {} # platform => spec
Rake::ExtensionTask.new("extension_one", spec) do |ext|
ext.cross_platform = platforms
ext.cross_compile = true
ext.cross_compiling do |cross_spec|
cross_specs[cross_spec.platform.to_s] = cross_spec
end
end
platforms.each do |platform|
Rake::Task["native:my_gem:#{platform}"].execute
end

cross_specs["arm64-darwin"].required_rubygems_version.should eq(Gem::Requirement.default)
cross_specs["arm-linux"].required_rubygems_version.should eq(Gem::Requirement.default)

if Gem::Version.new(Gem::VERSION) >= Gem::Version.new("3.3.22")
expected_rubygems_version = Gem::Requirement.new([">= 3.3.22"])
cross_specs["arm-linux-gnu"].required_rubygems_version.should eq(expected_rubygems_version)
cross_specs["arm-linux-musl"].required_rubygems_version.should eq(expected_rubygems_version)
end
end

it "should append to required_rubygems_version if it's set" do
platform = "arm-linux-musl"
ruby_cc_versions = ["3.3.0"]
ENV["RUBY_CC_VERSION"] = ruby_cc_versions.join(":")

ruby_cc_versions.each do |ruby_cc_version|
rbconf = "/rubies/#{ruby_cc_version}/rbconfig.rb"
allow_any_instance_of(Rake::CompilerConfig).to(
receive(:find)
.with(ruby_cc_version, platform)
.and_return(rbconf)
)
end

allow(Gem).to receive_message_chain(:configuration, :verbose=).and_return(true)

spec = Gem::Specification.new do |s|
s.name = 'my_gem'
s.platform = Gem::Platform::RUBY
s.extensions = ['ext/somegem/extconf.rb']
s.required_rubygems_version = "!= 3.4.1" # keep this around
end

actual_cross_spec = nil
Rake::ExtensionTask.new("extension_one", spec) do |ext|
ext.cross_platform = [platform]
ext.cross_compile = true
ext.cross_compiling do |cross_spec|
actual_cross_spec = cross_spec
end
end
Rake::Task["native:my_gem:#{platform}"].execute

expected_rubygems_version = Gem::Requirement.new(["!= 3.4.1", ">= 3.3.22"])

if Gem::Version.new(Gem::VERSION) < Gem::Version.new("3.3.22")
actual_cross_spec.required_rubygems_version.should eq(Gem::Requirement.new(["!= 3.4.1"]))
else
actual_cross_spec.required_rubygems_version.should eq(expected_rubygems_version)
end
end

after :each do
ENV.delete('RUBY_CC_VERSION')
end
Expand Down

0 comments on commit fa8097d

Please sign in to comment.