nokogiri 1.10.10 → 1.12.1

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 (216) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/LICENSE-DEPENDENCIES.md +1173 -884
  4. data/LICENSE.md +1 -1
  5. data/README.md +176 -96
  6. data/dependencies.yml +12 -12
  7. data/ext/nokogiri/depend +38 -358
  8. data/ext/nokogiri/extconf.rb +712 -414
  9. data/ext/nokogiri/gumbo.c +584 -0
  10. data/ext/nokogiri/html4_document.c +166 -0
  11. data/ext/nokogiri/html4_element_description.c +294 -0
  12. data/ext/nokogiri/html4_entity_lookup.c +37 -0
  13. data/ext/nokogiri/html4_sax_parser_context.c +119 -0
  14. data/ext/nokogiri/html4_sax_push_parser.c +95 -0
  15. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  16. data/ext/nokogiri/nokogiri.c +228 -91
  17. data/ext/nokogiri/nokogiri.h +188 -89
  18. data/ext/nokogiri/test_global_handlers.c +40 -0
  19. data/ext/nokogiri/xml_attr.c +15 -15
  20. data/ext/nokogiri/xml_attribute_decl.c +18 -18
  21. data/ext/nokogiri/xml_cdata.c +13 -18
  22. data/ext/nokogiri/xml_comment.c +19 -26
  23. data/ext/nokogiri/xml_document.c +267 -195
  24. data/ext/nokogiri/xml_document_fragment.c +13 -15
  25. data/ext/nokogiri/xml_dtd.c +54 -48
  26. data/ext/nokogiri/xml_element_content.c +31 -26
  27. data/ext/nokogiri/xml_element_decl.c +22 -22
  28. data/ext/nokogiri/xml_encoding_handler.c +28 -17
  29. data/ext/nokogiri/xml_entity_decl.c +32 -30
  30. data/ext/nokogiri/xml_entity_reference.c +16 -18
  31. data/ext/nokogiri/xml_namespace.c +58 -49
  32. data/ext/nokogiri/xml_node.c +489 -410
  33. data/ext/nokogiri/xml_node_set.c +174 -162
  34. data/ext/nokogiri/xml_processing_instruction.c +17 -19
  35. data/ext/nokogiri/xml_reader.c +197 -172
  36. data/ext/nokogiri/xml_relax_ng.c +52 -28
  37. data/ext/nokogiri/xml_sax_parser.c +112 -112
  38. data/ext/nokogiri/xml_sax_parser_context.c +105 -86
  39. data/ext/nokogiri/xml_sax_push_parser.c +36 -27
  40. data/ext/nokogiri/xml_schema.c +96 -46
  41. data/ext/nokogiri/xml_syntax_error.c +42 -21
  42. data/ext/nokogiri/xml_text.c +13 -17
  43. data/ext/nokogiri/xml_xpath_context.c +158 -73
  44. data/ext/nokogiri/xslt_stylesheet.c +158 -164
  45. data/gumbo-parser/CHANGES.md +63 -0
  46. data/gumbo-parser/Makefile +101 -0
  47. data/gumbo-parser/THANKS +27 -0
  48. data/gumbo-parser/src/Makefile +34 -0
  49. data/gumbo-parser/src/README.md +41 -0
  50. data/gumbo-parser/src/ascii.c +75 -0
  51. data/gumbo-parser/src/ascii.h +115 -0
  52. data/gumbo-parser/src/attribute.c +42 -0
  53. data/gumbo-parser/src/attribute.h +17 -0
  54. data/gumbo-parser/src/char_ref.c +22225 -0
  55. data/gumbo-parser/src/char_ref.h +29 -0
  56. data/gumbo-parser/src/char_ref.rl +2154 -0
  57. data/gumbo-parser/src/error.c +626 -0
  58. data/gumbo-parser/src/error.h +148 -0
  59. data/gumbo-parser/src/foreign_attrs.c +104 -0
  60. data/gumbo-parser/src/foreign_attrs.gperf +27 -0
  61. data/gumbo-parser/src/gumbo.h +943 -0
  62. data/gumbo-parser/src/insertion_mode.h +33 -0
  63. data/gumbo-parser/src/macros.h +91 -0
  64. data/gumbo-parser/src/parser.c +4886 -0
  65. data/gumbo-parser/src/parser.h +41 -0
  66. data/gumbo-parser/src/replacement.h +33 -0
  67. data/gumbo-parser/src/string_buffer.c +103 -0
  68. data/gumbo-parser/src/string_buffer.h +68 -0
  69. data/gumbo-parser/src/string_piece.c +48 -0
  70. data/gumbo-parser/src/svg_attrs.c +174 -0
  71. data/gumbo-parser/src/svg_attrs.gperf +77 -0
  72. data/gumbo-parser/src/svg_tags.c +137 -0
  73. data/gumbo-parser/src/svg_tags.gperf +55 -0
  74. data/gumbo-parser/src/tag.c +222 -0
  75. data/gumbo-parser/src/tag_lookup.c +382 -0
  76. data/gumbo-parser/src/tag_lookup.gperf +169 -0
  77. data/gumbo-parser/src/tag_lookup.h +13 -0
  78. data/gumbo-parser/src/token_buffer.c +79 -0
  79. data/gumbo-parser/src/token_buffer.h +71 -0
  80. data/gumbo-parser/src/token_type.h +17 -0
  81. data/gumbo-parser/src/tokenizer.c +3463 -0
  82. data/gumbo-parser/src/tokenizer.h +112 -0
  83. data/gumbo-parser/src/tokenizer_states.h +339 -0
  84. data/gumbo-parser/src/utf8.c +245 -0
  85. data/gumbo-parser/src/utf8.h +164 -0
  86. data/gumbo-parser/src/util.c +68 -0
  87. data/gumbo-parser/src/util.h +30 -0
  88. data/gumbo-parser/src/vector.c +111 -0
  89. data/gumbo-parser/src/vector.h +45 -0
  90. data/lib/nokogiri.rb +32 -51
  91. data/lib/nokogiri/css.rb +15 -14
  92. data/lib/nokogiri/css/node.rb +1 -0
  93. data/lib/nokogiri/css/parser.rb +64 -63
  94. data/lib/nokogiri/css/parser.y +3 -3
  95. data/lib/nokogiri/css/parser_extras.rb +39 -36
  96. data/lib/nokogiri/css/syntax_error.rb +2 -1
  97. data/lib/nokogiri/css/tokenizer.rb +1 -0
  98. data/lib/nokogiri/css/xpath_visitor.rb +73 -43
  99. data/lib/nokogiri/decorators/slop.rb +1 -0
  100. data/lib/nokogiri/extension.rb +26 -0
  101. data/lib/nokogiri/gumbo.rb +14 -0
  102. data/lib/nokogiri/html.rb +32 -27
  103. data/lib/nokogiri/html4.rb +40 -0
  104. data/lib/nokogiri/{html → html4}/builder.rb +3 -2
  105. data/lib/nokogiri/{html → html4}/document.rb +17 -30
  106. data/lib/nokogiri/{html → html4}/document_fragment.rb +18 -17
  107. data/lib/nokogiri/{html → html4}/element_description.rb +2 -1
  108. data/lib/nokogiri/{html → html4}/element_description_defaults.rb +2 -1
  109. data/lib/nokogiri/{html → html4}/entity_lookup.rb +2 -1
  110. data/lib/nokogiri/{html → html4}/sax/parser.rb +12 -14
  111. data/lib/nokogiri/html4/sax/parser_context.rb +19 -0
  112. data/lib/nokogiri/{html → html4}/sax/push_parser.rb +6 -5
  113. data/lib/nokogiri/html5.rb +473 -0
  114. data/lib/nokogiri/html5/document.rb +74 -0
  115. data/lib/nokogiri/html5/document_fragment.rb +80 -0
  116. data/lib/nokogiri/html5/node.rb +93 -0
  117. data/lib/nokogiri/jruby/dependencies.rb +20 -0
  118. data/lib/nokogiri/syntax_error.rb +1 -0
  119. data/lib/nokogiri/version.rb +3 -109
  120. data/lib/nokogiri/version/constant.rb +5 -0
  121. data/lib/nokogiri/version/info.rb +215 -0
  122. data/lib/nokogiri/xml.rb +36 -36
  123. data/lib/nokogiri/xml/attr.rb +1 -0
  124. data/lib/nokogiri/xml/attribute_decl.rb +1 -0
  125. data/lib/nokogiri/xml/builder.rb +3 -2
  126. data/lib/nokogiri/xml/cdata.rb +1 -0
  127. data/lib/nokogiri/xml/character_data.rb +1 -0
  128. data/lib/nokogiri/xml/document.rb +92 -41
  129. data/lib/nokogiri/xml/document_fragment.rb +5 -6
  130. data/lib/nokogiri/xml/dtd.rb +1 -0
  131. data/lib/nokogiri/xml/element_content.rb +1 -0
  132. data/lib/nokogiri/xml/element_decl.rb +1 -0
  133. data/lib/nokogiri/xml/entity_decl.rb +1 -0
  134. data/lib/nokogiri/xml/entity_reference.rb +1 -0
  135. data/lib/nokogiri/xml/namespace.rb +1 -0
  136. data/lib/nokogiri/xml/node.rb +629 -293
  137. data/lib/nokogiri/xml/node/save_options.rb +1 -0
  138. data/lib/nokogiri/xml/node_set.rb +1 -0
  139. data/lib/nokogiri/xml/notation.rb +1 -0
  140. data/lib/nokogiri/xml/parse_options.rb +12 -3
  141. data/lib/nokogiri/xml/pp.rb +3 -2
  142. data/lib/nokogiri/xml/pp/character_data.rb +1 -0
  143. data/lib/nokogiri/xml/pp/node.rb +1 -0
  144. data/lib/nokogiri/xml/processing_instruction.rb +1 -0
  145. data/lib/nokogiri/xml/reader.rb +9 -12
  146. data/lib/nokogiri/xml/relax_ng.rb +7 -2
  147. data/lib/nokogiri/xml/sax.rb +5 -4
  148. data/lib/nokogiri/xml/sax/document.rb +25 -30
  149. data/lib/nokogiri/xml/sax/parser.rb +1 -0
  150. data/lib/nokogiri/xml/sax/parser_context.rb +1 -0
  151. data/lib/nokogiri/xml/sax/push_parser.rb +1 -0
  152. data/lib/nokogiri/xml/schema.rb +13 -4
  153. data/lib/nokogiri/xml/searchable.rb +25 -16
  154. data/lib/nokogiri/xml/syntax_error.rb +1 -0
  155. data/lib/nokogiri/xml/text.rb +1 -0
  156. data/lib/nokogiri/xml/xpath.rb +4 -5
  157. data/lib/nokogiri/xml/xpath/syntax_error.rb +2 -1
  158. data/lib/nokogiri/xml/xpath_context.rb +1 -0
  159. data/lib/nokogiri/xslt.rb +17 -16
  160. data/lib/nokogiri/xslt/stylesheet.rb +2 -1
  161. data/lib/xsd/xmlparser/nokogiri.rb +1 -0
  162. data/patches/libxml2/{0002-Remove-script-macro-support.patch → 0001-Remove-script-macro-support.patch} +0 -0
  163. data/patches/libxml2/{0003-Update-entities-to-remove-handling-of-ssi.patch → 0002-Update-entities-to-remove-handling-of-ssi.patch} +0 -0
  164. data/patches/libxml2/{0004-libxml2.la-is-in-top_builddir.patch → 0003-libxml2.la-is-in-top_builddir.patch} +1 -1
  165. data/patches/libxml2/0004-use-glibc-strlen.patch +53 -0
  166. data/patches/libxml2/0005-avoid-isnan-isinf.patch +81 -0
  167. data/patches/libxml2/0006-update-automake-files-for-arm64.patch +2511 -0
  168. data/patches/libxml2/0007-Fix-XPath-recursion-limit.patch +31 -0
  169. data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2511 -0
  170. data/patches/libxslt/0002-Fix-xml2-config-check-in-configure-script.patch +19 -0
  171. data/ports/archives/libxml2-2.9.12.tar.gz +0 -0
  172. metadata +139 -161
  173. data/ext/nokogiri/html_document.c +0 -170
  174. data/ext/nokogiri/html_document.h +0 -10
  175. data/ext/nokogiri/html_element_description.c +0 -279
  176. data/ext/nokogiri/html_element_description.h +0 -10
  177. data/ext/nokogiri/html_entity_lookup.c +0 -32
  178. data/ext/nokogiri/html_entity_lookup.h +0 -8
  179. data/ext/nokogiri/html_sax_parser_context.c +0 -116
  180. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  181. data/ext/nokogiri/html_sax_push_parser.c +0 -87
  182. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  183. data/ext/nokogiri/xml_attr.h +0 -9
  184. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  185. data/ext/nokogiri/xml_cdata.h +0 -9
  186. data/ext/nokogiri/xml_comment.h +0 -9
  187. data/ext/nokogiri/xml_document.h +0 -23
  188. data/ext/nokogiri/xml_document_fragment.h +0 -10
  189. data/ext/nokogiri/xml_dtd.h +0 -10
  190. data/ext/nokogiri/xml_element_content.h +0 -10
  191. data/ext/nokogiri/xml_element_decl.h +0 -9
  192. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  193. data/ext/nokogiri/xml_entity_decl.h +0 -10
  194. data/ext/nokogiri/xml_entity_reference.h +0 -9
  195. data/ext/nokogiri/xml_io.c +0 -61
  196. data/ext/nokogiri/xml_io.h +0 -11
  197. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
  198. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  199. data/ext/nokogiri/xml_namespace.h +0 -14
  200. data/ext/nokogiri/xml_node.h +0 -13
  201. data/ext/nokogiri/xml_node_set.h +0 -12
  202. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  203. data/ext/nokogiri/xml_reader.h +0 -10
  204. data/ext/nokogiri/xml_relax_ng.h +0 -9
  205. data/ext/nokogiri/xml_sax_parser.h +0 -39
  206. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  207. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  208. data/ext/nokogiri/xml_schema.h +0 -9
  209. data/ext/nokogiri/xml_syntax_error.h +0 -13
  210. data/ext/nokogiri/xml_text.h +0 -9
  211. data/ext/nokogiri/xml_xpath_context.h +0 -10
  212. data/ext/nokogiri/xslt_stylesheet.h +0 -14
  213. data/lib/nokogiri/html/sax/parser_context.rb +0 -16
  214. data/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch +0 -78
  215. data/patches/libxml2/0005-Fix-infinite-loop-in-xmlStringLenDecodeEntities.patch +0 -32
  216. data/ports/archives/libxml2-2.9.10.tar.gz +0 -0
@@ -1,208 +1,364 @@
1
- # :stopdoc:
2
- ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
1
+ # frozen_string_literal: true
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
+ # helpful constants
11
+ PACKAGE_ROOT_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
12
+ REQUIRED_LIBXML_VERSION = "2.6.21"
13
+ RECOMMENDED_LIBXML_VERSION = "2.9.3"
14
+
15
+ # The gem version constraint in the Rakefile is not respected at install time.
16
+ # Keep this version in sync with the one in the Rakefile !
17
+ REQUIRED_MINI_PORTILE_VERSION = "~> 2.6.1"
18
+ REQUIRED_PKG_CONFIG_VERSION = "~> 1.1"
19
+
20
+ # Keep track of what versions of what libraries we build against
21
+ OTHER_LIBRARY_VERSIONS = {}
22
+
23
+ NOKOGIRI_HELP_MESSAGE = <<~HELP
24
+ USAGE: ruby #{$0} [options]
25
+
26
+ Flags that are always valid:
27
+
28
+ --use-system-libraries
29
+ --enable-system-libraries
30
+ Use system libraries instead of building and using the packaged libraries.
31
+
32
+ --disable-system-libraries
33
+ Use the packaged libraries, and ignore the system libraries. This is the default on most
34
+ platforms, and overrides `--use-system-libraries` and the environment variable
35
+ `NOKOGIRI_USE_SYSTEM_LIBRARIES`.
36
+
37
+ --disable-clean
38
+ Do not clean out intermediate files after successful build.
39
+
40
+ --prevent-strip
41
+ Take steps to prevent stripping the symbol table and debugging info from the shared
42
+ library, potentially overriding RbConfig's CFLAGS/LDFLAGS/DLDFLAGS.
43
+
44
+
45
+ Flags only used when using system libraries:
46
+
47
+ General:
48
+
49
+ --with-opt-dir=DIRECTORY
50
+ Look for headers and libraries in DIRECTORY.
51
+
52
+ --with-opt-lib=DIRECTORY
53
+ Look for libraries in DIRECTORY.
54
+
55
+ --with-opt-include=DIRECTORY
56
+ Look for headers in DIRECTORY.
57
+
58
+
59
+ Related to zlib:
60
+
61
+ --with-zlib-dir=DIRECTORY
62
+ Look for zlib headers and library in DIRECTORY.
63
+
64
+ --with-zlib-lib=DIRECTORY
65
+ Look for zlib library in DIRECTORY.
66
+
67
+ --with-zlib-include=DIRECTORY
68
+ Look for zlib headers in DIRECTORY.
69
+
70
+
71
+ Related to iconv:
72
+
73
+ --with-iconv-dir=DIRECTORY
74
+ Look for iconv headers and library in DIRECTORY.
75
+
76
+ --with-iconv-lib=DIRECTORY
77
+ Look for iconv library in DIRECTORY.
78
+
79
+ --with-iconv-include=DIRECTORY
80
+ Look for iconv headers in DIRECTORY.
81
+
82
+
83
+ Related to libxml2:
84
+
85
+ --with-xml2-dir=DIRECTORY
86
+ Look for xml2 headers and library in DIRECTORY.
87
+
88
+ --with-xml2-lib=DIRECTORY
89
+ Look for xml2 library in DIRECTORY.
90
+
91
+ --with-xml2-include=DIRECTORY
92
+ Look for xml2 headers in DIRECTORY.
93
+
94
+ --with-xml2-source-dir=DIRECTORY
95
+ (dev only) Build libxml2 from the source code in DIRECTORY
96
+
97
+
98
+ Related to libxslt:
99
+
100
+ --with-xslt-dir=DIRECTORY
101
+ Look for xslt headers and library in DIRECTORY.
102
+
103
+ --with-xslt-lib=DIRECTORY
104
+ Look for xslt library in DIRECTORY.
105
+
106
+ --with-xslt-include=DIRECTORY
107
+ Look for xslt headers in DIRECTORY.
108
+
109
+ --with-xslt-source-dir=DIRECTORY
110
+ (dev only) Build libxslt from the source code in DIRECTORY
111
+
112
+
113
+ Related to libexslt:
114
+
115
+ --with-exslt-dir=DIRECTORY
116
+ Look for exslt headers and library in DIRECTORY.
117
+
118
+ --with-exslt-lib=DIRECTORY
119
+ Look for exslt library in DIRECTORY.
120
+
121
+ --with-exslt-include=DIRECTORY
122
+ Look for exslt headers in DIRECTORY.
123
+
124
+
125
+ Flags only used when building and using the packaged libraries:
126
+
127
+ --disable-static
128
+ Do not statically link packaged libraries, instead use shared libraries.
129
+
130
+ --enable-cross-build
131
+ Enable cross-build mode. (You probably do not want to set this manually.)
132
+
133
+
134
+ Environment variables used:
135
+
136
+ NOKOGIRI_USE_SYSTEM_LIBRARIES
137
+ Equivalent to `--enable-system-libraries` when set, even if nil or blank.
138
+
139
+ CC
140
+ Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
141
+
142
+ CPPFLAGS
143
+ If this string is accepted by the C preprocessor, add it to the flags passed to the C preprocessor
144
+
145
+ CFLAGS
146
+ If this string is accepted by the compiler, add it to the flags passed to the compiler
147
+
148
+ LDFLAGS
149
+ If this string is accepted by the linker, add it to the flags passed to the linker
150
+
151
+ LIBS
152
+ Add this string to the flags passed to the linker
153
+ HELP
7
154
 
8
155
  #
9
- # functions
156
+ # utility functions
10
157
  #
158
+ def config_clean?
159
+ enable_config("clean", true)
160
+ end
161
+
162
+ def config_static?
163
+ default_static = !truffle?
164
+ enable_config("static", default_static)
165
+ end
166
+
167
+ def config_cross_build?
168
+ enable_config("cross-build")
169
+ end
170
+
171
+ def config_system_libraries?
172
+ enable_config("system-libraries", ENV.key?("NOKOGIRI_USE_SYSTEM_LIBRARIES")) do |_, default|
173
+ arg_config("--use-system-libraries", default)
174
+ end
175
+ end
176
+
11
177
  def windows?
12
- RbConfig::CONFIG['target_os'] =~ /mingw32|mswin/
178
+ RbConfig::CONFIG["target_os"] =~ /mingw32|mswin/
13
179
  end
14
180
 
15
181
  def solaris?
16
- RbConfig::CONFIG['target_os'] =~ /solaris/
182
+ RbConfig::CONFIG["target_os"] =~ /solaris/
17
183
  end
18
184
 
19
185
  def darwin?
20
- RbConfig::CONFIG['target_os'] =~ /darwin/
186
+ RbConfig::CONFIG["target_os"] =~ /darwin/
21
187
  end
22
188
 
23
189
  def openbsd?
24
- RbConfig::CONFIG['target_os'] =~ /openbsd/
190
+ RbConfig::CONFIG["target_os"] =~ /openbsd/
191
+ end
192
+
193
+ def aix?
194
+ RbConfig::CONFIG["target_os"] =~ /aix/
25
195
  end
26
196
 
27
197
  def nix?
28
- ! (windows? || solaris? || darwin?)
198
+ !(windows? || solaris? || darwin?)
29
199
  end
30
200
 
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
201
+ def truffle?
202
+ ::RUBY_ENGINE == "truffleruby"
50
203
  end
51
204
 
52
- def do_help
53
- print <<HELP
54
- usage: ruby #{$0} [options]
205
+ def concat_flags(*args)
206
+ args.compact.join(" ")
207
+ end
55
208
 
56
- --disable-clean
57
- Do not clean out intermediate files after successful build.
209
+ def local_have_library(lib, func = nil, headers = nil)
210
+ have_library(lib, func, headers) || have_library("lib#{lib}", func, headers)
211
+ end
58
212
 
59
- --disable-static
60
- Do not statically link bundled libraries.
213
+ LOCAL_PACKAGE_RESPONSE = Object.new
214
+ def LOCAL_PACKAGE_RESPONSE.%(package)
215
+ package ? "yes: #{package}" : "no"
216
+ end
61
217
 
62
- --with-iconv-dir=DIR
63
- Use the iconv library placed under DIR.
218
+ # wrapper around MakeMakefil#pkg_config and the PKGConfig gem
219
+ def try_package_configuration(pc)
220
+ unless ENV.key?("NOKOGIRI_TEST_PKG_CONFIG_GEM")
221
+ # try MakeMakefile#pkg_config, which uses the system utility `pkg-config`.
222
+ return if checking_for("#{pc} using `pkg_config`", LOCAL_PACKAGE_RESPONSE) do
223
+ pkg_config(pc)
224
+ end
225
+ end
64
226
 
65
- --with-zlib-dir=DIR
66
- Use the zlib library placed under DIR.
227
+ # `pkg-config` probably isn't installed, which appears to be the case for lots of freebsd systems.
228
+ # let's fall back to the pkg-config gem, which knows how to parse .pc files, and wrap it with the
229
+ # same logic as MakeMakefile#pkg_config
230
+ begin
231
+ require "rubygems"
232
+ gem("pkg-config", REQUIRED_PKG_CONFIG_VERSION)
233
+ require "pkg-config"
67
234
 
68
- --use-system-libraries
69
- Use system libraries instead of building and using the bundled
70
- libraries.
235
+ checking_for("#{pc} using pkg-config gem version #{PKGConfig::VERSION}", LOCAL_PACKAGE_RESPONSE) do
236
+ if PKGConfig.have_package(pc)
237
+ cflags = PKGConfig.cflags(pc)
238
+ ldflags = PKGConfig.libs_only_L(pc)
239
+ libs = PKGConfig.libs_only_l(pc)
71
240
 
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.
241
+ Logging.message("pkg-config gem found package configuration for %s\n", pc)
242
+ Logging.message("cflags: %s\nldflags: %s\nlibs: %s\n\n", cflags, ldflags, libs)
76
243
 
77
- --enable-cross-build
78
- Do cross-build.
79
- HELP
80
- exit! 0
244
+ [cflags, ldflags, libs]
245
+ end
246
+ end
247
+ rescue LoadError
248
+ message("Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n")
249
+ end
81
250
  end
82
251
 
83
- def do_clean
84
- require 'pathname'
85
- require 'fileutils'
252
+ # set up mkmf to link against the library if we can find it
253
+ def have_package_configuration(opt: nil, pc: nil, lib:, func:, headers:)
254
+ if opt
255
+ dir_config(opt)
256
+ dir_config("opt")
257
+ end
86
258
 
87
- root = Pathname(ROOT)
88
- pwd = Pathname(Dir.pwd)
259
+ # see if we have enough path info to do this without trying any harder
260
+ unless ENV.key?("NOKOGIRI_TEST_PKG_CONFIG")
261
+ return true if local_have_library(lib, func, headers)
262
+ end
89
263
 
90
- # Skip if this is a development work tree
91
- unless (root + '.git').exist?
92
- message "Cleaning files only used during build.\n"
264
+ try_package_configuration(pc) if pc
93
265
 
94
- # (root + 'tmp') cannot be removed at this stage because
95
- # nokogiri.so is yet to be copied to lib.
96
-
97
- # clean the ports build directory
98
- Pathname.glob(pwd.join('tmp', '*', 'ports')) do |dir|
99
- FileUtils.rm_rf(dir, verbose: true)
100
- end
266
+ # verify that we can compile and link against the library
267
+ local_have_library(lib, func, headers)
268
+ end
101
269
 
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
270
+ def ensure_package_configuration(opt: nil, pc: nil, lib:, func:, headers:)
271
+ have_package_configuration(opt: opt, pc: pc, lib: lib, func: func, headers: headers) ||
272
+ abort_could_not_find_library(lib)
273
+ end
109
274
 
110
- exit! 0
275
+ def ensure_func(func, headers = nil)
276
+ have_func(func, headers) || abort_could_not_find_library(func)
111
277
  end
112
278
 
113
- def package_config pkg, options={}
114
- package = pkg_config(pkg)
115
- return package if package
279
+ def preserving_globals
280
+ values = [$arg_config, $INCFLAGS, $CFLAGS, $CPPFLAGS, $LDFLAGS, $DLDFLAGS, $LIBPATH, $libs].map(&:dup)
281
+ yield
282
+ ensure
283
+ $arg_config, $INCFLAGS, $CFLAGS, $CPPFLAGS, $LDFLAGS, $DLDFLAGS, $LIBPATH, $libs = values
284
+ end
116
285
 
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)
286
+ def abort_could_not_find_library(lib)
287
+ abort("-----\n#{caller[0]}\n#{lib} is missing. Please locate mkmf.log to investigate how it is failing.\n-----")
288
+ end
125
289
 
126
- cflags = PKGConfig.cflags(pkg)
127
- ldflags = PKGConfig.libs_only_L(pkg)
128
- libs = PKGConfig.libs_only_l(pkg)
290
+ def chdir_for_build
291
+ # When using rake-compiler-dock on Windows, the underlying Virtualbox shared
292
+ # folders don't support symlinks, but libiconv expects it for a build on
293
+ # Linux. We work around this limitation by using the temp dir for cooking.
294
+ build_dir = ENV["RCD_HOST_RUBY_PLATFORM"].to_s =~ /mingw|mswin|cygwin/ ? "/tmp" : "."
295
+ Dir.chdir(build_dir) do
296
+ yield
297
+ end
298
+ end
129
299
 
130
- Logging::message "PKGConfig package configuration for %s\n", pkg
131
- Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n", cflags, ldflags, libs
300
+ def sh_export_path(path)
301
+ # because libxslt 1.1.29 configure.in uses AC_PATH_TOOL which treats ":"
302
+ # as a $PATH separator, we need to convert windows paths from
303
+ #
304
+ # C:/path/to/foo
305
+ #
306
+ # to
307
+ #
308
+ # /C/path/to/foo
309
+ #
310
+ # which is sh-compatible, in order to find things properly during
311
+ # configuration
312
+ return path unless windows?
132
313
 
133
- [cflags, ldflags, libs]
314
+ match = Regexp.new("^([A-Z]):(/.*)").match(path)
315
+ if match && match.length == 3
316
+ return File.join("/", match[1], match[2])
134
317
  end
135
- end
136
318
 
137
- def nokogiri_try_compile
138
- try_compile "int main() {return 0;}", "", {werror: true}
319
+ path
139
320
  end
140
321
 
141
- def check_libxml_version version=nil
142
- source = if version.nil?
143
- <<-SRC
144
- #include <libxml/xmlversion.h>
145
- SRC
146
- else
147
- 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
153
- SRC
154
- end
155
-
156
- try_cpp source
157
- end
158
-
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
322
+ def libflag_to_filename(ldflag)
323
+ case ldflag
324
+ when /\A-l(.+)/
325
+ "lib#{Regexp.last_match(1)}.#{$LIBEXT}"
169
326
  end
170
327
  end
171
328
 
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
329
+ def have_libxml_headers?(version = nil)
330
+ source = if version.nil?
331
+ <<~SRC
332
+ #include <libxml/xmlversion.h>
333
+ SRC
334
+ else
335
+ version_int = format("%d%2.2d%2.2d", *version.split("."))
336
+ <<~SRC
337
+ #include <libxml/xmlversion.h>
338
+ #if LIBXML_VERSION < #{version_int}
339
+ # error libxml2 is older than #{version}
340
+ #endif
341
+ SRC
342
+ end
185
343
 
186
- def asplode(lib)
187
- abort "-----\n#{lib} is missing. Please locate mkmf.log to investigate how it is failing.\n-----"
344
+ try_cpp(source)
188
345
  end
189
346
 
190
- def have_iconv?(using = nil)
191
- checking_for(using ? "iconv using #{using}" : 'iconv') do
192
- ['', '-liconv'].any? do |opt|
347
+ def try_link_iconv(using = nil)
348
+ checking_for(using ? "iconv using #{using}" : "iconv") do
349
+ ["", "-liconv"].any? do |opt|
193
350
  preserving_globals do
194
351
  yield if block_given?
195
352
 
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
- }
353
+ try_link(<<~'SRC', opt)
354
+ #include <stdlib.h>
355
+ #include <iconv.h>
356
+ int main(void)
357
+ {
358
+ iconv_t cd = iconv_open("", "");
359
+ iconv(cd, NULL, NULL, NULL, NULL);
360
+ return EXIT_SUCCESS;
361
+ }
206
362
  SRC
207
363
  end
208
364
  end
@@ -210,67 +366,63 @@ int main(void)
210
366
  end
211
367
 
212
368
  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) }
218
- idirs, ldirs = config.map do |dirs|
219
- Array(dirs).flat_map do |dir|
220
- dir.split(File::PATH_SEPARATOR)
221
- end if dirs
222
- end
223
-
224
- return [
225
- '--with-iconv=yes',
226
- *("CPPFLAGS=#{idirs.map { |dir| '-I' + dir }.join(' ')}" if idirs),
227
- *("LDFLAGS=#{ldirs.map { |dir| '-L' + dir }.join(' ')}" if ldirs),
228
- ]
369
+ # give --with-iconv-dir and --with-opt-dir first priority
370
+ ["iconv", "opt"].each do |target|
371
+ config = preserving_globals { dir_config(target) }
372
+ next unless config.any? && try_link_iconv("--with-#{target}-* flags") { dir_config(target) }
373
+ idirs, ldirs = config.map do |dirs|
374
+ Array(dirs).flat_map do |dir|
375
+ dir.split(File::PATH_SEPARATOR)
376
+ end if dirs
229
377
  end
378
+
379
+ return [
380
+ "--with-iconv=yes",
381
+ *("CPPFLAGS=#{idirs.map { |dir| "-I" + dir }.join(" ")}" if idirs),
382
+ *("LDFLAGS=#{ldirs.map { |dir| "-L" + dir }.join(" ")}" if ldirs),
383
+ ]
230
384
  end
231
385
 
232
- if have_iconv?
233
- return ['--with-iconv=yes']
386
+ if try_link_iconv
387
+ return ["--with-iconv=yes"]
234
388
  end
235
389
 
236
- if (config = preserving_globals { package_config('libiconv') }) &&
237
- have_iconv?('pkg-config libiconv') { package_config('libiconv') }
390
+ config = preserving_globals { have_package_configuration("libiconv") }
391
+ if config && try_link_iconv("pkg-config libiconv") { have_package_configuration("libiconv") }
238
392
  cflags, ldflags, libs = config
239
393
 
240
394
  return [
241
- '--with-iconv=yes',
395
+ "--with-iconv=yes",
242
396
  "CPPFLAGS=#{cflags}",
243
397
  "LDFLAGS=#{ldflags}",
244
398
  "LIBS=#{libs}",
245
399
  ]
246
400
  end
247
401
 
248
- asplode "libiconv"
402
+ abort_could_not_find_library("libiconv")
249
403
  end
250
404
 
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
405
+ def process_recipe(name, version, static_p, cross_p, cacheable_p=true)
406
+ require "rubygems"
407
+ gem("mini_portile2", REQUIRED_MINI_PORTILE_VERSION)
408
+ require "mini_portile2"
409
+ message("Using mini_portile version #{MiniPortile::VERSION}\n")
410
+
411
+ unless ["libxml2", "libxslt"].include?(name)
412
+ OTHER_LIBRARY_VERSIONS[name] = version
258
413
  end
259
- end
260
414
 
261
- def process_recipe(name, version, static_p, cross_p)
262
415
  MiniPortile.new(name, version).tap do |recipe|
263
- recipe.target = File.join(ROOT, "ports")
416
+ recipe.target = File.join(PACKAGE_ROOT_DIR, "ports") if cacheable_p
264
417
  # Prefer host_alias over host in order to use i586-mingw32msvc as
265
418
  # correct compiler prefix for cross build, but use host if not set.
266
419
  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
268
420
  recipe.configure_options << "--libdir=#{File.join(recipe.path, "lib")}"
269
421
 
270
422
  yield recipe
271
423
 
272
424
  env = Hash.new do |hash, key|
273
- hash[key] = "#{ENV[key]}" # (ENV[key].dup rescue '')
425
+ hash[key] = (ENV[key]).to_s
274
426
  end
275
427
 
276
428
  recipe.configure_options.flatten!
@@ -278,7 +430,11 @@ def process_recipe(name, version, static_p, cross_p)
278
430
  recipe.configure_options.delete_if do |option|
279
431
  case option
280
432
  when /\A(\w+)=(.*)\z/
281
- env[$1] = $2
433
+ env[Regexp.last_match(1)] = if env.key?(Regexp.last_match(1))
434
+ concat_flags(env[Regexp.last_match(1)], Regexp.last_match(2))
435
+ else
436
+ Regexp.last_match(2)
437
+ end
282
438
  true
283
439
  else
284
440
  false
@@ -290,7 +446,7 @@ def process_recipe(name, version, static_p, cross_p)
290
446
  "--disable-shared",
291
447
  "--enable-static",
292
448
  ]
293
- env['CFLAGS'] = "-fPIC #{env['CFLAGS']}"
449
+ env["CFLAGS"] = concat_flags(env["CFLAGS"], "-fPIC")
294
450
  else
295
451
  recipe.configure_options += [
296
452
  "--enable-shared",
@@ -305,333 +461,416 @@ def process_recipe(name, version, static_p, cross_p)
305
461
  ]
306
462
  end
307
463
 
308
- if RbConfig::CONFIG['target_cpu'] == 'universal'
464
+ if RbConfig::CONFIG["target_cpu"] == "universal"
309
465
  %w[CFLAGS LDFLAGS].each do |key|
310
- unless env[key].include?('-arch')
311
- env[key] += ' ' + RbConfig::CONFIG['ARCH_FLAG']
466
+ unless env[key].include?("-arch")
467
+ env[key] = concat_flags(env[key], RbConfig::CONFIG["ARCH_FLAG"])
312
468
  end
313
469
  end
314
470
  end
315
471
 
316
472
  recipe.configure_options += env.map do |key, value|
317
- "#{key}=#{value}"
473
+ "#{key}=#{value.strip}"
318
474
  end
319
475
 
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
476
+ checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
477
+ if File.exist?(checkpoint) && !recipe.source_directory
478
+ message("Building Nokogiri with a packaged version of #{name}-#{version}.\n")
479
+ else
480
+ message(<<~EOM)
481
+ ---------- IMPORTANT NOTICE ----------
482
+ Building Nokogiri with a packaged version of #{name}-#{version}.
483
+ Configuration options: #{recipe.configure_options.shelljoin}
484
+ EOM
326
485
 
327
- unless recipe.patch_files.empty?
328
- message "with the following patches applied:\n"
486
+ unless recipe.patch_files.empty?
487
+ message("The following patches are being applied:\n")
329
488
 
330
- recipe.patch_files.each do |patch|
331
- message "\t- %s\n" % File.basename(patch)
489
+ recipe.patch_files.each do |patch|
490
+ message(" - %s\n" % File.basename(patch))
491
+ end
332
492
  end
333
- end
334
-
335
- message <<-"EOS"
336
493
 
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:
494
+ message(<<~EOM) if name != "libgumbo"
341
495
 
342
- gem install nokogiri -- --use-system-libraries
343
- [--with-xml2-config=/path/to/xml2-config]
344
- [--with-xslt-config=/path/to/xslt-config]
496
+ The Nokogiri maintainers intend to provide timely security updates, but if
497
+ this is a concern for you and want to use your OS/distro system library
498
+ instead, then abort this installation process and install nokogiri as
499
+ instructed at:
345
500
 
346
- If you are using Bundler, tell it to use the option:
501
+ https://nokogiri.org/tutorials/installing_nokogiri.html#installing-using-standard-system-libraries
347
502
 
348
- bundle config build.nokogiri --use-system-libraries
349
- bundle install
350
- EOS
503
+ EOM
351
504
 
352
- message <<-"EOS" if name == 'libxml2'
505
+ message(<<~EOM) if name == "libxml2"
506
+ Note, however, that nokogiri cannot guarantee compatibility with every
507
+ version of libxml2 that may be provided by OS/package vendors.
353
508
 
354
- Note, however, that nokogiri is not fully compatible with arbitrary
355
- versions of libxml2 provided by OS/package vendors.
356
- EOS
509
+ EOM
357
510
 
358
- message <<-"EOS"
359
- ************************************************************************
360
- EOS
361
-
362
- checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
363
- unless File.exist?(checkpoint)
364
- chdir_for_build do
365
- recipe.cook
366
- end
367
- FileUtils.touch checkpoint
511
+ chdir_for_build { recipe.cook }
512
+ FileUtils.touch(checkpoint)
368
513
  end
369
514
  recipe.activate
370
515
  end
371
516
  end
372
517
 
373
- def lib_a(ldflag)
374
- case ldflag
375
- when /\A-l(.+)/
376
- "lib#{$1}.#{$LIBEXT}"
518
+ def copy_packaged_libraries_headers(to_path:, from_recipes:)
519
+ FileUtils.rm_rf(to_path, secure: true)
520
+ FileUtils.mkdir(to_path)
521
+ from_recipes.each do |recipe|
522
+ FileUtils.cp_r(Dir[File.join(recipe.path, "include/*")], to_path)
377
523
  end
378
524
  end
379
525
 
380
- def using_system_libraries?
381
- arg_config('--use-system-libraries', !!ENV['NOKOGIRI_USE_SYSTEM_LIBRARIES'])
526
+ def do_help
527
+ print(NOKOGIRI_HELP_MESSAGE)
528
+ exit!(0)
382
529
  end
383
530
 
384
- #
385
- # main
386
- #
531
+ def do_clean
532
+ root = Pathname(PACKAGE_ROOT_DIR)
533
+ pwd = Pathname(Dir.pwd)
387
534
 
388
- case
389
- when arg_config('--help')
390
- do_help
391
- when arg_config('--clean')
392
- do_clean
393
- end
535
+ # Skip if this is a development work tree
536
+ unless (root + ".git").exist?
537
+ message("Cleaning files only used during build.\n")
394
538
 
395
- if darwin?
396
- ENV['CFLAGS'] = "#{ENV['CFLAGS']} -I /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libxml2"
397
- end
539
+ # (root + 'tmp') cannot be removed at this stage because
540
+ # nokogiri.so is yet to be copied to lib.
398
541
 
399
- if openbsd? && !using_system_libraries?
400
- if `#{ENV['CC'] || '/usr/bin/cc'} -v 2>&1` !~ /clang/
401
- ENV['CC'] ||= find_executable('egcc') or
402
- abort "Please install gcc 4.9+ from ports using `pkg_add -v gcc`"
542
+ # clean the ports build directory
543
+ Pathname.glob(pwd.join("tmp", "*", "ports")) do |dir|
544
+ FileUtils.rm_rf(dir, verbose: true)
545
+ end
546
+
547
+ if config_static?
548
+ # ports installation can be safely removed if statically linked.
549
+ FileUtils.rm_rf(root + "ports", verbose: true)
550
+ else
551
+ FileUtils.rm_rf(root + "ports" + "archives", verbose: true)
552
+ end
403
553
  end
404
- ENV['CFLAGS'] = "#{ENV['CFLAGS']} -I /usr/local/include"
405
- end
406
554
 
407
- if ENV['CC']
408
- RbConfig::CONFIG['CC'] = RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC']
555
+ exit!(0)
409
556
  end
410
- # use same c compiler for libxml and libxslt
411
- ENV['CC'] = RbConfig::CONFIG['CC']
412
-
413
- $LIBS << " #{ENV["LIBS"]}"
414
557
 
415
- # Read CFLAGS from ENV and make sure compiling works.
416
- add_cflags(ENV["CFLAGS"])
558
+ #
559
+ # main
560
+ #
561
+ do_help if arg_config("--help")
562
+ do_clean if arg_config("--clean")
417
563
 
418
- if windows?
419
- $CFLAGS << " -DXP_WIN -DXP_WIN32 -DUSE_INCLUDED_VASPRINTF"
564
+ if openbsd? && !config_system_libraries?
565
+ if %x(#{ENV["CC"] || "/usr/bin/cc"} -v 2>&1) !~ /clang/
566
+ (ENV["CC"] ||= find_executable("egcc")) ||
567
+ abort("Please install gcc 4.9+ from ports using `pkg_add -v gcc`")
568
+ end
569
+ append_cppflags "-I/usr/local/include"
420
570
  end
421
571
 
422
- if solaris?
423
- $CFLAGS << " -DUSE_INCLUDED_VASPRINTF"
572
+ if ENV["CC"]
573
+ RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"]
424
574
  end
425
575
 
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
576
+ # use same c compiler for libxml and libxslt
577
+ ENV["CC"] = RbConfig::CONFIG["CC"]
430
578
 
431
- if nix?
432
- $CFLAGS << " -g -DXP_UNIX"
579
+ if arg_config("--prevent-strip")
580
+ old_cflags = $CFLAGS.split.join(" ")
581
+ old_ldflags = $LDFLAGS.split.join(" ")
582
+ old_dldflags = $DLDFLAGS.split.join(" ")
583
+ $CFLAGS = $CFLAGS.split.reject { |flag| flag == "-s" }.join(" ")
584
+ $LDFLAGS = $LDFLAGS.split.reject { |flag| flag == "-s" }.join(" ")
585
+ $DLDFLAGS = $DLDFLAGS.split.reject { |flag| flag == "-s" }.join(" ")
586
+ puts "Prevent stripping by removing '-s' from $CFLAGS" if old_cflags != $CFLAGS
587
+ puts "Prevent stripping by removing '-s' from $LDFLAGS" if old_ldflags != $LDFLAGS
588
+ puts "Prevent stripping by removing '-s' from $DLDFLAGS" if old_dldflags != $DLDFLAGS
433
589
  end
434
590
 
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
591
+ # adopt environment config
592
+ append_cflags(ENV["CFLAGS"].split) unless ENV["CFLAGS"].nil?
593
+ append_cppflags(ENV["CPPFLAGS"].split) unless ENV["CPPFLAGS"].nil?
594
+ append_ldflags(ENV["LDFLAGS"].split) unless ENV["LDFLAGS"].nil?
595
+ $LIBS = concat_flags($LIBS, ENV["LIBS"])
440
596
 
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
597
+ # always include debugging information
598
+ append_cflags("-g")
445
599
 
446
- case
447
- when using_system_libraries?
448
- message "Building nokogiri using system libraries.\n"
600
+ # we use at least one inline function in the C extension
601
+ append_cflags("-Winline")
449
602
 
450
- dir_config('zlib')
603
+ # good to have no matter what Ruby was compiled with
604
+ append_cflags("-Wmissing-noreturn")
451
605
 
452
- # Using system libraries means we rely on the system libxml2 with
453
- # regard to the iconv support.
606
+ # handle clang variations, see #1101
607
+ append_cflags("-Wno-error=unused-command-line-argument-hard-error-in-future") if darwin?
454
608
 
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')
609
+ # these tend to be noisy, but on occasion useful during development
610
+ # append_cflags(["-Wcast-qual", "-Wwrite-strings"])
458
611
 
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."
612
+ # Add SDK-specific include path for macOS and brew versions before v2.2.12 (2020-04-08) [#1851, #1801]
613
+ macos_mojave_sdk_include_path = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libxml2"
614
+ if config_system_libraries? && darwin? && Dir.exist?(macos_mojave_sdk_include_path)
615
+ append_cppflags("-I#{macos_mojave_sdk_include_path}")
616
+ end
617
+
618
+ # Work around a character escaping bug in MSYS by passing an arbitrary double-quoted parameter to gcc.
619
+ # See https://sourceforge.net/p/mingw/bugs/2142
620
+ append_cppflags(' "-Idummypath"') if windows?
621
+
622
+ if config_system_libraries?
623
+ message "Building nokogiri using system libraries.\n"
624
+ ensure_package_configuration(opt: "zlib", pc: "zlib", lib: "z",
625
+ headers: "zlib.h", func: "gzdopen")
626
+ ensure_package_configuration(opt: "xml2", pc: "libxml-2.0", lib: "xml2",
627
+ headers: "libxml/parser.h", func: "xmlParseDoc")
628
+ ensure_package_configuration(opt: "xslt", pc: "libxslt", lib: "xslt",
629
+ headers: "libxslt/xslt.h", func: "xsltParseStylesheetDoc")
630
+ ensure_package_configuration(opt: "exslt", pc: "libexslt", lib: "exslt",
631
+ headers: "libexslt/exslt.h", func: "exsltFuncRegister")
632
+
633
+ have_libxml_headers?(REQUIRED_LIBXML_VERSION) ||
634
+ abort("ERROR: libxml2 version #{REQUIRED_LIBXML_VERSION} or later is required!")
635
+ have_libxml_headers?(RECOMMENDED_LIBXML_VERSION) ||
636
+ warn("WARNING: libxml2 version #{RECOMMENDED_LIBXML_VERSION} or later is highly recommended, but proceeding anyway.")
462
637
 
463
638
  else
464
639
  message "Building nokogiri using packaged libraries.\n"
465
640
 
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"
472
-
473
- require 'yaml'
641
+ static_p = config_static?
642
+ message "Static linking is #{static_p ? "enabled" : "disabled"}.\n"
474
643
 
475
- static_p = enable_config('static', true) or
476
- message "Static linking is disabled.\n"
644
+ cross_build_p = config_cross_build?
645
+ message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n"
477
646
 
478
- dir_config('zlib')
647
+ require "yaml"
648
+ dependencies = YAML.load_file(File.join(PACKAGE_ROOT_DIR, "dependencies.yml"))
479
649
 
480
- dependencies = YAML.load_file(File.join(ROOT, "dependencies.yml"))
650
+ dir_config("zlib")
481
651
 
482
- cross_build_p = enable_config("cross-build")
483
652
  if cross_build_p || windows?
484
653
  zlib_recipe = process_recipe("zlib", dependencies["zlib"]["version"], static_p, cross_build_p) do |recipe|
485
654
  recipe.files = [{
486
- url: "http://zlib.net/fossils/#{recipe.name}-#{recipe.version}.tar.gz",
487
- sha256: dependencies["zlib"]["sha256"]
488
- }]
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
655
+ url: "http://zlib.net/fossils/#{recipe.name}-#{recipe.version}.tar.gz",
656
+ sha256: dependencies["zlib"]["sha256"],
657
+ }]
658
+ if windows?
659
+ class << recipe
660
+ attr_accessor :cross_build_p
661
+
662
+ def configure
663
+ Dir.chdir(work_path) do
664
+ mk = File.read("win32/Makefile.gcc")
665
+ File.open("win32/Makefile.gcc", "wb") do |f|
666
+ f.puts "BINARY_PATH = #{path}/bin"
667
+ f.puts "LIBRARY_PATH = #{path}/lib"
668
+ f.puts "INCLUDE_PATH = #{path}/include"
669
+ mk.sub!(/^PREFIX\s*=\s*$/, "PREFIX = #{host}-") if cross_build_p
670
+ f.puts mk
671
+ end
672
+ end
673
+ end
674
+
675
+ def configured?
676
+ Dir.chdir(work_path) do
677
+ !!(File.read("win32/Makefile.gcc") =~ /^BINARY_PATH/)
501
678
  end
502
679
  end
503
- end
504
680
 
505
- def configured?
506
- Dir.chdir work_path do
507
- !! (File.read('win32/Makefile.gcc') =~ /^BINARY_PATH/)
681
+ def compile
682
+ execute("compile", "make -f win32/Makefile.gcc")
508
683
  end
509
- end
510
684
 
511
- def compile
512
- execute "compile", "make -f win32/Makefile.gcc"
685
+ def install
686
+ execute("install", "make -f win32/Makefile.gcc install")
687
+ end
513
688
  end
689
+ recipe.cross_build_p = cross_build_p
690
+ else
691
+ class << recipe
692
+ def configure
693
+ cflags = concat_flags(ENV["CFLAGS"], "-fPIC", "-g")
694
+ execute("configure",
695
+ ["env", "CHOST=#{host}", "CFLAGS=#{cflags}", "./configure", "--static", configure_prefix])
696
+ end
514
697
 
515
- def install
516
- execute "install", "make -f win32/Makefile.gcc install"
698
+ def compile
699
+ if host =~ /darwin/
700
+ execute("compile", "make AR=#{host}-libtool")
701
+ else
702
+ super
703
+ end
704
+ end
517
705
  end
518
706
  end
519
- recipe.cross_build_p = cross_build_p
520
707
  end
521
708
 
522
- libiconv_recipe = process_recipe("libiconv", dependencies["libiconv"]["version"], static_p, cross_build_p) do |recipe|
523
- recipe.files = [{
709
+ unless nix?
710
+ libiconv_recipe = process_recipe("libiconv", dependencies["libiconv"]["version"], static_p,
711
+ cross_build_p) do |recipe|
712
+ recipe.files = [{
524
713
  url: "http://ftp.gnu.org/pub/gnu/libiconv/#{recipe.name}-#{recipe.version}.tar.gz",
525
- sha256: dependencies["libiconv"]["sha256"]
714
+ sha256: dependencies["libiconv"]["sha256"],
526
715
  }]
527
- recipe.configure_options += [
528
- "CPPFLAGS=-Wall",
529
- "CFLAGS=-O2 -g",
530
- "CXXFLAGS=-O2 -g",
531
- "LDFLAGS="
532
- ]
533
- end
534
- else
535
- 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
716
+
717
+ cflags = concat_flags(ENV["CFLAGS"], "-O2", "-U_FORTIFY_SOURCE", "-g")
718
+
719
+ recipe.configure_options += [
720
+ "--disable-dependency-tracking",
721
+ "CPPFLAGS=-Wall",
722
+ "CFLAGS=#{cflags}",
723
+ "CXXFLAGS=#{cflags}",
724
+ "LDFLAGS=",
725
+ ]
726
+ end
548
727
  end
728
+ elsif darwin? && !have_header("iconv.h")
729
+ abort(<<~EOM.chomp)
730
+ -----
731
+ The file "iconv.h" is missing in your build environment,
732
+ which means you haven't installed Xcode Command Line Tools properly.
733
+
734
+ To install Command Line Tools, try running `xcode-select --install` on
735
+ terminal and follow the instructions. If it fails, open Xcode.app,
736
+ select from the menu "Xcode" - "Open Developer Tool" - "More Developer
737
+ Tools" to open the developer site, download the installer for your OS
738
+ version and run it.
739
+ -----
740
+ EOM
549
741
  end
550
742
 
551
743
  unless windows?
552
- preserving_globals {
553
- have_library('z', 'gzdopen', 'zlib.h')
554
- } or abort 'zlib is missing; necessary for building libxml2'
744
+ preserving_globals { local_have_library("z", "gzdopen", "zlib.h") } ||
745
+ abort("zlib is missing; necessary for building libxml2")
555
746
  end
556
747
 
557
748
  libxml2_recipe = process_recipe("libxml2", dependencies["libxml2"]["version"], static_p, cross_build_p) do |recipe|
558
- recipe.files = [{
749
+ source_dir = arg_config("--with-xml2-source-dir")
750
+ if source_dir
751
+ recipe.source_directory = source_dir
752
+ else
753
+ recipe.files = [{
559
754
  url: "http://xmlsoft.org/sources/#{recipe.name}-#{recipe.version}.tar.gz",
560
- sha256: dependencies["libxml2"]["sha256"]
755
+ sha256: dependencies["libxml2"]["sha256"],
561
756
  }]
757
+ recipe.patch_files = Dir[File.join(PACKAGE_ROOT_DIR, "patches", "libxml2", "*.patch")].sort
758
+ end
759
+
760
+ cflags = concat_flags(ENV["CFLAGS"], "-O2", "-U_FORTIFY_SOURCE", "-g")
761
+
762
+ if zlib_recipe
763
+ recipe.configure_options << "--with-zlib=#{zlib_recipe.path}"
764
+ cflags = concat_flags(cflags, "-I#{zlib_recipe.path}/include")
765
+ end
766
+
767
+ if libiconv_recipe
768
+ recipe.configure_options << "--with-iconv=#{libiconv_recipe.path}"
769
+ else
770
+ recipe.configure_options += iconv_configure_flags
771
+ end
772
+
773
+ if darwin? && !cross_build_p
774
+ recipe.configure_options += ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"]
775
+ end
776
+
777
+ if windows?
778
+ cflags = concat_flags(cflags, "-ULIBXML_STATIC", "-DIN_LIBXML")
779
+ end
780
+
781
+ recipe.configure_options << if source_dir
782
+ "--config-cache"
783
+ else
784
+ "--disable-dependency-tracking"
785
+ end
786
+
562
787
  recipe.configure_options += [
563
788
  "--without-python",
564
789
  "--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
790
  "--with-c14n",
568
791
  "--with-debug",
569
792
  "--with-threads",
570
- *(darwin? ? ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"] : "")
793
+ "CFLAGS=#{cflags}",
571
794
  ]
572
795
  end
573
796
 
574
797
  libxslt_recipe = process_recipe("libxslt", dependencies["libxslt"]["version"], static_p, cross_build_p) do |recipe|
575
- recipe.files = [{
798
+ source_dir = arg_config("--with-xslt-source-dir")
799
+ if source_dir
800
+ recipe.source_directory = source_dir
801
+ else
802
+ recipe.files = [{
576
803
  url: "http://xmlsoft.org/sources/#{recipe.name}-#{recipe.version}.tar.gz",
577
- sha256: dependencies["libxslt"]["sha256"]
804
+ sha256: dependencies["libxslt"]["sha256"],
578
805
  }]
806
+ recipe.patch_files = Dir[File.join(PACKAGE_ROOT_DIR, "patches", "libxslt", "*.patch")].sort
807
+ end
808
+
809
+ cflags = concat_flags(ENV["CFLAGS"], "-O2", "-U_FORTIFY_SOURCE", "-g")
810
+
811
+ if darwin? && !cross_build_p
812
+ recipe.configure_options += ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"]
813
+ end
814
+
815
+ recipe.configure_options << if source_dir
816
+ "--config-cache"
817
+ else
818
+ "--disable-dependency-tracking"
819
+ end
820
+
579
821
  recipe.configure_options += [
580
822
  "--without-python",
581
823
  "--without-crypto",
582
824
  "--with-debug",
583
825
  "--with-libxml-prefix=#{sh_export_path(libxml2_recipe.path)}",
584
- *(darwin? ? ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"] : "")
826
+ "CFLAGS=#{cflags}",
585
827
  ]
586
828
  end
587
829
 
588
- $CFLAGS << ' ' << '-DNOKOGIRI_USE_PACKAGED_LIBRARIES'
830
+ append_cppflags("-DNOKOGIRI_PACKAGED_LIBRARIES")
831
+ append_cppflags("-DNOKOGIRI_PRECOMPILED_LIBRARIES") if cross_build_p
832
+
589
833
  $LIBPATH = ["#{zlib_recipe.path}/lib"] | $LIBPATH if zlib_recipe
590
834
  $LIBPATH = ["#{libiconv_recipe.path}/lib"] | $LIBPATH if libiconv_recipe
591
835
 
592
- have_lzma = preserving_globals {
593
- have_library('lzma')
594
- }
595
-
596
836
  $libs = $libs.shellsplit.tap do |libs|
597
837
  [libxml2_recipe, libxslt_recipe].each do |recipe|
598
838
  libname = recipe.name[/\Alib(.+)\z/, 1]
599
839
  File.join(recipe.path, "bin", "#{libname}-config").tap do |config|
600
840
  # call config scripts explicit with 'sh' for compat with Windows
601
- $CPPFLAGS = `sh #{config} --cflags`.strip << ' ' << $CPPFLAGS
602
- `sh #{config} --libs`.strip.shellsplit.each do |arg|
841
+ $CPPFLAGS = %x(sh #{config} --cflags).strip << " " << $CPPFLAGS
842
+ %x(sh #{config} --libs).strip.shellsplit.each do |arg|
603
843
  case arg
604
844
  when /\A-L(.+)\z/
605
845
  # Prioritize ports' directories
606
- if $1.start_with?(ROOT + '/')
607
- $LIBPATH = [$1] | $LIBPATH
846
+ $LIBPATH = if Regexp.last_match(1).start_with?(PACKAGE_ROOT_DIR + "/")
847
+ [Regexp.last_match(1)] | $LIBPATH
608
848
  else
609
- $LIBPATH = $LIBPATH | [$1]
849
+ $LIBPATH | [Regexp.last_match(1)]
610
850
  end
611
851
  when /\A-l./
612
852
  libs.unshift(arg)
613
853
  else
614
- $LDFLAGS << ' ' << arg.shellescape
854
+ $LDFLAGS << " " << arg.shellescape
615
855
  end
616
856
  end
617
857
  end
618
858
 
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
859
+ patches_string = recipe.patch_files.map { |path| File.basename(path) }.join(" ")
860
+ append_cppflags(%[-DNOKOGIRI_#{recipe.name.upcase}_PATCHES="\\\"#{patches_string}\\\""])
622
861
 
623
862
  case libname
624
- when 'xml2'
863
+ when "xml2"
625
864
  # xslt-config --libs or pkg-config libxslt --libs does not include
626
865
  # -llzma, so we need to add it manually when linking statically.
627
- if static_p && have_lzma
866
+ if static_p && preserving_globals { local_have_library("lzma") }
628
867
  # Add it at the end; GH #988
629
- libs << '-llzma'
868
+ libs << "-llzma"
630
869
  end
631
- when 'xslt'
870
+ when "xslt"
632
871
  # xslt-config does not have a flag to emit options including
633
872
  # -lexslt, so add it manually.
634
- libs.unshift('-lexslt')
873
+ libs.unshift("-lexslt")
635
874
  end
636
875
  end
637
876
  end.shelljoin
@@ -639,48 +878,107 @@ EOM
639
878
  if static_p
640
879
  $libs = $libs.shellsplit.map do |arg|
641
880
  case arg
642
- when '-lxml2'
643
- File.join(libxml2_recipe.path, 'lib', lib_a(arg))
644
- when '-lxslt', '-lexslt'
645
- File.join(libxslt_recipe.path, 'lib', lib_a(arg))
881
+ when "-lxml2"
882
+ File.join(libxml2_recipe.path, "lib", libflag_to_filename(arg))
883
+ when "-lxslt", "-lexslt"
884
+ File.join(libxslt_recipe.path, "lib", libflag_to_filename(arg))
646
885
  else
647
886
  arg
648
887
  end
649
888
  end.shelljoin
650
889
  end
651
- end
652
890
 
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}")
891
+ ensure_func("xmlParseDoc", "libxml/parser.h")
892
+ ensure_func("xsltParseStylesheetDoc", "libxslt/xslt.h")
893
+ ensure_func("exsltFuncRegister", "libexslt/exslt.h")
662
894
  end
663
895
 
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')
896
+ libgumbo_recipe = process_recipe("libgumbo", "1.0.0-nokogiri", static_p, cross_build_p, false) do |recipe|
897
+ recipe.configure_options = []
898
+
899
+ class << recipe
900
+ def downloaded?
901
+ true
902
+ end
671
903
 
672
- create_makefile('nokogiri/nokogiri')
904
+ def extract
905
+ target = File.join(tmp_path, "gumbo-parser")
906
+ output("Copying gumbo-parser files into #{target}...")
907
+ FileUtils.mkdir_p(target)
908
+ FileUtils.cp(Dir.glob(File.join(PACKAGE_ROOT_DIR, "gumbo-parser/src/*")), target)
909
+ end
673
910
 
674
- if enable_config('clean', true)
675
- # Do not clean if run in a development work tree.
676
- File.open('Makefile', 'at') do |mk|
677
- mk.print <<EOF
678
- all: clean-ports
911
+ def configured?
912
+ true
913
+ end
914
+
915
+ def install
916
+ lib_dir = File.join(port_path, "lib")
917
+ inc_dir = File.join(port_path, "include")
918
+ FileUtils.mkdir_p([lib_dir, inc_dir])
919
+ FileUtils.cp(File.join(work_path, "libgumbo.a"), lib_dir)
920
+ FileUtils.cp(Dir.glob(File.join(work_path, "*.h")), inc_dir)
921
+ end
922
+
923
+ def compile
924
+ cflags = concat_flags(ENV["CFLAGS"], "-fPIC", "-g")
679
925
 
680
- clean-ports: $(DLLIB)
681
- -$(Q)$(RUBY) $(srcdir)/extconf.rb --clean --#{static_p ? 'enable' : 'disable'}-static
682
- EOF
926
+ env = { "CC" => gcc_cmd, "CFLAGS" => cflags }
927
+ if config_cross_build?
928
+ if host =~ /darwin/
929
+ env["AR"] = "#{host}-libtool"
930
+ env["ARFLAGS"] = "-o"
931
+ else
932
+ env["AR"] = "#{host}-ar"
933
+ end
934
+ env["RANLIB"] = "#{host}-ranlib"
935
+ end
936
+
937
+ execute("compile", make_cmd, { env: env })
938
+ end
683
939
  end
684
940
  end
941
+ append_cppflags("-I#{File.join(libgumbo_recipe.path, "include")}")
942
+ $libs = $libs + " " + File.join(libgumbo_recipe.path, "lib", "libgumbo.a")
943
+ $LIBPATH = $LIBPATH | [File.join(libgumbo_recipe.path, "lib")]
944
+ ensure_func("gumbo_parse_with_options", "gumbo.h")
945
+
946
+ have_func("xmlHasFeature") || abort("xmlHasFeature() is missing.") # introduced in libxml 2.6.21
947
+ have_func("xmlFirstElementChild") # introduced in libxml 2.7.3
948
+ have_func("xmlRelaxNGSetParserStructuredErrors") # introduced in libxml 2.6.24
949
+ have_func("xmlRelaxNGSetValidStructuredErrors") # introduced in libxml 2.6.21
950
+ have_func("xmlSchemaSetValidStructuredErrors") # introduced in libxml 2.6.23
951
+ have_func("xmlSchemaSetParserStructuredErrors") # introduced in libxml 2.6.23
952
+
953
+ have_func("vasprintf")
954
+
955
+ other_library_versions_string = OTHER_LIBRARY_VERSIONS.map { |k, v| [k, v].join(":") }.join(",")
956
+ append_cppflags(%[-DNOKOGIRI_OTHER_LIBRARY_VERSIONS="\\\"#{other_library_versions_string}\\\""])
957
+
958
+ unless config_system_libraries?
959
+ if cross_build_p
960
+ # When precompiling native gems, copy packaged libraries' headers to ext/nokogiri/include
961
+ # These are packaged up by the cross-compiling callback in the ExtensionTask
962
+ copy_packaged_libraries_headers(to_path: File.join(PACKAGE_ROOT_DIR, "ext/nokogiri/include"),
963
+ from_recipes: [libxml2_recipe, libxslt_recipe])
964
+ else
965
+ # When compiling during installation, install packaged libraries' header files into ext/nokogiri/include
966
+ copy_packaged_libraries_headers(to_path: "include",
967
+ from_recipes: [libxml2_recipe, libxslt_recipe])
968
+ $INSTALLFILES << ["include/**/*.h", "$(rubylibdir)"]
969
+ end
970
+ end
971
+
972
+ create_makefile("nokogiri/nokogiri")
685
973
 
686
- # :startdoc:
974
+ if config_clean?
975
+ # Do not clean if run in a development work tree.
976
+ File.open("Makefile", "at") do |mk|
977
+ mk.print(<<~EOF)
978
+
979
+ all: clean-ports
980
+ clean-ports: $(DLLIB)
981
+ \t-$(Q)$(RUBY) $(srcdir)/extconf.rb --clean --#{static_p ? "enable" : "disable"}-static
982
+ EOF
983
+ end
984
+ end