class Object
Constants
- LOCAL_PACKAGE_RESPONSE
- NOKOGIRI_HELP_MESSAGE
- OTHER_LIBRARY_VERSIONS
Keep track of what versions of what libraries we build against
- PACKAGE_ROOT_DIR
helpful constants
- RECOMMENDED_LIBXML_VERSION
- REQUIRED_LIBXML_VERSION
- REQUIRED_MINI_PORTILE_VERSION
The gem version constraint in the Rakefile is not respected at install time. Keep this version in sync with the one in the Rakefile !
- REQUIRED_PKG_CONFIG_VERSION
Public Instance Methods
Nokogiri(*args, &block)
click to toggle source
Parse a document contained in args
. Nokogiri will try to guess what type of document
you are attempting to parse. For more information, see Nokogiri.parse
To specify the type of document, use Nokogiri.XML or Nokogiri.HTML.
# File lib/nokogiri.rb, line 115 def Nokogiri(*args, &block) if block_given? Nokogiri::HTML::Builder.new(&block).doc.root else Nokogiri.parse(*args) end end
abort_could_not_find_library(lib)
click to toggle source
# File ext/nokogiri/extconf.rb, line 279 def abort_could_not_find_library(lib) abort("-----\n#{caller[0]}\n#{lib} is missing. Please locate mkmf.log to investigate how it is failing.\n-----") end
aix?()
click to toggle source
# File ext/nokogiri/extconf.rb, line 186 def aix? RbConfig::CONFIG["target_os"] =~ /aix/ end
chdir_for_build() { || ... }
click to toggle source
# File ext/nokogiri/extconf.rb, line 283 def chdir_for_build # When using rake-compiler-dock on Windows, the underlying Virtualbox shared # folders don't support symlinks, but libiconv expects it for a build on # Linux. We work around this limitation by using the temp dir for cooking. build_dir = ENV['RCD_HOST_RUBY_PLATFORM'].to_s =~ /mingw|mswin|cygwin/ ? '/tmp' : '.' Dir.chdir(build_dir) do yield end end
concat_flags(*args)
click to toggle source
# File ext/nokogiri/extconf.rb, line 198 def concat_flags(*args) args.compact.join(" ") end
config_clean?()
click to toggle source
utility functions
# File ext/nokogiri/extconf.rb, line 151 def config_clean? enable_config('clean', true) end
config_cross_build?()
click to toggle source
# File ext/nokogiri/extconf.rb, line 160 def config_cross_build? enable_config("cross-build") end
config_static?()
click to toggle source
# File ext/nokogiri/extconf.rb, line 155 def config_static? default_static = !truffle? enable_config("static", default_static) end
config_system_libraries?()
click to toggle source
# File ext/nokogiri/extconf.rb, line 164 def config_system_libraries? enable_config("system-libraries", ENV.key?("NOKOGIRI_USE_SYSTEM_LIBRARIES")) do |_, default| arg_config('--use-system-libraries', default) end end
copy_packaged_libraries_headers(to_path:, from_recipes:)
click to toggle source
# File ext/nokogiri/extconf.rb, line 514 def copy_packaged_libraries_headers(to_path:, from_recipes:) FileUtils.rm_rf(to_path, secure: true) FileUtils.mkdir(to_path) from_recipes.each do |recipe| FileUtils.cp_r(Dir[File.join(recipe.path, 'include/*')], to_path) end end
darwin?()
click to toggle source
# File ext/nokogiri/extconf.rb, line 178 def darwin? RbConfig::CONFIG['target_os'] =~ /darwin/ end
do_clean()
click to toggle source
# File ext/nokogiri/extconf.rb, line 527 def do_clean root = Pathname(PACKAGE_ROOT_DIR) pwd = Pathname(Dir.pwd) # Skip if this is a development work tree unless (root + '.git').exist? message("Cleaning files only used during build.\n") # (root + 'tmp') cannot be removed at this stage because # nokogiri.so is yet to be copied to lib. # clean the ports build directory Pathname.glob(pwd.join('tmp', '*', 'ports')) do |dir| FileUtils.rm_rf(dir, verbose: true) end if config_static? # ports installation can be safely removed if statically linked. FileUtils.rm_rf(root + 'ports', verbose: true) else FileUtils.rm_rf(root + 'ports' + 'archives', verbose: true) end end exit!(0) end
do_help()
click to toggle source
# File ext/nokogiri/extconf.rb, line 522 def do_help print(NOKOGIRI_HELP_MESSAGE) exit!(0) end
ensure_func(func, headers = nil)
click to toggle source
# File ext/nokogiri/extconf.rb, line 268 def ensure_func(func, headers = nil) have_func(func, headers) || abort_could_not_find_library(func) end
ensure_package_configuration(opt: nil, pc: nil, lib:, func:, headers:)
click to toggle source
# File ext/nokogiri/extconf.rb, line 263 def ensure_package_configuration(opt: nil, pc: nil, lib:, func:, headers:) have_package_configuration(opt: opt, pc: pc, lib: lib, func: func, headers: headers) || abort_could_not_find_library(lib) end
have_libxml_headers?(version = nil)
click to toggle source
# File ext/nokogiri/extconf.rb, line 322 def have_libxml_headers?(version = nil) source = if version.nil? <<~SRC #include <libxml/xmlversion.h> SRC else version_int = format("%d%2.2d%2.2d", *version.split(".")) <<~SRC #include <libxml/xmlversion.h> #if LIBXML_VERSION < #{version_int} # error libxml2 is older than #{version} #endif SRC end try_cpp(source) end
have_package_configuration(opt: nil, pc: nil, lib:, func:, headers:)
click to toggle source
set up mkmf to link against the library if we can find it
# File ext/nokogiri/extconf.rb, line 246 def have_package_configuration(opt: nil, pc: nil, lib:, func:, headers:) if opt dir_config(opt) dir_config("opt") end # see if we have enough path info to do this without trying any harder unless ENV.key?("NOKOGIRI_TEST_PKG_CONFIG") return true if local_have_library(lib, func, headers) end try_package_configuration(pc) if pc # verify that we can compile and link against the library local_have_library(lib, func, headers) end
iconv_configure_flags()
click to toggle source
# File ext/nokogiri/extconf.rb, line 361 def iconv_configure_flags # give --with-iconv-dir and --with-opt-dir first priority ["iconv", "opt"].each do |target| config = preserving_globals { dir_config(target) } next unless config.any? && try_link_iconv("--with-#{target}-* flags") { dir_config(target) } idirs, ldirs = config.map do |dirs| Array(dirs).flat_map do |dir| dir.split(File::PATH_SEPARATOR) end if dirs end return [ '--with-iconv=yes', *("CPPFLAGS=#{idirs.map { |dir| '-I' + dir }.join(' ')}" if idirs), *("LDFLAGS=#{ldirs.map { |dir| '-L' + dir }.join(' ')}" if ldirs), ] end if try_link_iconv return ['--with-iconv=yes'] end config = preserving_globals { have_package_configuration('libiconv') } if config && try_link_iconv('pkg-config libiconv') { have_package_configuration('libiconv') } cflags, ldflags, libs = config return [ '--with-iconv=yes', "CPPFLAGS=#{cflags}", "LDFLAGS=#{ldflags}", "LIBS=#{libs}", ] end abort_could_not_find_library("libiconv") end
libflag_to_filename(ldflag)
click to toggle source
# File ext/nokogiri/extconf.rb, line 315 def libflag_to_filename(ldflag) case ldflag when /\A-l(.+)/ "lib#{Regexp.last_match(1)}.#{$LIBEXT}" end end
local_have_library(lib, func = nil, headers = nil)
click to toggle source
# File ext/nokogiri/extconf.rb, line 202 def local_have_library(lib, func = nil, headers = nil) have_library(lib, func, headers) || have_library("lib#{lib}", func, headers) end
nix?()
click to toggle source
# File ext/nokogiri/extconf.rb, line 190 def nix? !(windows? || solaris? || darwin?) end
openbsd?()
click to toggle source
# File ext/nokogiri/extconf.rb, line 182 def openbsd? RbConfig::CONFIG['target_os'] =~ /openbsd/ end
preserving_globals() { || ... }
click to toggle source
# File ext/nokogiri/extconf.rb, line 272 def preserving_globals values = [$arg_config, $INCFLAGS, $CFLAGS, $CPPFLAGS, $LDFLAGS, $DLDFLAGS, $LIBPATH, $libs].map(&:dup) yield ensure $arg_config, $INCFLAGS, $CFLAGS, $CPPFLAGS, $LDFLAGS, $DLDFLAGS, $LIBPATH, $libs = values end
process_recipe(name, version, static_p, cross_p) { |recipe| ... }
click to toggle source
# File ext/nokogiri/extconf.rb, line 398 def process_recipe(name, version, static_p, cross_p) require 'rubygems' gem('mini_portile2', REQUIRED_MINI_PORTILE_VERSION) require 'mini_portile2' message("Using mini_portile version #{MiniPortile::VERSION}\n") if name != "libxml2" && name != "libxslt" OTHER_LIBRARY_VERSIONS[name] = version end MiniPortile.new(name, version).tap do |recipe| recipe.target = File.join(PACKAGE_ROOT_DIR, "ports") # Prefer host_alias over host in order to use i586-mingw32msvc as # 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.patch_files = Dir[File.join(PACKAGE_ROOT_DIR, "patches", name, "*.patch")].sort recipe.configure_options << "--libdir=#{File.join(recipe.path, 'lib')}" yield recipe env = Hash.new do |hash, key| hash[key] = (ENV[key]).to_s end recipe.configure_options.flatten! recipe.configure_options.delete_if do |option| case option when /\A(\w+)=(.*)\z/ env[Regexp.last_match(1)] = if env.key?(Regexp.last_match(1)) concat_flags(env[Regexp.last_match(1)], Regexp.last_match(2)) else Regexp.last_match(2) end true else false end end if static_p recipe.configure_options += [ "--disable-shared", "--enable-static", ] env["CFLAGS"] = concat_flags(env["CFLAGS"], "-fPIC") else recipe.configure_options += [ "--enable-shared", "--disable-static", ] end if cross_p recipe.configure_options += [ "--target=#{recipe.host}", "--host=#{recipe.host}", ] end if RbConfig::CONFIG['target_cpu'] == 'universal' %w[CFLAGS LDFLAGS].each do |key| unless env[key].include?('-arch') env[key] = concat_flags(env[key], RbConfig::CONFIG['ARCH_FLAG']) end end end recipe.configure_options += env.map do |key, value| "#{key}=#{value.strip}" end checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed" if File.exist?(checkpoint) message("Building Nokogiri with a packaged version of #{name}-#{version}.\n") else message(<<~EOM) ---------- IMPORTANT NOTICE ---------- Building Nokogiri with a packaged version of #{name}-#{version}. Configuration options: #{recipe.configure_options.shelljoin} EOM unless recipe.patch_files.empty? message("The following patches are being applied:\n") recipe.patch_files.each do |patch| message(" - %s\n" % File.basename(patch)) end end message(<<~EOM) The Nokogiri maintainers intend to provide timely security updates, but if this is a concern for you and want to use your OS/distro system library instead, then abort this installation process and install nokogiri as instructed at: https://nokogiri.org/tutorials/installing_nokogiri.html#installing-using-standard-system-libraries EOM message(<<~EOM) if name == 'libxml2' Note, however, that nokogiri cannot guarantee compatiblity with every version of libxml2 that may be provided by OS/package vendors. EOM chdir_for_build do recipe.cook end FileUtils.touch(checkpoint) end recipe.activate end end
sh_export_path(path)
click to toggle source
# File ext/nokogiri/extconf.rb, line 293 def sh_export_path(path) # because libxslt 1.1.29 configure.in uses AC_PATH_TOOL which treats ":" # as a $PATH separator, we need to convert windows paths from # # C:/path/to/foo # # to # # /C/path/to/foo # # which is sh-compatible, in order to find things properly during # configuration return path unless windows? match = Regexp.new("^([A-Z]):(/.*)").match(path) if match && match.length == 3 return File.join("/", match[1], match[2]) end path end
solaris?()
click to toggle source
# File ext/nokogiri/extconf.rb, line 174 def solaris? RbConfig::CONFIG['target_os'] =~ /solaris/ end
truffle?()
click to toggle source
# File ext/nokogiri/extconf.rb, line 194 def truffle? ::RUBY_ENGINE == 'truffleruby' end
try_link_iconv(using = nil) { || ... }
click to toggle source
# File ext/nokogiri/extconf.rb, line 340 def try_link_iconv(using = nil) checking_for(using ? "iconv using #{using}" : 'iconv') do ['', '-liconv'].any? do |opt| preserving_globals do yield if block_given? try_link(<<~'SRC', opt) #include <stdlib.h> #include <iconv.h> int main(void) { iconv_t cd = iconv_open("", ""); iconv(cd, NULL, NULL, NULL, NULL); return EXIT_SUCCESS; } SRC end end end end
try_package_configuration(pc)
click to toggle source
wrapper around MakeMakefil#pkg_config and the PKGConfig gem
# File ext/nokogiri/extconf.rb, line 212 def try_package_configuration(pc) unless ENV.key?("NOKOGIRI_TEST_PKG_CONFIG_GEM") # try MakeMakefile#pkg_config, which uses the system utility `pkg-config`. return if checking_for("#{pc} using `pkg_config`", LOCAL_PACKAGE_RESPONSE) do pkg_config(pc) end end # `pkg-config` probably isn't installed, which appears to be the case for lots of freebsd systems. # let's fall back to the pkg-config gem, which knows how to parse .pc files, and wrap it with the # same logic as MakeMakefile#pkg_config begin require 'rubygems' gem('pkg-config', REQUIRED_PKG_CONFIG_VERSION) require 'pkg-config' checking_for("#{pc} using pkg-config gem version #{PKGConfig::VERSION}", LOCAL_PACKAGE_RESPONSE) do if PKGConfig.have_package(pc) cflags = PKGConfig.cflags(pc) ldflags = PKGConfig.libs_only_L(pc) libs = PKGConfig.libs_only_l(pc) Logging.message("pkg-config gem found package configuration for %s\n", pc) Logging.message("cflags: %s\nldflags: %s\nlibs: %s\n\n", cflags, ldflags, libs) [cflags, ldflags, libs] end end rescue LoadError message("Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n") end end
windows?()
click to toggle source
# File ext/nokogiri/extconf.rb, line 170 def windows? RbConfig::CONFIG['target_os'] =~ /mingw32|mswin/ end