Skip to content

Commit

Permalink
fix(windows): version info contains ldflags on windows
Browse files Browse the repository at this point in the history
to allow downstream gems like nokogumbo to build correctly simply by
requiring nokogiri in the extconf and running:

  append_cflags(Nokogiri::VERSION_INFO["nokogiri"]["cppflags"])
  append_ldflags(Nokogiri::VERSION_INFO["nokogiri"]["ldflags"])

this is needed because unresolved symbols aren't allowed on windows.

Related to #2167
  • Loading branch information
flavorjones committed Mar 7, 2021
1 parent bb7cab7 commit 1b448d7
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
23 changes: 23 additions & 0 deletions lib/nokogiri/version/info.rb
Expand Up @@ -10,6 +10,14 @@ def jruby?
::JRUBY_VERSION if ::RUBY_PLATFORM == "java"
end

def windows?
::RUBY_PLATFORM =~ /mingw|mswin/
end

def ruby_minor
Gem::Version.new(::RUBY_VERSION).segments[0..1].join(".")
end

def engine
defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "mri"
end
Expand Down Expand Up @@ -74,18 +82,33 @@ def warnings

def to_hash
header_directory = File.expand_path(File.join(File.dirname(__FILE__), "../../../ext/nokogiri"))

{}.tap do |vi|
vi["warnings"] = []
vi["nokogiri"] = {}.tap do |nokogiri|
nokogiri["version"] = Nokogiri::VERSION

unless jruby?
cppflags = ["-I#{header_directory.shellescape}"]
ldflags = []

if libxml2_using_packaged?
cppflags << "-I#{File.join(header_directory, 'include').shellescape}"
cppflags << "-I#{File.join(header_directory, 'include/libxml2').shellescape}"

if windows?
# on windows, nokogumbo needs to link against nokogiri.so to resolve symbols. see #2167
lib_directory = File.expand_path(File.join(File.dirname(__FILE__), "../#{ruby_minor}"))
unless File.exist?(lib_directory)
lib_directory = File.expand_path(File.join(File.dirname(__FILE__), ".."))
end
ldflags << "-L#{lib_directory.shellescape}"
ldflags << "-l:nokogiri.so"
end
end

nokogiri["cppflags"] = cppflags
nokogiri["ldflags"] = ldflags
end
end
vi["ruby"] = {}.tap do |ruby|
Expand Down
16 changes: 16 additions & 0 deletions scripts/test-gem-installation
Expand Up @@ -43,6 +43,8 @@ Minitest::Reporters.use!([Minitest::Reporters::SpecReporter.new])

puts "Testing #{gemspec.full_name} installed in #{gemspec.base_dir}"
describe gemspec.full_name do
let(:ruby_maj_min) { Gem::Version.new(::RUBY_VERSION).segments[0..1].join(".") }
let(:nokogiri_lib_dir) { File.join(gemspec.gem_dir, "lib/nokogiri") }
let(:nokogiri_ext_dir) { File.join(gemspec.gem_dir, "ext/nokogiri") }
let(:nokogiri_include_dir) { File.join(nokogiri_ext_dir, "include") }

Expand Down Expand Up @@ -108,6 +110,20 @@ describe gemspec.full_name do
assert(found, "expected to find #{header} in one of: #{headers_dirs.inspect}")
end
end

it "has ldflags pointing to the shared object file" do
ldflags = Nokogiri::VERSION_INFO["nokogiri"]["ldflags"]
if ::RUBY_PLATFORM =~ /mingw|mswin/
if gemspec.platform.cpu
assert_includes(ldflags, "-L#{File.join(nokogiri_lib_dir, ruby_maj_min)}")
else
assert_includes(ldflags, "-L#{nokogiri_lib_dir}")
end
assert_includes(ldflags, "-l:nokogiri.so")
else
assert_empty(ldflags)
end
end
end if Nokogiri::VersionInfo.instance.libxml2_using_packaged?

describe "using system libraries" do
Expand Down
5 changes: 3 additions & 2 deletions test/test_version.rb
Expand Up @@ -18,8 +18,9 @@ def test_version_info_basics
if jruby?
refute(Nokogiri::VERSION_INFO["nokogiri"].has_key?("cppflags"), "did not expect cppflags")
else
# cppflags are more fully tested in scripts/test-gem-installation
assert_kind_of(Array, Nokogiri::VERSION_INFO["nokogiri"]["cppflags"], "expected cppflags to be an array")
# cppflags/ldflags are more fully tested in scripts/test-gem-installation
assert_kind_of(Array, Nokogiri::VERSION_INFO["nokogiri"]["cppflags"], "cppflags should be an array")
assert_kind_of(Array, Nokogiri::VERSION_INFO["nokogiri"]["ldflags"], "ldflags should be an array")
end

assert_equal(::RUBY_VERSION, Nokogiri::VERSION_INFO["ruby"]["version"])
Expand Down

0 comments on commit 1b448d7

Please sign in to comment.