Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fat binary gem support for ruby-3.1 #2409

Merged
merged 9 commits into from Jan 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 27 additions & 20 deletions .cross_rubies
@@ -1,21 +1,28 @@
3.0.0:i686-w64-mingw32
3.0.0:x86_64-w64-mingw32
3.0.0:i686-linux-gnu
3.0.0:x86_64-linux-gnu
3.0.0:x86_64-darwin
3.0.0:arm64-darwin
3.0.0:aarch64-linux
2.7.0:i686-w64-mingw32
2.7.0:x86_64-w64-mingw32
2.7.0:i686-linux-gnu
2.7.0:x86_64-linux-gnu
2.7.0:x86_64-darwin
2.7.0:arm64-darwin
2.7.0:aarch64-linux
2.6.0:i686-w64-mingw32
2.6.0:x86_64-w64-mingw32
2.6.0:i686-linux-gnu
2.6.0:x86_64-linux-gnu
2.6.0:x86_64-darwin
2.6.0:arm64-darwin
2.6.0:aarch64-linux
2.6.0:arm64-darwin
2.6.0:x64-mingw32
2.6.0:x86-linux
2.6.0:x86-mingw32
2.6.0:x86_64-darwin
2.6.0:x86_64-linux
2.7.0:aarch64-linux
2.7.0:arm64-darwin
2.7.0:x64-mingw32
2.7.0:x86-linux
2.7.0:x86-mingw32
2.7.0:x86_64-darwin
2.7.0:x86_64-linux
3.0.0:aarch64-linux
3.0.0:arm64-darwin
3.0.0:x64-mingw32
3.0.0:x86-linux
3.0.0:x86-mingw32
3.0.0:x86_64-darwin
3.0.0:x86_64-linux
3.1.0:aarch64-linux
3.1.0:arm64-darwin
3.1.0:x64-mingw-ucrt
3.1.0:x86-linux
3.1.0:x86-mingw32
3.1.0:x86_64-darwin
3.1.0:x86_64-linux
32 changes: 26 additions & 6 deletions .github/workflows/gem-install.yml
Expand Up @@ -20,7 +20,7 @@ jobs:
name: "cruby-package"
runs-on: ubuntu-latest
container:
image: "larskanis/rake-compiler-dock-mri-x86_64-linux:1.1.0"
image: "larskanis/rake-compiler-dock-mri-x86_64-linux:1.2.0"
steps:
- uses: actions/checkout@v2
with:
Expand Down Expand Up @@ -132,10 +132,10 @@ jobs:
strategy:
fail-fast: false
matrix:
plat: ["x86_64-linux", "x86_64-darwin", "x64-mingw32"]
plat: ["x86_64-linux", "x86_64-darwin", "x64-mingw32", "x64-mingw-ucrt"]
runs-on: ubuntu-latest
container:
image: "larskanis/rake-compiler-dock-mri-${{matrix.plat}}:1.1.0"
image: "larskanis/rake-compiler-dock-mri-${{matrix.plat}}:1.2.0"
steps:
- uses: actions/checkout@v2
with:
Expand All @@ -156,7 +156,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby: ["2.6", "2.7", "3.0"]
ruby: ["2.6", "2.7", "3.0", "3.1"]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -193,7 +193,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby: ["2.6", "2.7", "3.0"]
ruby: ["2.6", "2.7", "3.0", "3.1"]
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -228,12 +228,32 @@ jobs:
gem list -d nokogiri
nokogiri -v

cruby-x64-mingw-ucrt-install:
needs: ["cruby-native-package"]
strategy:
fail-fast: false
matrix:
ruby: ["3.1"]
runs-on: windows-2022
steps:
- uses: MSP-Greg/setup-ruby-pkgs@win-ucrt-2
with:
ruby-version: "${{matrix.ruby}}"
setup-ruby-ref: MSP-Greg/ruby-setup-ruby/win-ucrt-1
- uses: actions/download-artifact@v2
with:
name: cruby-x64-mingw-ucrt-gem
path: gems
- run: |
gem install --verbose --no-document gems/*.gem
gem list -d nokogiri
nokogiri -v

jruby-package:
name: "jruby-package"
runs-on: ubuntu-latest
container:
image: "larskanis/rake-compiler-dock-jruby:1.1.0"
image: "larskanis/rake-compiler-dock-jruby:1.2.0"
steps:
- uses: actions/checkout@v2
with:
Expand Down
18 changes: 11 additions & 7 deletions CHANGELOG.md
Expand Up @@ -8,23 +8,27 @@ Nokogiri follows [Semantic Versioning](https://semver.org/), please see the [REA

### Notes

#### Ruby

This release introduces native gem support for Ruby 3.1. Please note that Windows users should use the `x64-mingw-ucrt` platform gem for Ruby 3.1, and `x64-mingw32` for Ruby 2.6–3.0 (see [RubyInstaller 3.1.0 release notes](https://rubyinstaller.org/2021/12/31/rubyinstaller-3.1.0-1-released.html)).

This release ends support for:

* Ruby 2.5, for which [official support ended 2021-03-31](https://www.ruby-lang.org/en/downloads/branches/).
* JRuby 9.2, which is a Ruby 2.5-compatible release.


#### Faster, more reliable installation: Native Gem for ARM64 Linux

This version of Nokogiri ships experimental native gem support for the `aarch64-linux` platform, which should support AWS Graviton and other ARM Linux platforms. We don't yet have CI running for this platform, and so we're interested in hearing back from y'all whether this is working, and what problems you're seeing. Please send us feedback here: [Feedback: Have you used the `aarch64-linux` native gem?](https://github.com/sparklemotion/nokogiri/discussions/2359)


#### Publishing

This version of Nokogiri opts-in to the ["MFA required to publish" setting](https://guides.rubygems.org/mfa-requirement-opt-in/) on Rubygems.org. This and all future Nokogiri gem files must be published to Rubygems by an account with multi-factor authentication enabled. This should provide some additional protection against supply-chain attacks.

A related discussion about Trust exists at [#2357](https://github.com/sparklemotion/nokogiri/issues/2357) in which I invite you to participate if you have feelings or opinions on this topic.

#### Ruby

This release ends support for:

* Ruby 2.5, for which [official support ended 2021-03-31](https://www.ruby-lang.org/en/downloads/branches/).
* JRuby 9.2, which is a Ruby 2.5-compatible release.


### Dependencies

Expand Down
15 changes: 11 additions & 4 deletions ext/nokogiri/extconf.rb
Expand Up @@ -176,7 +176,7 @@ def config_system_libraries?
end

def windows?
RbConfig::CONFIG["target_os"].match?(/mingw32|mswin/)
RbConfig::CONFIG["target_os"].match?(/mingw|mswin/)
end

def solaris?
Expand Down Expand Up @@ -413,9 +413,13 @@ def process_recipe(name, version, static_p, cross_p, cacheable_p = true)
end

MiniPortile.new(name, version).tap do |recipe|
def recipe.port_path
"#{@target}/#{RUBY_PLATFORM}/#{@name}/#{@version}"
end

recipe.target = File.join(PACKAGE_ROOT_DIR, "ports") if cacheable_p
# Prefer host_alias over host in order to use i586-mingw32msvc as
# correct compiler prefix for cross build, but use host if not set.
# Prefer host_alias over host in order to use the correct compiler prefix for cross build, but
# use host if not set.
recipe.host = RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"]
recipe.configure_options << "--libdir=#{File.join(recipe.path, "lib")}"

Expand Down Expand Up @@ -473,7 +477,7 @@ def process_recipe(name, version, static_p, cross_p, cacheable_p = true)
"#{key}=#{value.strip}"
end

checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{RUBY_PLATFORM}.installed"
if File.exist?(checkpoint) && !recipe.source_directory
message("Building Nokogiri with a packaged version of #{name}-#{version}.\n")
else
Expand Down Expand Up @@ -718,6 +722,9 @@ def compile
sha256: dependencies["libiconv"]["sha256"],
}]

# The libiconv configure script doesn't accept "arm64" host string but "aarch64"
recipe.host = recipe.host.gsub("arm64-apple-darwin", "aarch64-apple-darwin")

cflags = concat_flags(ENV["CFLAGS"], "-O2", "-U_FORTIFY_SOURCE", "-g")

recipe.configure_options += [
Expand Down
Binary file added misc/ruby-maven-3.3.12.gem
Binary file not shown.
9 changes: 2 additions & 7 deletions nokogiri.gemspec
Expand Up @@ -40,12 +40,7 @@ Gem::Specification.new do |spec|

spec.license = "MIT"

if java_p # rubocop:disable Style/ConditionalAssignment
# TODO: drop this more-liberal requirement for jruby when https://github.com/jruby/jruby/issues/6904 is fixed
spec.required_ruby_version = ">= 2.5.0"
else
spec.required_ruby_version = ">= 2.6.0" # rubocop:disable Gemspec/DuplicatedAssignment
end
spec.required_ruby_version = ">= 2.6.0"

spec.homepage = "https://nokogiri.org"
spec.metadata = {
Expand Down Expand Up @@ -332,7 +327,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency("minitest-reporters", "~> 1.4")
spec.add_development_dependency("rake", "~> 13.0")
spec.add_development_dependency("rake-compiler", "= 1.1.6")
spec.add_development_dependency("rake-compiler-dock", "~> 1.1")
spec.add_development_dependency("rake-compiler-dock", "~> 1.2")
spec.add_development_dependency("rdoc", "~> 6.3")
spec.add_development_dependency("rexical", "~> 1.0.7")
spec.add_development_dependency("rubocop", "~> 1.23")
Expand Down
88 changes: 64 additions & 24 deletions rakelib/extensions.rake
Expand Up @@ -3,8 +3,9 @@
require "rbconfig"
require "shellwords"

CrossRuby = Struct.new(:version, :host) do
CrossRuby = Struct.new(:version, :platform) do
WINDOWS_PLATFORM_REGEX = /mingw|mswin/
MINGWUCRT_PLATFORM_REGEX = /mingw-ucrt/
MINGW32_PLATFORM_REGEX = /mingw32/
LINUX_PLATFORM_REGEX = /linux/
X86_LINUX_PLATFORM_REGEX = /x86.*linux/
Expand Down Expand Up @@ -40,42 +41,44 @@ CrossRuby = Struct.new(:version, :host) do
end
end

def platform
@platform ||= case host
when /\Ax86_64.*mingw32/
"x64-mingw32"
when /\Ai[3-6]86.*mingw32/
"x86-mingw32"
when /\Ax86_64.*linux/
"x86_64-linux"
when /\Ai[3-6]86.*linux/
"x86-linux"
when /\Aaarch64-linux/
def host
@host ||= case platform
when "x64-mingw-ucrt"
"x86_64-w64-mingw32"
when "x64-mingw32"
"x86_64-w64-mingw32"
when "x86-mingw32"
"i686-w64-mingw32"
when "x86_64-linux"
"x86_64-linux-gnu"
when "x86-linux"
"i686-linux-gnu"
when "aarch64-linux"
"aarch64-linux"
when /\Ax86_64-darwin/
when "x86_64-darwin"
"x86_64-darwin"
when /\Aarm64-darwin/
"arm64-darwin"
when "arm64-darwin"
"aarch64-darwin"
else
raise "CrossRuby.platform: unsupported host: #{host}"
raise "CrossRuby.platform: unsupported platform: #{platform}"
end
end

def tool(name)
(@binutils_prefix ||= case platform
when "x64-mingw32"
when "x64-mingw-ucrt", "x64-mingw32"
"x86_64-w64-mingw32-"
when "x86-mingw32"
"i686-w64-mingw32-"
when "x86_64-linux"
"x86_64-redhat-linux-"
when "x86-linux"
"i686-redhat-linux-"
when /a.*64.*linux/
when "aarch64-linux"
"aarch64-linux-gnu-"
when /x86_64.*darwin/
when "x86_64-darwin"
"x86_64-apple-darwin-"
when /a.*64.*darwin/
when "arm64-darwin"
"aarch64-apple-darwin-"
else
raise "CrossRuby.tool: unmatched platform: #{platform}"
Expand All @@ -84,7 +87,7 @@ CrossRuby = Struct.new(:version, :host) do

def target_file_format
case platform
when "x64-mingw32"
when "x64-mingw-ucrt", "x64-mingw32"
"pei-x86-64"
when "x86-mingw32"
"pei-i386"
Expand Down Expand Up @@ -113,6 +116,8 @@ CrossRuby = Struct.new(:version, :host) do

def libruby_dll
case platform
when "x64-mingw-ucrt"
"x64-ucrt-ruby#{api_ver_suffix}.dll"
when "x64-mingw32"
"x64-msvcrt-ruby#{api_ver_suffix}.dll"
when "x86-mingw32"
Expand All @@ -133,6 +138,25 @@ CrossRuby = Struct.new(:version, :host) do
"advapi32.dll",
libruby_dll,
]
when MINGWUCRT_PLATFORM_REGEX
[
"kernel32.dll",
"ws2_32.dll",
"advapi32.dll",
"api-ms-win-crt-convert-l1-1-0.dll",
"api-ms-win-crt-environment-l1-1-0.dll",
"api-ms-win-crt-filesystem-l1-1-0.dll",
"api-ms-win-crt-heap-l1-1-0.dll",
"api-ms-win-crt-locale-l1-1-0.dll",
"api-ms-win-crt-math-l1-1-0.dll",
"api-ms-win-crt-private-l1-1-0.dll",
"api-ms-win-crt-runtime-l1-1-0.dll",
"api-ms-win-crt-stdio-l1-1-0.dll",
"api-ms-win-crt-string-l1-1-0.dll",
"api-ms-win-crt-time-l1-1-0.dll",
"api-ms-win-crt-utility-l1-1-0.dll",
libruby_dll,
]
when X86_LINUX_PLATFORM_REGEX
[
"libm.so.6",
Expand All @@ -145,6 +169,7 @@ CrossRuby = Struct.new(:version, :host) do
[
"libm.so.6",
"libc.so.6",
"libdl.so.2", # on old dists only - now in libc
"ld-linux-aarch64.so.1",
].tap do |dlls|
dlls << "libpthread.so.0" if ver < "2.6.0"
Expand Down Expand Up @@ -282,7 +307,7 @@ namespace "gem" do
desc "build native gem for #{plat} platform"
task plat do
RakeCompilerDock.sh(<<~EOT, platform: plat)
rvm use 3.0 &&
rvm use 3.1.0 &&
gem install bundler --no-document &&
bundle &&
bundle exec rake gem:#{plat}:builder MAKE='nice make -j`nproc`'
Expand All @@ -301,8 +326,14 @@ namespace "gem" do

desc "build a jruby gem"
task "jruby" do
RakeCompilerDock.sh("gem install bundler --no-document && bundle && bundle exec rake java gem",
rubyvm: "jruby", platform: "jruby")
# TODO: remove the ruby-maven bit after ruby-maven 3.3.13 or later is shipped
# see https://github.com/jruby/jruby/issues/6904
RakeCompilerDock.sh(<<~EOF, rubyvm: "jruby", platform: "jruby")
gem install bundler --no-document &&
gem install misc/ruby-maven-*.gem --no-document &&
bundle &&
bundle exec rake java gem
EOF
end

desc "build native gems for windows"
Expand Down Expand Up @@ -374,6 +405,15 @@ else
spec.files.reject! { |path| File.fnmatch?("gumbo-parser/**/*", path) }
spec.dependencies.reject! { |dep| dep.name == "mini_portile2" }

# I would like rake-compiler to do this, but can't quite figure it out right now
supported_rubies = CROSS_RUBIES.select { |c| spec.platform =~ c.platform }
.map { |c| Gem::Version.new(c.ver) }
.sort
spec.required_ruby_version = [
">= #{supported_rubies.first.to_s.split(".").take(2).join(".")}",
"< #{supported_rubies.last.to_s.split(".").take(2).join(".").succ}.dev",
]

# when pre-compiling a native gem, package all the C headers sitting in ext/nokogiri/include
# which were copied there in the $INSTALLFILES section of extconf.rb.
# (see scripts/test-gem-file-contents and scripts/test-gem-installation for tests)
Expand Down