nokogiri 1.5.10 → 1.13.0

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