nokogiri 1.10.10 → 1.12.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

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