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