nokogiri 1.5.10 → 1.12.5

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