nokogiri 1.13.0-x64-mingw-ucrt

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