nokogiri 1.10.10 → 1.14.3-aarch64-linux

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