nokogiri 1.10.10-java → 1.11.0-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/LICENSE-DEPENDENCIES.md +1015 -947
  4. data/README.md +165 -91
  5. data/ext/java/nokogiri/HtmlDocument.java +34 -46
  6. data/ext/java/nokogiri/HtmlSaxParserContext.java +88 -58
  7. data/ext/java/nokogiri/HtmlSaxPushParser.java +1 -1
  8. data/ext/java/nokogiri/NokogiriService.java +1 -1
  9. data/ext/java/nokogiri/XmlAttr.java +13 -20
  10. data/ext/java/nokogiri/XmlAttributeDecl.java +11 -12
  11. data/ext/java/nokogiri/XmlCdata.java +3 -4
  12. data/ext/java/nokogiri/XmlComment.java +1 -1
  13. data/ext/java/nokogiri/XmlDocument.java +148 -175
  14. data/ext/java/nokogiri/XmlDocumentFragment.java +13 -31
  15. data/ext/java/nokogiri/XmlDtd.java +5 -8
  16. data/ext/java/nokogiri/XmlElement.java +1 -20
  17. data/ext/java/nokogiri/XmlElementDecl.java +23 -28
  18. data/ext/java/nokogiri/XmlEntityDecl.java +23 -27
  19. data/ext/java/nokogiri/XmlEntityReference.java +2 -2
  20. data/ext/java/nokogiri/XmlNamespace.java +72 -89
  21. data/ext/java/nokogiri/XmlNode.java +303 -406
  22. data/ext/java/nokogiri/XmlNodeSet.java +70 -76
  23. data/ext/java/nokogiri/XmlReader.java +12 -13
  24. data/ext/java/nokogiri/XmlRelaxng.java +10 -3
  25. data/ext/java/nokogiri/XmlSaxParserContext.java +15 -10
  26. data/ext/java/nokogiri/XmlSchema.java +87 -27
  27. data/ext/java/nokogiri/XmlSyntaxError.java +2 -6
  28. data/ext/java/nokogiri/XmlText.java +12 -9
  29. data/ext/java/nokogiri/XmlXpathContext.java +55 -25
  30. data/ext/java/nokogiri/XsltStylesheet.java +7 -15
  31. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +52 -46
  32. data/ext/java/nokogiri/internals/NokogiriHandler.java +1 -1
  33. data/ext/java/nokogiri/internals/NokogiriHelpers.java +71 -135
  34. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +90 -58
  35. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +9 -2
  36. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +67 -10
  37. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +4 -2
  38. data/ext/java/nokogiri/internals/ParserContext.java +27 -73
  39. data/ext/java/nokogiri/internals/ReaderNode.java +2 -4
  40. data/ext/java/nokogiri/internals/XmlDomParserContext.java +18 -33
  41. data/ext/nokogiri/depend +476 -357
  42. data/ext/nokogiri/extconf.rb +507 -357
  43. data/ext/nokogiri/html_document.c +79 -78
  44. data/ext/nokogiri/html_sax_parser_context.c +2 -2
  45. data/ext/nokogiri/nokogiri.c +34 -40
  46. data/ext/nokogiri/xml_document.c +18 -4
  47. data/ext/nokogiri/xml_io.c +8 -6
  48. data/ext/nokogiri/xml_node.c +21 -1
  49. data/ext/nokogiri/xml_node_set.c +1 -1
  50. data/ext/nokogiri/xml_reader.c +6 -17
  51. data/ext/nokogiri/xml_relax_ng.c +29 -11
  52. data/ext/nokogiri/xml_sax_parser.c +2 -7
  53. data/ext/nokogiri/xml_sax_parser_context.c +2 -2
  54. data/ext/nokogiri/xml_schema.c +55 -13
  55. data/ext/nokogiri/xml_xpath_context.c +80 -4
  56. data/ext/nokogiri/xslt_stylesheet.c +1 -8
  57. data/lib/nokogiri.rb +22 -22
  58. data/lib/nokogiri/css.rb +1 -0
  59. data/lib/nokogiri/css/node.rb +1 -0
  60. data/lib/nokogiri/css/parser.rb +63 -62
  61. data/lib/nokogiri/css/parser.y +2 -2
  62. data/lib/nokogiri/css/parser_extras.rb +39 -36
  63. data/lib/nokogiri/css/syntax_error.rb +1 -0
  64. data/lib/nokogiri/css/tokenizer.rb +1 -0
  65. data/lib/nokogiri/css/xpath_visitor.rb +73 -43
  66. data/lib/nokogiri/decorators/slop.rb +1 -0
  67. data/lib/nokogiri/html.rb +1 -0
  68. data/lib/nokogiri/html/builder.rb +1 -0
  69. data/lib/nokogiri/html/document.rb +13 -26
  70. data/lib/nokogiri/html/document_fragment.rb +1 -0
  71. data/lib/nokogiri/html/element_description.rb +1 -0
  72. data/lib/nokogiri/html/element_description_defaults.rb +1 -0
  73. data/lib/nokogiri/html/entity_lookup.rb +1 -0
  74. data/lib/nokogiri/html/sax/parser.rb +1 -0
  75. data/lib/nokogiri/html/sax/parser_context.rb +1 -0
  76. data/lib/nokogiri/html/sax/push_parser.rb +1 -0
  77. data/lib/nokogiri/jruby/dependencies.rb +20 -0
  78. data/lib/nokogiri/nokogiri.jar +0 -0
  79. data/lib/nokogiri/syntax_error.rb +1 -0
  80. data/lib/nokogiri/version.rb +3 -109
  81. data/lib/nokogiri/version/constant.rb +5 -0
  82. data/lib/nokogiri/version/info.rb +182 -0
  83. data/lib/nokogiri/xml.rb +1 -0
  84. data/lib/nokogiri/xml/attr.rb +1 -0
  85. data/lib/nokogiri/xml/attribute_decl.rb +1 -0
  86. data/lib/nokogiri/xml/builder.rb +3 -2
  87. data/lib/nokogiri/xml/cdata.rb +1 -0
  88. data/lib/nokogiri/xml/character_data.rb +1 -0
  89. data/lib/nokogiri/xml/document.rb +20 -15
  90. data/lib/nokogiri/xml/document_fragment.rb +5 -6
  91. data/lib/nokogiri/xml/dtd.rb +1 -0
  92. data/lib/nokogiri/xml/element_content.rb +1 -0
  93. data/lib/nokogiri/xml/element_decl.rb +1 -0
  94. data/lib/nokogiri/xml/entity_decl.rb +1 -0
  95. data/lib/nokogiri/xml/entity_reference.rb +1 -0
  96. data/lib/nokogiri/xml/namespace.rb +1 -0
  97. data/lib/nokogiri/xml/node.rb +587 -249
  98. data/lib/nokogiri/xml/node/save_options.rb +1 -0
  99. data/lib/nokogiri/xml/node_set.rb +1 -0
  100. data/lib/nokogiri/xml/notation.rb +1 -0
  101. data/lib/nokogiri/xml/parse_options.rb +10 -3
  102. data/lib/nokogiri/xml/pp.rb +1 -0
  103. data/lib/nokogiri/xml/pp/character_data.rb +1 -0
  104. data/lib/nokogiri/xml/pp/node.rb +1 -0
  105. data/lib/nokogiri/xml/processing_instruction.rb +1 -0
  106. data/lib/nokogiri/xml/reader.rb +7 -3
  107. data/lib/nokogiri/xml/relax_ng.rb +7 -2
  108. data/lib/nokogiri/xml/sax.rb +1 -0
  109. data/lib/nokogiri/xml/sax/document.rb +1 -0
  110. data/lib/nokogiri/xml/sax/parser.rb +1 -0
  111. data/lib/nokogiri/xml/sax/parser_context.rb +1 -0
  112. data/lib/nokogiri/xml/sax/push_parser.rb +1 -0
  113. data/lib/nokogiri/xml/schema.rb +13 -4
  114. data/lib/nokogiri/xml/searchable.rb +25 -16
  115. data/lib/nokogiri/xml/syntax_error.rb +1 -0
  116. data/lib/nokogiri/xml/text.rb +1 -0
  117. data/lib/nokogiri/xml/xpath.rb +1 -0
  118. data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -0
  119. data/lib/nokogiri/xml/xpath_context.rb +1 -0
  120. data/lib/nokogiri/xslt.rb +1 -0
  121. data/lib/nokogiri/xslt/stylesheet.rb +1 -0
  122. data/lib/xsd/xmlparser/nokogiri.rb +1 -0
  123. metadata +86 -159
  124. data/ext/java/nokogiri/internals/NokogiriEncodingReaderWrapper.java +0 -107
  125. data/ext/java/nokogiri/internals/UncloseableInputStream.java +0 -102
  126. data/ext/nokogiri/html_document.h +0 -10
  127. data/ext/nokogiri/html_element_description.h +0 -10
  128. data/ext/nokogiri/html_entity_lookup.h +0 -8
  129. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  130. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  131. data/ext/nokogiri/nokogiri.h +0 -121
  132. data/ext/nokogiri/xml_attr.h +0 -9
  133. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  134. data/ext/nokogiri/xml_cdata.h +0 -9
  135. data/ext/nokogiri/xml_comment.h +0 -9
  136. data/ext/nokogiri/xml_document.h +0 -23
  137. data/ext/nokogiri/xml_document_fragment.h +0 -10
  138. data/ext/nokogiri/xml_dtd.h +0 -10
  139. data/ext/nokogiri/xml_element_content.h +0 -10
  140. data/ext/nokogiri/xml_element_decl.h +0 -9
  141. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  142. data/ext/nokogiri/xml_entity_decl.h +0 -10
  143. data/ext/nokogiri/xml_entity_reference.h +0 -9
  144. data/ext/nokogiri/xml_io.h +0 -11
  145. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  146. data/ext/nokogiri/xml_namespace.h +0 -14
  147. data/ext/nokogiri/xml_node.h +0 -13
  148. data/ext/nokogiri/xml_node_set.h +0 -12
  149. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  150. data/ext/nokogiri/xml_reader.h +0 -10
  151. data/ext/nokogiri/xml_relax_ng.h +0 -9
  152. data/ext/nokogiri/xml_sax_parser.h +0 -39
  153. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  154. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  155. data/ext/nokogiri/xml_schema.h +0 -9
  156. data/ext/nokogiri/xml_syntax_error.h +0 -13
  157. data/ext/nokogiri/xml_text.h +0 -9
  158. data/ext/nokogiri/xml_xpath_context.h +0 -10
  159. data/ext/nokogiri/xslt_stylesheet.h +0 -14
@@ -1,12 +1,115 @@
1
1
  # :stopdoc:
2
2
  ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
3
3
 
4
- require 'mkmf'
4
+ require "mkmf"
5
+ require "rbconfig"
6
+ require "fileutils"
7
+ require "shellwords"
8
+ require "pathname"
5
9
 
6
- ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
10
+ #
11
+ # helpful constants
12
+ #
13
+ PACKAGE_ROOT_DIR = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
14
+ REQUIRED_LIBXML_VERSION = "2.6.21"
15
+ RECOMMENDED_LIBXML_VERSION = "2.9.3"
16
+
17
+ # The gem version constraint in the Rakefile is not respected at install time.
18
+ # Keep this version in sync with the one in the Rakefile !
19
+ REQUIRED_MINI_PORTILE_VERSION = "~> 2.5.0"
20
+ REQUIRED_PKG_CONFIG_VERSION = "~> 1.1"
21
+
22
+ # Keep track of what versions of what libraries we build against
23
+ OTHER_LIBRARY_VERSIONS = {}
24
+
25
+ NOKOGIRI_HELP_MESSAGE = <<~HELP
26
+ USAGE: ruby #{$0} [options]
27
+
28
+ Flags that are always valid:
29
+
30
+ --use-system-libraries
31
+ Use system libraries instead of building and using the packaged libraries
32
+
33
+ --disable-clean
34
+ Do not clean out intermediate files after successful build
35
+
36
+ --prevent-strip
37
+ Take steps to prevent stripping the symbol table and debugging info from the shared
38
+ library, potentially overriding RbConfig's CFLAGS/LDFLAGS/DLDFLAGS.
39
+
40
+
41
+ Flags only used when using system libraries:
42
+
43
+ --with-opt-dir=DIRECTORY
44
+ Look for headers and libraries in DIRECTORY
45
+
46
+ --with-zlib-dir=DIR
47
+ Look for zlib header and library in DIRECTORY
48
+
49
+ --with-iconv-dir=DIRECTORY
50
+ Look for iconv header and library in DIRECTORY
51
+
52
+ --with-xml2-dir=DIRECTORY
53
+ Look for xml2 headers and library in DIRECTORY
54
+
55
+ --with-xml2-lib=DIRECTORY
56
+ Look for xml2 library in DIRECTORY
57
+
58
+ --with-xslt-include=DIRECTORY
59
+ Look for xslt headers in DIRECTORY
60
+
61
+ --with-xslt-dir=DIRECTORY
62
+ Look for xslt headers and library in DIRECTORY
63
+
64
+ --with-xslt-lib=DIRECTORY
65
+ Look for xslt library in DIRECTORY
66
+
67
+ --with-xslt-include=DIRECTORY
68
+ Look for xslt headers in DIRECTORY
69
+
70
+ --with-exslt-dir=DIRECTORY
71
+ Look for exslt headers and library in DIRECTORY
72
+
73
+ --with-exslt-lib=DIRECTORY
74
+ Look for exslt library in DIRECTORY
75
+
76
+ --with-exslt-include=DIRECTORY
77
+ Look for exslt headers in DIRECTORY
78
+
79
+
80
+ Flags only used when building and using the packaged libraries:
81
+
82
+ --disable-static
83
+ Do not statically link packaged libraries, instead use shared libraries
84
+
85
+ --enable-cross-build
86
+ Enable cross-build mode. (You probably do not want to set this manually.)
87
+
88
+
89
+ Environment variables used:
90
+
91
+ NOKOGIRI_USE_SYSTEM_LIBRARIES
92
+ When set, even if nil or blank, use system libraries instead of building and using the
93
+ packaged libraries. Equivalent to `--use-system-libraries`.
94
+
95
+ CC
96
+ Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
97
+
98
+ CPPFLAGS
99
+ If this string is accepted by the C preprocessor, add it to the flags passed to the C preprocessor
100
+
101
+ CFLAGS
102
+ If this string is accepted by the compiler, add it to the flags passed to the compiler
103
+
104
+ LDFLAGS
105
+ If this string is accepted by the linker, add it to the flags passed to the linker
106
+
107
+ LIBS
108
+ Add this string to the flags passed to the linker
109
+ HELP
7
110
 
8
111
  #
9
- # functions
112
+ # utility functions
10
113
  #
11
114
  def windows?
12
115
  RbConfig::CONFIG['target_os'] =~ /mingw32|mswin/
@@ -24,185 +127,176 @@ def openbsd?
24
127
  RbConfig::CONFIG['target_os'] =~ /openbsd/
25
128
  end
26
129
 
130
+ def aix?
131
+ RbConfig::CONFIG["target_os"] =~ /aix/
132
+ end
133
+
27
134
  def nix?
28
135
  ! (windows? || solaris? || darwin?)
29
136
  end
30
137
 
31
- def sh_export_path path
32
- # because libxslt 1.1.29 configure.in uses AC_PATH_TOOL which treats ":"
33
- # as a $PATH separator, we need to convert windows paths from
34
- #
35
- # C:/path/to/foo
36
- #
37
- # to
38
- #
39
- # /C/path/to/foo
40
- #
41
- # which is sh-compatible, in order to find things properly during
42
- # configuration
43
- if windows?
44
- match = Regexp.new("^([A-Z]):(/.*)").match(path)
45
- if match && match.length == 3
46
- return File.join("/", match[1], match[2])
47
- end
48
- end
49
- path
138
+ def concat_flags *args
139
+ args.compact.join(" ")
50
140
  end
51
141
 
52
- def do_help
53
- print <<HELP
54
- usage: ruby #{$0} [options]
55
-
56
- --disable-clean
57
- Do not clean out intermediate files after successful build.
142
+ def local_have_library(lib, func=nil, headers=nil)
143
+ have_library(lib, func, headers) or have_library("lib#{lib}", func, headers)
144
+ end
58
145
 
59
- --disable-static
60
- Do not statically link bundled libraries.
146
+ LOCAL_PACKAGE_RESPONSE = Object.new
147
+ def LOCAL_PACKAGE_RESPONSE.%(package)
148
+ package ? "yes: #{package}" : "no"
149
+ end
61
150
 
62
- --with-iconv-dir=DIR
63
- Use the iconv library placed under DIR.
151
+ # wrapper around MakeMakefil#pkg_config and the PKGConfig gem
152
+ def try_package_configuration(pc)
153
+ if !ENV.key?("NOKOGIRI_TEST_PKG_CONFIG_GEM")
154
+ # try MakeMakefile#pkg_config, which uses the system utility `pkg-config`.
155
+ return if checking_for("#{pc} using `pkg_config`", LOCAL_PACKAGE_RESPONSE) do
156
+ pkg_config(pc)
157
+ end
158
+ end
64
159
 
65
- --with-zlib-dir=DIR
66
- Use the zlib library placed under DIR.
160
+ # `pkg-config` probably isn't installed, which appears to be the case for lots of freebsd systems.
161
+ # let's fall back to the pkg-config gem, which knows how to parse .pc files, and wrap it with the
162
+ # same logic as MakeMakefile#pkg_config
163
+ begin
164
+ require 'rubygems'
165
+ gem 'pkg-config', REQUIRED_PKG_CONFIG_VERSION
166
+ require 'pkg-config'
67
167
 
68
- --use-system-libraries
69
- Use system libraries instead of building and using the bundled
70
- libraries.
168
+ checking_for("#{pc} using pkg-config gem version #{PKGConfig::VERSION}", LOCAL_PACKAGE_RESPONSE) do
169
+ if PKGConfig.have_package(pc)
170
+ cflags = PKGConfig.cflags(pc)
171
+ ldflags = PKGConfig.libs_only_L(pc)
172
+ libs = PKGConfig.libs_only_l(pc)
71
173
 
72
- --with-xml2-dir=DIR / --with-xml2-config=CONFIG
73
- --with-xslt-dir=DIR / --with-xslt-config=CONFIG
74
- --with-exslt-dir=DIR / --with-exslt-config=CONFIG
75
- Use libxml2/libxslt/libexslt as specified.
174
+ Logging::message "pkg-config gem found package configuration for %s\n", pc
175
+ Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n", cflags, ldflags, libs
76
176
 
77
- --enable-cross-build
78
- Do cross-build.
79
- HELP
80
- exit! 0
177
+ [cflags, ldflags, libs]
178
+ end
179
+ end
180
+ rescue LoadError
181
+ message "Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n"
182
+ end
81
183
  end
82
184
 
83
- def do_clean
84
- require 'pathname'
85
- require 'fileutils'
185
+ # set up mkmf to link against the library if we can find it
186
+ def have_package_configuration(opt: nil, pc: nil, lib:, func:, headers:)
187
+ if opt
188
+ dir_config(opt)
189
+ dir_config("opt")
190
+ end
86
191
 
87
- root = Pathname(ROOT)
88
- pwd = Pathname(Dir.pwd)
192
+ # see if we have enough path info to do this without trying any harder
193
+ if !ENV.key?("NOKOGIRI_TEST_PKG_CONFIG")
194
+ return true if local_have_library(lib, func, headers)
195
+ end
89
196
 
90
- # Skip if this is a development work tree
91
- unless (root + '.git').exist?
92
- message "Cleaning files only used during build.\n"
197
+ try_package_configuration(pc) if pc
93
198
 
94
- # (root + 'tmp') cannot be removed at this stage because
95
- # nokogiri.so is yet to be copied to lib.
199
+ # verify that we can compile and link against the library
200
+ local_have_library(lib, func, headers)
201
+ end
96
202
 
97
- # clean the ports build directory
98
- Pathname.glob(pwd.join('tmp', '*', 'ports')) do |dir|
99
- FileUtils.rm_rf(dir, verbose: true)
100
- end
203
+ def ensure_package_configuration(opt: nil, pc: nil, lib:, func:, headers:)
204
+ have_package_configuration(opt: opt, pc: pc, lib: lib, func: func, headers: headers) or
205
+ abort_could_not_find_library(lib)
206
+ end
101
207
 
102
- if enable_config('static')
103
- # ports installation can be safely removed if statically linked.
104
- FileUtils.rm_rf(root + 'ports', verbose: true)
105
- else
106
- FileUtils.rm_rf(root + 'ports' + 'archives', verbose: true)
107
- end
108
- end
208
+ def ensure_func(func, headers=nil)
209
+ have_func(func, headers) or abort_could_not_find_library(lib)
210
+ end
109
211
 
110
- exit! 0
212
+ def preserving_globals
213
+ values = [$arg_config, $INCFLAGS, $CFLAGS, $CPPFLAGS, $LDFLAGS, $DLDFLAGS, $LIBPATH, $libs].map(&:dup)
214
+ yield
215
+ ensure
216
+ $arg_config, $INCFLAGS, $CFLAGS, $CPPFLAGS, $LDFLAGS, $DLDFLAGS, $LIBPATH, $libs = values
111
217
  end
112
218
 
113
- def package_config pkg, options={}
114
- package = pkg_config(pkg)
115
- return package if package
219
+ def abort_could_not_find_library(lib)
220
+ abort "-----\n#{caller[0]}\n#{lib} is missing. Please locate mkmf.log to investigate how it is failing.\n-----"
221
+ end
116
222
 
117
- begin
118
- require 'rubygems'
119
- gem 'pkg-config', (gem_ver='~> 1.1')
120
- require 'pkg-config' and message("Using pkg-config gem version #{PKGConfig::VERSION}\n")
121
- rescue LoadError
122
- message "pkg-config could not be used to find #{pkg}\nPlease install either `pkg-config` or the pkg-config gem per\n\n gem install pkg-config -v #{gem_ver.inspect}\n\n"
123
- else
124
- return nil unless PKGConfig.have_package(pkg)
223
+ def chdir_for_build
224
+ # When using rake-compiler-dock on Windows, the underlying Virtualbox shared
225
+ # folders don't support symlinks, but libiconv expects it for a build on
226
+ # Linux. We work around this limitation by using the temp dir for cooking.
227
+ build_dir = ENV['RCD_HOST_RUBY_PLATFORM'].to_s =~ /mingw|mswin|cygwin/ ? '/tmp' : '.'
228
+ Dir.chdir(build_dir) do
229
+ yield
230
+ end
231
+ end
232
+
233
+ def sh_export_path path
234
+ # because libxslt 1.1.29 configure.in uses AC_PATH_TOOL which treats ":"
235
+ # as a $PATH separator, we need to convert windows paths from
236
+ #
237
+ # C:/path/to/foo
238
+ #
239
+ # to
240
+ #
241
+ # /C/path/to/foo
242
+ #
243
+ # which is sh-compatible, in order to find things properly during
244
+ # configuration
245
+ return path if !windows?
125
246
 
126
- cflags = PKGConfig.cflags(pkg)
127
- ldflags = PKGConfig.libs_only_L(pkg)
128
- libs = PKGConfig.libs_only_l(pkg)
247
+ match = Regexp.new("^([A-Z]):(/.*)").match(path)
248
+ if match && match.length == 3
249
+ return File.join("/", match[1], match[2])
250
+ end
129
251
 
130
- Logging::message "PKGConfig package configuration for %s\n", pkg
131
- Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n", cflags, ldflags, libs
252
+ path
253
+ end
132
254
 
133
- [cflags, ldflags, libs]
255
+ def libflag_to_filename(ldflag)
256
+ case ldflag
257
+ when /\A-l(.+)/
258
+ "lib#{$1}.#{$LIBEXT}"
134
259
  end
135
260
  end
136
261
 
137
- def nokogiri_try_compile
138
- try_compile "int main() {return 0;}", "", {werror: true}
262
+ def using_system_libraries?
263
+ # NOTE: TruffleRuby uses this env var as it does not support using static libraries yet.
264
+ arg_config('--use-system-libraries', ENV.key?("NOKOGIRI_USE_SYSTEM_LIBRARIES"))
139
265
  end
140
266
 
141
- def check_libxml_version version=nil
267
+ def have_libxml_headers?(version=nil)
142
268
  source = if version.nil?
143
- <<-SRC
144
- #include <libxml/xmlversion.h>
269
+ <<~SRC
270
+ #include <libxml/xmlversion.h>
145
271
  SRC
146
272
  else
147
273
  version_int = sprintf "%d%2.2d%2.2d", *(version.split("."))
148
- <<-SRC
149
- #include <libxml/xmlversion.h>
150
- #if LIBXML_VERSION < #{version_int}
151
- #error libxml2 is older than #{version}
152
- #endif
274
+ <<~SRC
275
+ #include <libxml/xmlversion.h>
276
+ #if LIBXML_VERSION < #{version_int}
277
+ # error libxml2 is older than #{version}
278
+ #endif
153
279
  SRC
154
280
  end
155
281
 
156
282
  try_cpp source
157
283
  end
158
284
 
159
- def add_cflags(flags)
160
- print "checking if the C compiler accepts #{flags}... "
161
- with_cflags("#{$CFLAGS} #{flags}") do
162
- if nokogiri_try_compile
163
- puts 'yes'
164
- true
165
- else
166
- puts 'no'
167
- false
168
- end
169
- end
170
- end
171
-
172
- def preserving_globals
173
- values = [
174
- $arg_config,
175
- $CFLAGS, $CPPFLAGS,
176
- $LDFLAGS, $LIBPATH, $libs
177
- ].map(&:dup)
178
- yield
179
- ensure
180
- $arg_config,
181
- $CFLAGS, $CPPFLAGS,
182
- $LDFLAGS, $LIBPATH, $libs =
183
- values
184
- end
185
-
186
- def asplode(lib)
187
- abort "-----\n#{lib} is missing. Please locate mkmf.log to investigate how it is failing.\n-----"
188
- end
189
-
190
- def have_iconv?(using = nil)
285
+ def try_link_iconv(using = nil)
191
286
  checking_for(using ? "iconv using #{using}" : 'iconv') do
192
287
  ['', '-liconv'].any? do |opt|
193
288
  preserving_globals do
194
289
  yield if block_given?
195
290
 
196
- try_link(<<-'SRC', opt)
197
- #include <stdlib.h>
198
- #include <iconv.h>
199
-
200
- int main(void)
201
- {
202
- iconv_t cd = iconv_open("", "");
203
- iconv(cd, NULL, NULL, NULL, NULL);
204
- return EXIT_SUCCESS;
205
- }
291
+ try_link(<<~'SRC', opt)
292
+ #include <stdlib.h>
293
+ #include <iconv.h>
294
+ int main(void)
295
+ {
296
+ iconv_t cd = iconv_open("", "");
297
+ iconv(cd, NULL, NULL, NULL, NULL);
298
+ return EXIT_SUCCESS;
299
+ }
206
300
  SRC
207
301
  end
208
302
  end
@@ -210,11 +304,10 @@ int main(void)
210
304
  end
211
305
 
212
306
  def iconv_configure_flags
213
- # If --with-iconv-dir or --with-opt-dir is given, it should be
214
- # the first priority
215
- %w[iconv opt].each do |name|
216
- if (config = preserving_globals { dir_config(name) }).any? &&
217
- have_iconv?("--with-#{name}-* flags") { dir_config(name) }
307
+ # give --with-iconv-dir and --with-opt-dir first priority
308
+ ["iconv", "opt"].each do |target|
309
+ config = preserving_globals { dir_config(target) }
310
+ if config.any? && try_link_iconv("--with-#{target}-* flags") { dir_config(target) }
218
311
  idirs, ldirs = config.map do |dirs|
219
312
  Array(dirs).flat_map do |dir|
220
313
  dir.split(File::PATH_SEPARATOR)
@@ -229,12 +322,12 @@ def iconv_configure_flags
229
322
  end
230
323
  end
231
324
 
232
- if have_iconv?
325
+ if try_link_iconv
233
326
  return ['--with-iconv=yes']
234
327
  end
235
328
 
236
- if (config = preserving_globals { package_config('libiconv') }) &&
237
- have_iconv?('pkg-config libiconv') { package_config('libiconv') }
329
+ config = preserving_globals { have_package_configuration('libiconv') }
330
+ if config && try_link_iconv('pkg-config libiconv') { have_package_configuration('libiconv') }
238
331
  cflags, ldflags, libs = config
239
332
 
240
333
  return [
@@ -245,26 +338,25 @@ def iconv_configure_flags
245
338
  ]
246
339
  end
247
340
 
248
- asplode "libiconv"
341
+ abort_could_not_find_library "libiconv"
249
342
  end
250
343
 
251
- # When using rake-compiler-dock on Windows, the underlying Virtualbox shared
252
- # folders don't support symlinks, but libiconv expects it for a build on
253
- # Linux. We work around this limitation by using the temp dir for cooking.
254
- def chdir_for_build
255
- build_dir = ENV['RCD_HOST_RUBY_PLATFORM'].to_s =~ /mingw|mswin|cygwin/ ? '/tmp' : '.'
256
- Dir.chdir(build_dir) do
257
- yield
344
+ def process_recipe(name, version, static_p, cross_p)
345
+ require 'rubygems'
346
+ gem 'mini_portile2', REQUIRED_MINI_PORTILE_VERSION
347
+ require 'mini_portile2'
348
+ message "Using mini_portile version #{MiniPortile::VERSION}\n"
349
+
350
+ if name != "libxml2" && name != "libxslt"
351
+ OTHER_LIBRARY_VERSIONS[name] = version
258
352
  end
259
- end
260
353
 
261
- def process_recipe(name, version, static_p, cross_p)
262
354
  MiniPortile.new(name, version).tap do |recipe|
263
- recipe.target = File.join(ROOT, "ports")
355
+ recipe.target = File.join(PACKAGE_ROOT_DIR, "ports")
264
356
  # Prefer host_alias over host in order to use i586-mingw32msvc as
265
357
  # correct compiler prefix for cross build, but use host if not set.
266
358
  recipe.host = RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"]
267
- recipe.patch_files = Dir[File.join(ROOT, "patches", name, "*.patch")].sort
359
+ recipe.patch_files = Dir[File.join(PACKAGE_ROOT_DIR, "patches", name, "*.patch")].sort
268
360
  recipe.configure_options << "--libdir=#{File.join(recipe.path, "lib")}"
269
361
 
270
362
  yield recipe
@@ -278,7 +370,11 @@ def process_recipe(name, version, static_p, cross_p)
278
370
  recipe.configure_options.delete_if do |option|
279
371
  case option
280
372
  when /\A(\w+)=(.*)\z/
281
- env[$1] = $2
373
+ if env.key?($1)
374
+ env[$1] = concat_flags(env[$1], $2)
375
+ else
376
+ env[$1] = $2
377
+ end
282
378
  true
283
379
  else
284
380
  false
@@ -290,7 +386,7 @@ def process_recipe(name, version, static_p, cross_p)
290
386
  "--disable-shared",
291
387
  "--enable-static",
292
388
  ]
293
- env['CFLAGS'] = "-fPIC #{env['CFLAGS']}"
389
+ env["CFLAGS"] = concat_flags(env["CFLAGS"], "-fPIC")
294
390
  else
295
391
  recipe.configure_options += [
296
392
  "--enable-shared",
@@ -308,59 +404,50 @@ def process_recipe(name, version, static_p, cross_p)
308
404
  if RbConfig::CONFIG['target_cpu'] == 'universal'
309
405
  %w[CFLAGS LDFLAGS].each do |key|
310
406
  unless env[key].include?('-arch')
311
- env[key] += ' ' + RbConfig::CONFIG['ARCH_FLAG']
407
+ env[key] = concat_flags(env[key], RbConfig::CONFIG['ARCH_FLAG'])
312
408
  end
313
409
  end
314
410
  end
315
411
 
316
412
  recipe.configure_options += env.map do |key, value|
317
- "#{key}=#{value}"
413
+ "#{key}=#{value.strip}"
318
414
  end
319
415
 
320
- message <<-"EOS"
321
- ************************************************************************
322
- IMPORTANT NOTICE:
323
-
324
- Building Nokogiri with a packaged version of #{name}-#{version}#{'.' if recipe.patch_files.empty?}
325
- EOS
416
+ checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
417
+ if File.exist?(checkpoint)
418
+ message "Building Nokogiri with a packaged version of #{name}-#{version}.\n"
419
+ else
420
+ message <<~EOM
421
+ ---------- IMPORTANT NOTICE ----------
422
+ Building Nokogiri with a packaged version of #{name}-#{version}.
423
+ Configuration options: #{recipe.configure_options.shelljoin}
424
+ EOM
326
425
 
327
- unless recipe.patch_files.empty?
328
- message "with the following patches applied:\n"
426
+ unless recipe.patch_files.empty?
427
+ message "The following patches are being applied:\n"
329
428
 
330
- recipe.patch_files.each do |patch|
331
- message "\t- %s\n" % File.basename(patch)
429
+ recipe.patch_files.each do |patch|
430
+ message " - %s\n" % File.basename(patch)
431
+ end
332
432
  end
333
- end
334
-
335
- message <<-"EOS"
336
-
337
- Team Nokogiri will keep on doing their best to provide security
338
- updates in a timely manner, but if this is a concern for you and want
339
- to use the system library instead; abort this installation process and
340
- reinstall nokogiri as follows:
341
433
 
342
- gem install nokogiri -- --use-system-libraries
343
- [--with-xml2-config=/path/to/xml2-config]
344
- [--with-xslt-config=/path/to/xslt-config]
434
+ message <<~EOM
345
435
 
346
- If you are using Bundler, tell it to use the option:
436
+ The Nokogiri maintainers intend to provide timely security updates, but if
437
+ this is a concern for you and want to use your OS/distro system library
438
+ instead, then abort this installation process and install nokogiri as
439
+ instructed at:
347
440
 
348
- bundle config build.nokogiri --use-system-libraries
349
- bundle install
350
- EOS
441
+ https://nokogiri.org/tutorials/installing_nokogiri.html#install-with-system-libraries
351
442
 
352
- message <<-"EOS" if name == 'libxml2'
443
+ EOM
353
444
 
354
- Note, however, that nokogiri is not fully compatible with arbitrary
355
- versions of libxml2 provided by OS/package vendors.
356
- EOS
445
+ message <<~EOM if name == 'libxml2'
446
+ Note, however, that nokogiri cannot guarantee compatiblity with every
447
+ version of libxml2 that may be provided by OS/package vendors.
357
448
 
358
- message <<-"EOS"
359
- ************************************************************************
360
- EOS
449
+ EOM
361
450
 
362
- checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
363
- unless File.exist?(checkpoint)
364
451
  chdir_for_build do
365
452
  recipe.cook
366
453
  end
@@ -370,188 +457,220 @@ versions of libxml2 provided by OS/package vendors.
370
457
  end
371
458
  end
372
459
 
373
- def lib_a(ldflag)
374
- case ldflag
375
- when /\A-l(.+)/
376
- "lib#{$1}.#{$LIBEXT}"
460
+ def copy_packaged_libraries_headers(to_path:, from_recipes:)
461
+ FileUtils.rm_rf(to_path, secure: true)
462
+ FileUtils.mkdir(to_path)
463
+ from_recipes.each do |recipe|
464
+ FileUtils.cp_r(Dir[File.join(recipe.path, 'include/*')], to_path)
377
465
  end
378
466
  end
379
467
 
380
- def using_system_libraries?
381
- arg_config('--use-system-libraries', !!ENV['NOKOGIRI_USE_SYSTEM_LIBRARIES'])
468
+ def do_help
469
+ print NOKOGIRI_HELP_MESSAGE
470
+ exit! 0
382
471
  end
383
472
 
384
- #
385
- # main
386
- #
473
+ def do_clean
474
+ root = Pathname(PACKAGE_ROOT_DIR)
475
+ pwd = Pathname(Dir.pwd)
387
476
 
388
- case
389
- when arg_config('--help')
390
- do_help
391
- when arg_config('--clean')
392
- do_clean
393
- end
477
+ # Skip if this is a development work tree
478
+ unless (root + '.git').exist?
479
+ message "Cleaning files only used during build.\n"
480
+
481
+ # (root + 'tmp') cannot be removed at this stage because
482
+ # nokogiri.so is yet to be copied to lib.
483
+
484
+ # clean the ports build directory
485
+ Pathname.glob(pwd.join('tmp', '*', 'ports')) do |dir|
486
+ FileUtils.rm_rf(dir, verbose: true)
487
+ end
488
+
489
+ if enable_config('static')
490
+ # ports installation can be safely removed if statically linked.
491
+ FileUtils.rm_rf(root + 'ports', verbose: true)
492
+ else
493
+ FileUtils.rm_rf(root + 'ports' + 'archives', verbose: true)
494
+ end
495
+ end
394
496
 
395
- if darwin?
396
- ENV['CFLAGS'] = "#{ENV['CFLAGS']} -I /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libxml2"
497
+ exit! 0
397
498
  end
398
499
 
500
+ #
501
+ # main
502
+ #
503
+ do_help if arg_config('--help')
504
+ do_clean if arg_config('--clean')
505
+
399
506
  if openbsd? && !using_system_libraries?
400
507
  if `#{ENV['CC'] || '/usr/bin/cc'} -v 2>&1` !~ /clang/
401
508
  ENV['CC'] ||= find_executable('egcc') or
402
509
  abort "Please install gcc 4.9+ from ports using `pkg_add -v gcc`"
403
510
  end
404
- ENV['CFLAGS'] = "#{ENV['CFLAGS']} -I /usr/local/include"
511
+ append_cppflags "-I/usr/local/include"
405
512
  end
406
513
 
407
514
  if ENV['CC']
408
515
  RbConfig::CONFIG['CC'] = RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC']
409
516
  end
517
+
410
518
  # use same c compiler for libxml and libxslt
411
519
  ENV['CC'] = RbConfig::CONFIG['CC']
412
520
 
413
- $LIBS << " #{ENV["LIBS"]}"
414
-
415
- # Read CFLAGS from ENV and make sure compiling works.
416
- add_cflags(ENV["CFLAGS"])
417
-
418
- if windows?
419
- $CFLAGS << " -DXP_WIN -DXP_WIN32 -DUSE_INCLUDED_VASPRINTF"
420
- end
421
-
422
- if solaris?
423
- $CFLAGS << " -DUSE_INCLUDED_VASPRINTF"
424
- end
425
-
426
- if darwin?
427
- # Let Apple LLVM/clang 5.1 ignore unknown compiler flags
428
- add_cflags("-Wno-error=unused-command-line-argument-hard-error-in-future")
429
- end
430
-
431
- if nix?
432
- $CFLAGS << " -g -DXP_UNIX"
433
- end
434
-
435
- if RUBY_PLATFORM =~ /mingw/i
436
- # Work around a character escaping bug in MSYS by passing an arbitrary
437
- # double quoted parameter to gcc. See https://sourceforge.net/p/mingw/bugs/2142
438
- $CPPFLAGS << ' "-Idummypath"'
439
- end
440
-
441
- if RbConfig::CONFIG['CC'] =~ /gcc/
442
- $CFLAGS << " -O3" unless $CFLAGS[/-O\d/]
443
- $CFLAGS << " -Wall -Wcast-qual -Wwrite-strings -Wmissing-noreturn -Winline"
444
- end
445
-
446
- case
447
- when using_system_libraries?
521
+ if arg_config('--prevent-strip')
522
+ old_cflags = $CFLAGS.split.join(" ")
523
+ old_ldflags = $LDFLAGS.split.join(" ")
524
+ old_dldflags = $DLDFLAGS.split.join(" ")
525
+ $CFLAGS = $CFLAGS.split.reject { |flag| flag == "-s" }.join(" ")
526
+ $LDFLAGS = $LDFLAGS.split.reject { |flag| flag == "-s" }.join(" ")
527
+ $DLDFLAGS = $DLDFLAGS.split.reject { |flag| flag == "-s" }.join(" ")
528
+ puts "Prevent stripping by removing '-s' from $CFLAGS" if old_cflags != $CFLAGS
529
+ puts "Prevent stripping by removing '-s' from $LDFLAGS" if old_ldflags != $LDFLAGS
530
+ puts "Prevent stripping by removing '-s' from $DLDFLAGS" if old_dldflags != $DLDFLAGS
531
+ end
532
+
533
+ # adopt environment config
534
+ append_cflags(ENV["CFLAGS"].split) if !ENV["CFLAGS"].nil?
535
+ append_cppflags(ENV["CPPFLAGS"].split) if !ENV["CPPFLAGS"].nil?
536
+ append_ldflags(ENV["LDFLAGS"].split) if !ENV["LDFLAGS"].nil?
537
+ $LIBS = concat_flags($LIBS, ENV["LIBS"])
538
+
539
+ append_cflags("-g") # always include debugging information
540
+ append_cflags("-Winline") # we use at least one inline function in the C extension
541
+ append_cflags("-Wmissing-noreturn") # good to have no matter what Ruby was compiled with
542
+ append_cflags("-Wno-error=unused-command-line-argument-hard-error-in-future") if darwin?
543
+ # append_cflags(["-Wcast-qual", "-Wwrite-strings"]) # these tend to be noisy, but on occasion useful during development
544
+
545
+ # Add SDK-specific include path for macOS and brew versions before v2.2.12 (2020-04-08) [#1851, #1801]
546
+ macos_mojave_sdk_include_path = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libxml2"
547
+ if using_system_libraries? && darwin? && Dir.exist?(macos_mojave_sdk_include_path)
548
+ append_cppflags("-I#{macos_mojave_sdk_include_path}")
549
+ end
550
+
551
+ # Work around a character escaping bug in MSYS by passing an arbitrary double-quoted parameter to gcc.
552
+ # See https://sourceforge.net/p/mingw/bugs/2142
553
+ append_cppflags(' "-Idummypath"') if windows?
554
+
555
+ if using_system_libraries?
448
556
  message "Building nokogiri using system libraries.\n"
557
+ ensure_package_configuration(opt: "zlib", pc: "zlib", lib: "z", headers: "zlib.h", func: "gzdopen")
558
+ ensure_package_configuration(opt: "xml2", pc: "libxml-2.0", lib: "xml2", headers: "libxml/parser.h", func: "xmlParseDoc")
559
+ ensure_package_configuration(opt: "xslt", pc: "libxslt", lib: "xslt", headers: "libxslt/xslt.h", func: "xsltParseStylesheetDoc")
560
+ ensure_package_configuration(opt: "exslt", pc: "libexslt", lib: "exslt", headers: "libexslt/exslt.h", func: "exsltFuncRegister")
449
561
 
450
- dir_config('zlib')
451
-
452
- # Using system libraries means we rely on the system libxml2 with
453
- # regard to the iconv support.
454
-
455
- dir_config('xml2').any? or package_config('libxml-2.0')
456
- dir_config('xslt').any? or package_config('libxslt')
457
- dir_config('exslt').any? or package_config('libexslt')
458
-
459
- check_libxml_version or abort "ERROR: cannot discover where libxml2 is located on your system. please make sure `pkg-config` is installed."
460
- check_libxml_version("2.6.21") or abort "ERROR: libxml2 version 2.6.21 or later is required!"
461
- check_libxml_version("2.9.3") or warn "WARNING: libxml2 version 2.9.3 or later is highly recommended, but proceeding anyway."
562
+ have_libxml_headers?(REQUIRED_LIBXML_VERSION) or
563
+ abort "ERROR: libxml2 version #{REQUIRED_LIBXML_VERSION} or later is required!"
564
+ have_libxml_headers?(RECOMMENDED_LIBXML_VERSION) or
565
+ warn "WARNING: libxml2 version #{RECOMMENDED_LIBXML_VERSION} or later is highly recommended, but proceeding anyway."
462
566
 
463
567
  else
464
568
  message "Building nokogiri using packaged libraries.\n"
465
569
 
466
- # The gem version constraint in the Rakefile is not respected at install time.
467
- # Keep this version in sync with the one in the Rakefile !
468
- require 'rubygems'
469
- gem 'mini_portile2', '~> 2.4.0'
470
- require 'mini_portile2'
471
- message "Using mini_portile version #{MiniPortile::VERSION}\n"
570
+ static_p = enable_config("static", true)
571
+ message "Static linking is #{static_p ? "enabled" : "disabled"}.\n"
472
572
 
473
- require 'yaml'
573
+ cross_build_p = enable_config("cross-build")
574
+ message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n"
474
575
 
475
- static_p = enable_config('static', true) or
476
- message "Static linking is disabled.\n"
576
+ require 'yaml'
577
+ dependencies = YAML.load_file(File.join(PACKAGE_ROOT_DIR, "dependencies.yml"))
477
578
 
478
579
  dir_config('zlib')
479
580
 
480
- dependencies = YAML.load_file(File.join(ROOT, "dependencies.yml"))
481
-
482
- cross_build_p = enable_config("cross-build")
483
581
  if cross_build_p || windows?
484
582
  zlib_recipe = process_recipe("zlib", dependencies["zlib"]["version"], static_p, cross_build_p) do |recipe|
485
583
  recipe.files = [{
486
584
  url: "http://zlib.net/fossils/#{recipe.name}-#{recipe.version}.tar.gz",
487
585
  sha256: dependencies["zlib"]["sha256"]
488
586
  }]
489
- class << recipe
490
- attr_accessor :cross_build_p
491
-
492
- def configure
493
- Dir.chdir work_path do
494
- mk = File.read 'win32/Makefile.gcc'
495
- File.open 'win32/Makefile.gcc', 'wb' do |f|
496
- f.puts "BINARY_PATH = #{path}/bin"
497
- f.puts "LIBRARY_PATH = #{path}/lib"
498
- f.puts "INCLUDE_PATH = #{path}/include"
499
- mk.sub!(/^PREFIX\s*=\s*$/, "PREFIX = #{host}-") if cross_build_p
500
- f.puts mk
587
+ if windows?
588
+ class << recipe
589
+ attr_accessor :cross_build_p
590
+
591
+ def configure
592
+ Dir.chdir work_path do
593
+ mk = File.read 'win32/Makefile.gcc'
594
+ File.open 'win32/Makefile.gcc', 'wb' do |f|
595
+ f.puts "BINARY_PATH = #{path}/bin"
596
+ f.puts "LIBRARY_PATH = #{path}/lib"
597
+ f.puts "INCLUDE_PATH = #{path}/include"
598
+ mk.sub!(/^PREFIX\s*=\s*$/, "PREFIX = #{host}-") if cross_build_p
599
+ f.puts mk
600
+ end
601
+ end
602
+ end
603
+
604
+ def configured?
605
+ Dir.chdir work_path do
606
+ !! (File.read('win32/Makefile.gcc') =~ /^BINARY_PATH/)
501
607
  end
502
608
  end
503
- end
504
609
 
505
- def configured?
506
- Dir.chdir work_path do
507
- !! (File.read('win32/Makefile.gcc') =~ /^BINARY_PATH/)
610
+ def compile
611
+ execute "compile", "make -f win32/Makefile.gcc"
508
612
  end
509
- end
510
613
 
511
- def compile
512
- execute "compile", "make -f win32/Makefile.gcc"
614
+ def install
615
+ execute "install", "make -f win32/Makefile.gcc install"
616
+ end
513
617
  end
618
+ recipe.cross_build_p = cross_build_p
619
+ else
620
+ class << recipe
621
+ def configure
622
+ cflags = concat_flags(ENV["CFLAGS"], "-fPIC", "-g")
623
+ execute "configure", ["env", "CHOST=#{host}", "CFLAGS=#{cflags}", "./configure", "--static", configure_prefix]
624
+ end
514
625
 
515
- def install
516
- execute "install", "make -f win32/Makefile.gcc install"
626
+ def compile
627
+ if host=~/darwin/
628
+ execute "compile", "make AR=#{host}-libtool"
629
+ else
630
+ super
631
+ end
632
+ end
517
633
  end
518
634
  end
519
- recipe.cross_build_p = cross_build_p
520
635
  end
521
636
 
522
- libiconv_recipe = process_recipe("libiconv", dependencies["libiconv"]["version"], static_p, cross_build_p) do |recipe|
523
- recipe.files = [{
524
- url: "http://ftp.gnu.org/pub/gnu/libiconv/#{recipe.name}-#{recipe.version}.tar.gz",
525
- sha256: dependencies["libiconv"]["sha256"]
526
- }]
527
- recipe.configure_options += [
528
- "CPPFLAGS=-Wall",
529
- "CFLAGS=-O2 -g",
530
- "CXXFLAGS=-O2 -g",
531
- "LDFLAGS="
532
- ]
637
+ unless nix?
638
+ libiconv_recipe = process_recipe("libiconv", dependencies["libiconv"]["version"], static_p, cross_build_p) do |recipe|
639
+ recipe.files = [{
640
+ url: "http://ftp.gnu.org/pub/gnu/libiconv/#{recipe.name}-#{recipe.version}.tar.gz",
641
+ sha256: dependencies["libiconv"]["sha256"]
642
+ }]
643
+
644
+ cflags = concat_flags(ENV["CFLAGS"], "-O2", "-U_FORTIFY_SOURCE", "-g")
645
+
646
+ recipe.configure_options += [
647
+ "CPPFLAGS=-Wall",
648
+ "CFLAGS=#{cflags}",
649
+ "CXXFLAGS=#{cflags}",
650
+ "LDFLAGS="
651
+ ]
652
+ end
533
653
  end
534
654
  else
535
655
  if darwin? && !have_header('iconv.h')
536
- abort <<'EOM'.chomp
537
- -----
538
- The file "iconv.h" is missing in your build environment,
539
- which means you haven't installed Xcode Command Line Tools properly.
540
-
541
- To install Command Line Tools, try running `xcode-select --install` on
542
- terminal and follow the instructions. If it fails, open Xcode.app,
543
- select from the menu "Xcode" - "Open Developer Tool" - "More Developer
544
- Tools" to open the developer site, download the installer for your OS
545
- version and run it.
546
- -----
547
- EOM
656
+ abort <<~EOM.chomp
657
+ -----
658
+ The file "iconv.h" is missing in your build environment,
659
+ which means you haven't installed Xcode Command Line Tools properly.
660
+
661
+ To install Command Line Tools, try running `xcode-select --install` on
662
+ terminal and follow the instructions. If it fails, open Xcode.app,
663
+ select from the menu "Xcode" - "Open Developer Tool" - "More Developer
664
+ Tools" to open the developer site, download the installer for your OS
665
+ version and run it.
666
+ -----
667
+ EOM
548
668
  end
549
669
  end
550
670
 
551
671
  unless windows?
552
- preserving_globals {
553
- have_library('z', 'gzdopen', 'zlib.h')
554
- } or abort 'zlib is missing; necessary for building libxml2'
672
+ preserving_globals { local_have_library('z', 'gzdopen', 'zlib.h') } or
673
+ abort 'zlib is missing; necessary for building libxml2'
555
674
  end
556
675
 
557
676
  libxml2_recipe = process_recipe("libxml2", dependencies["libxml2"]["version"], static_p, cross_build_p) do |recipe|
@@ -559,15 +678,31 @@ EOM
559
678
  url: "http://xmlsoft.org/sources/#{recipe.name}-#{recipe.version}.tar.gz",
560
679
  sha256: dependencies["libxml2"]["sha256"]
561
680
  }]
681
+
682
+ cflags = concat_flags(ENV["CFLAGS"], "-O2", "-U_FORTIFY_SOURCE", "-g")
683
+
684
+ if zlib_recipe
685
+ recipe.configure_options << "--with-zlib=#{zlib_recipe.path}"
686
+ cflags = concat_flags(cflags, "-I#{zlib_recipe.path}/include")
687
+ end
688
+
689
+ if libiconv_recipe
690
+ recipe.configure_options << "--with-iconv=#{libiconv_recipe.path}"
691
+ else
692
+ recipe.configure_options += iconv_configure_flags
693
+ end
694
+
695
+ if darwin? && !cross_build_p
696
+ recipe.configure_options += ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"]
697
+ end
698
+
562
699
  recipe.configure_options += [
563
700
  "--without-python",
564
701
  "--without-readline",
565
- *(zlib_recipe ? ["--with-zlib=#{zlib_recipe.path}", "CFLAGS=-I#{zlib_recipe.path}/include"] : []),
566
- *(libiconv_recipe ? "--with-iconv=#{libiconv_recipe.path}" : iconv_configure_flags),
567
702
  "--with-c14n",
568
703
  "--with-debug",
569
704
  "--with-threads",
570
- *(darwin? ? ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"] : "")
705
+ "CFLAGS=#{cflags}",
571
706
  ]
572
707
  end
573
708
 
@@ -576,23 +711,28 @@ EOM
576
711
  url: "http://xmlsoft.org/sources/#{recipe.name}-#{recipe.version}.tar.gz",
577
712
  sha256: dependencies["libxslt"]["sha256"]
578
713
  }]
714
+
715
+ cflags = concat_flags(ENV["CFLAGS"], "-O2", "-U_FORTIFY_SOURCE", "-g")
716
+
717
+ if darwin? && !cross_build_p
718
+ recipe.configure_options += ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"]
719
+ end
720
+
579
721
  recipe.configure_options += [
580
722
  "--without-python",
581
723
  "--without-crypto",
582
724
  "--with-debug",
583
725
  "--with-libxml-prefix=#{sh_export_path(libxml2_recipe.path)}",
584
- *(darwin? ? ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"] : "")
726
+ "CFLAGS=#{cflags}",
585
727
  ]
586
728
  end
587
729
 
588
- $CFLAGS << ' ' << '-DNOKOGIRI_USE_PACKAGED_LIBRARIES'
730
+ append_cppflags("-DNOKOGIRI_PACKAGED_LIBRARIES")
731
+ append_cppflags("-DNOKOGIRI_PRECOMPILED_LIBRARIES") if cross_build_p
732
+
589
733
  $LIBPATH = ["#{zlib_recipe.path}/lib"] | $LIBPATH if zlib_recipe
590
734
  $LIBPATH = ["#{libiconv_recipe.path}/lib"] | $LIBPATH if libiconv_recipe
591
735
 
592
- have_lzma = preserving_globals {
593
- have_library('lzma')
594
- }
595
-
596
736
  $libs = $libs.shellsplit.tap do |libs|
597
737
  [libxml2_recipe, libxslt_recipe].each do |recipe|
598
738
  libname = recipe.name[/\Alib(.+)\z/, 1]
@@ -603,7 +743,7 @@ EOM
603
743
  case arg
604
744
  when /\A-L(.+)\z/
605
745
  # Prioritize ports' directories
606
- if $1.start_with?(ROOT + '/')
746
+ if $1.start_with?(PACKAGE_ROOT_DIR + '/')
607
747
  $LIBPATH = [$1] | $LIBPATH
608
748
  else
609
749
  $LIBPATH = $LIBPATH | [$1]
@@ -616,15 +756,14 @@ EOM
616
756
  end
617
757
  end
618
758
 
619
- # Defining a macro that expands to a C string; double quotes are significant.
620
- $CPPFLAGS << ' ' << "-DNOKOGIRI_#{recipe.name.upcase}_PATH=\"#{recipe.path}\"".inspect
621
- $CPPFLAGS << ' ' << "-DNOKOGIRI_#{recipe.name.upcase}_PATCHES=\"#{recipe.patch_files.map { |path| File.basename(path) }.join(' ')}\"".inspect
759
+ patches_string = recipe.patch_files.map { |path| File.basename(path) }.join(' ')
760
+ append_cppflags(%Q[-DNOKOGIRI_#{recipe.name.upcase}_PATCHES="\\\"#{patches_string}\\\""])
622
761
 
623
762
  case libname
624
763
  when 'xml2'
625
764
  # xslt-config --libs or pkg-config libxslt --libs does not include
626
765
  # -llzma, so we need to add it manually when linking statically.
627
- if static_p && have_lzma
766
+ if static_p && preserving_globals { local_have_library('lzma') }
628
767
  # Add it at the end; GH #988
629
768
  libs << '-llzma'
630
769
  end
@@ -640,46 +779,57 @@ EOM
640
779
  $libs = $libs.shellsplit.map do |arg|
641
780
  case arg
642
781
  when '-lxml2'
643
- File.join(libxml2_recipe.path, 'lib', lib_a(arg))
782
+ File.join(libxml2_recipe.path, 'lib', libflag_to_filename(arg))
644
783
  when '-lxslt', '-lexslt'
645
- File.join(libxslt_recipe.path, 'lib', lib_a(arg))
784
+ File.join(libxslt_recipe.path, 'lib', libflag_to_filename(arg))
646
785
  else
647
786
  arg
648
787
  end
649
788
  end.shelljoin
650
789
  end
651
- end
652
790
 
653
- {
654
- "xml2" => ['xmlParseDoc', 'libxml/parser.h'],
655
- "xslt" => ['xsltParseStylesheetDoc', 'libxslt/xslt.h'],
656
- "exslt" => ['exsltFuncRegister', 'libexslt/exslt.h'],
657
- }.each do |lib, (func, header)|
658
- have_func(func, header) ||
659
- have_library(lib, func, header) ||
660
- have_library("lib#{lib}", func, header) or
661
- asplode("lib#{lib}")
791
+ ensure_func("xmlParseDoc", "libxml/parser.h")
792
+ ensure_func("xsltParseStylesheetDoc", "libxslt/xslt.h")
793
+ ensure_func("exsltFuncRegister", "libexslt/exslt.h")
662
794
  end
663
795
 
664
- have_func('xmlHasFeature') or abort "xmlHasFeature() is missing."
665
- have_func('xmlFirstElementChild')
666
- have_func('xmlRelaxNGSetParserStructuredErrors')
667
- have_func('xmlRelaxNGSetParserStructuredErrors')
668
- have_func('xmlRelaxNGSetValidStructuredErrors')
669
- have_func('xmlSchemaSetValidStructuredErrors')
670
- have_func('xmlSchemaSetParserStructuredErrors')
796
+ have_func('xmlHasFeature') or abort("xmlHasFeature() is missing.") # introduced in libxml 2.6.21
797
+ have_func('xmlFirstElementChild') # introduced in libxml 2.7.3
798
+ have_func('xmlRelaxNGSetParserStructuredErrors') # introduced in libxml 2.6.24
799
+ have_func('xmlRelaxNGSetValidStructuredErrors') # introduced in libxml 2.6.21
800
+ have_func('xmlSchemaSetValidStructuredErrors') # introduced in libxml 2.6.23
801
+ have_func('xmlSchemaSetParserStructuredErrors') # introduced in libxml 2.6.23
802
+
803
+ have_func('vasprintf')
804
+
805
+ other_library_versions_string = OTHER_LIBRARY_VERSIONS.map { |k,v| [k,v].join(":") }.join(",")
806
+ append_cppflags(%Q[-DNOKOGIRI_OTHER_LIBRARY_VERSIONS="\\\"#{other_library_versions_string}\\\""])
807
+
808
+ unless using_system_libraries?
809
+ if cross_build_p
810
+ # When precompiling native gems, copy packaged libraries' headers to ext/nokogiri/include
811
+ # These are packaged up by the cross-compiling callback in the ExtensionTask
812
+ copy_packaged_libraries_headers(to_path: File.join(PACKAGE_ROOT_DIR, "ext/nokogiri/include"),
813
+ from_recipes: [libxml2_recipe, libxslt_recipe])
814
+ else
815
+ # When compiling during installation, install packaged libraries' header files into ext/nokogiri/include
816
+ copy_packaged_libraries_headers(to_path: "include",
817
+ from_recipes: [libxml2_recipe, libxslt_recipe])
818
+ $INSTALLFILES << ["include/**/*.h", "$(rubylibdir)"]
819
+ end
820
+ end
671
821
 
672
822
  create_makefile('nokogiri/nokogiri')
673
823
 
674
824
  if enable_config('clean', true)
675
825
  # Do not clean if run in a development work tree.
676
826
  File.open('Makefile', 'at') do |mk|
677
- mk.print <<EOF
678
- all: clean-ports
827
+ mk.print <<~EOF
679
828
 
680
- clean-ports: $(DLLIB)
681
- -$(Q)$(RUBY) $(srcdir)/extconf.rb --clean --#{static_p ? 'enable' : 'disable'}-static
682
- EOF
829
+ all: clean-ports
830
+ clean-ports: $(DLLIB)
831
+ \t-$(Q)$(RUBY) $(srcdir)/extconf.rb --clean --#{static_p ? 'enable' : 'disable'}-static
832
+ EOF
683
833
  end
684
834
  end
685
835