nokogiri 1.6.1 → 1.6.2.rc1

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 (93) hide show
  1. checksums.yaml +7 -7
  2. data/.editorconfig +17 -0
  3. data/.travis.yml +4 -6
  4. data/CHANGELOG.ja.rdoc +37 -8
  5. data/CHANGELOG.rdoc +48 -3
  6. data/Gemfile +3 -3
  7. data/Manifest.txt +57 -1
  8. data/README.ja.rdoc +22 -16
  9. data/README.rdoc +24 -19
  10. data/ROADMAP.md +1 -2
  11. data/Rakefile +161 -58
  12. data/build_all +56 -31
  13. data/dependencies.yml +3 -3
  14. data/ext/nokogiri/extconf.rb +379 -121
  15. data/ext/nokogiri/html_document.c +2 -2
  16. data/ext/nokogiri/nokogiri.c +6 -1
  17. data/ext/nokogiri/xml_document.c +5 -4
  18. data/ext/nokogiri/xml_node.c +11 -4
  19. data/ext/nokogiri/xml_reader.c +1 -1
  20. data/ext/nokogiri/xml_sax_parser_context.c +40 -0
  21. data/ext/nokogiri/xml_syntax_error.c +10 -5
  22. data/ext/nokogiri/xml_syntax_error.h +1 -1
  23. data/ext/nokogiri/xml_xpath_context.c +2 -14
  24. data/ext/nokogiri/xslt_stylesheet.c +1 -1
  25. data/lib/nokogiri.rb +31 -22
  26. data/lib/nokogiri/css/node.rb +0 -50
  27. data/lib/nokogiri/css/parser.rb +213 -218
  28. data/lib/nokogiri/css/parser.y +21 -30
  29. data/lib/nokogiri/css/xpath_visitor.rb +62 -14
  30. data/lib/nokogiri/html/document.rb +97 -18
  31. data/lib/nokogiri/html/sax/parser.rb +2 -2
  32. data/lib/nokogiri/version.rb +1 -1
  33. data/lib/nokogiri/xml/builder.rb +1 -1
  34. data/lib/nokogiri/xml/document.rb +2 -2
  35. data/lib/nokogiri/xml/dtd.rb +10 -0
  36. data/lib/nokogiri/xml/node.rb +26 -1
  37. data/lib/nokogiri/xml/sax/parser.rb +1 -1
  38. data/ports/archives/libxslt-1.1.28.tar.gz +0 -0
  39. data/ports/patches/libxml2/0001-Fix-parser-local-buffers-size-problems.patch +265 -0
  40. data/ports/patches/libxml2/0002-Fix-entities-local-buffers-size-problems.patch +102 -0
  41. data/ports/patches/libxml2/0003-Fix-an-error-in-previous-commit.patch +26 -0
  42. data/ports/patches/libxml2/0004-Fix-potential-out-of-bound-access.patch +26 -0
  43. data/ports/patches/libxml2/0005-Detect-excessive-entities-expansion-upon-replacement.patch +158 -0
  44. data/ports/patches/libxml2/0006-Do-not-fetch-external-parsed-entities.patch +78 -0
  45. data/ports/patches/libxml2/0007-Enforce-XML_PARSER_EOF-state-handling-through-the-pa.patch +480 -0
  46. data/ports/patches/libxml2/0008-Improve-handling-of-xmlStopParser.patch +315 -0
  47. data/ports/patches/libxml2/0009-Fix-a-couple-of-return-without-value.patch +37 -0
  48. data/ports/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch +222 -0
  49. data/ports/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch +53 -0
  50. data/ports/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch +60 -0
  51. data/ports/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch +42 -0
  52. data/ports/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch +164 -0
  53. data/ports/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch +587 -0
  54. data/ports/patches/libxslt/0008-Fix-direct-pattern-matching.patch +80 -0
  55. data/ports/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch +185 -0
  56. data/ports/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch +126 -0
  57. data/ports/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch +25 -0
  58. data/ports/patches/libxslt/0014-Fix-for-bug-436589.patch +43 -0
  59. data/ports/patches/libxslt/0015-Fix-mkdir-for-mingw.patch +41 -0
  60. data/suppressions/README.txt +1 -0
  61. data/suppressions/nokogiri_ree-1.8.7.358.supp +61 -0
  62. data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
  63. data/suppressions/nokogiri_ruby-1.9.2.320.supp +28 -0
  64. data/suppressions/nokogiri_ruby-1.9.3.327.supp +28 -0
  65. data/test/css/test_nthiness.rb +65 -2
  66. data/test/css/test_parser.rb +27 -10
  67. data/test/css/test_tokenizer.rb +1 -1
  68. data/test/css/test_xpath_visitor.rb +6 -1
  69. data/test/files/atom.xml +344 -0
  70. data/test/files/shift_jis_no_charset.html +9 -0
  71. data/test/helper.rb +10 -0
  72. data/test/html/test_document.rb +74 -7
  73. data/test/html/test_document_encoding.rb +10 -0
  74. data/test/html/test_document_fragment.rb +3 -3
  75. data/test/namespaces/test_namespaces_in_cloned_doc.rb +31 -0
  76. data/test/test_nokogiri.rb +6 -0
  77. data/test/test_reader.rb +7 -4
  78. data/test/test_xslt_transforms.rb +25 -0
  79. data/test/xml/sax/test_parser.rb +16 -0
  80. data/test/xml/sax/test_parser_context.rb +9 -0
  81. data/test/xml/test_builder.rb +9 -0
  82. data/test/xml/test_c14n.rb +12 -2
  83. data/test/xml/test_document.rb +66 -0
  84. data/test/xml/test_document_fragment.rb +5 -0
  85. data/test/xml/test_dtd.rb +84 -0
  86. data/test/xml/test_entity_reference.rb +3 -3
  87. data/test/xml/test_node.rb +21 -3
  88. data/test/xml/test_node_attributes.rb +17 -0
  89. data/test/xml/test_schema.rb +26 -0
  90. data/test/xml/test_xpath.rb +81 -0
  91. metadata +254 -174
  92. data/ports/archives/libxslt-1.1.26.tar.gz +0 -0
  93. data/tasks/cross_compile.rb +0 -134
@@ -1,4 +1,4 @@
1
1
  libxml2: "2.8.0"
2
- libxslt: "1.1.26"
3
- zlib: "1.2.7"
4
- libiconv: "1.13.1"
2
+ libxslt: "1.1.28"
3
+ zlib: "1.2.8"
4
+ libiconv: "1.14"
@@ -1,15 +1,74 @@
1
1
  ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
2
2
 
3
+ # Available options:
4
+ #
5
+ # --enable-clean (default)
6
+ # --disable-clean
7
+ #
8
+ # --enable-static (default)
9
+ # --disable-static
10
+ #
11
+ # --with-iconv-dir=DIR
12
+ #
13
+ # --with-zlib-dir=DIR
14
+ #
15
+ # --use-system-libraries
16
+ # --with-xml2-dir=DIR / --with-xml2-config=CONFIG
17
+ # --with-xslt-dir=DIR / --with-xslt-config=CONFIG
18
+ # --with-exslt-dir=DIR / --with-exslt-config=CONFIG
19
+ #
20
+ # --enable-cross-build
21
+
3
22
  # :stopdoc:
4
23
 
5
24
  require 'mkmf'
6
25
 
26
+ def message!(important_message)
27
+ message important_message
28
+ if !$stdout.tty? && File.chardev?('/dev/tty')
29
+ File.open('/dev/tty', 'w') { |tty|
30
+ tty.print important_message
31
+ }
32
+ end
33
+ end
34
+
7
35
  RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
8
36
 
9
37
  ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
10
- LIBDIR = RbConfig::CONFIG['libdir']
11
- @libdir_basename = "lib" # shrug, ruby 2.0 won't work for me.
12
- INCLUDEDIR = RbConfig::CONFIG['includedir']
38
+ # Workaround for Ruby bug #8074, introduced in Ruby 2.0.0, fixed in Ruby 2.1.0
39
+ # https://bugs.ruby-lang.org/issues/8074
40
+ @libdir_basename = "lib"
41
+
42
+ if arg_config('--clean')
43
+ require 'pathname'
44
+ require 'fileutils'
45
+
46
+ root = Pathname(ROOT)
47
+ pwd = Pathname(Dir.pwd)
48
+
49
+ # Skip if this is a development work tree
50
+ unless (root + '.git').exist?
51
+ message "Cleaning files only used during build.\n"
52
+
53
+ # (root + 'tmp') cannot be removed at this stage because
54
+ # nokogiri.so is yet to be copied to lib.
55
+
56
+ # clean the ports build directory
57
+ Pathname.glob(pwd.join('tmp', '*', 'ports')) { |dir|
58
+ FileUtils.rm_rf(dir, verbose: true)
59
+ FileUtils.rmdir(dir.parent, parents: true, verbose: true)
60
+ }
61
+
62
+ if enable_config('static')
63
+ # ports installation can be safely removed if statically linked.
64
+ FileUtils.rm_rf(root + 'ports', verbose: true)
65
+ else
66
+ FileUtils.rm_rf(root + 'ports' + 'archives', verbose: true)
67
+ end
68
+ end
69
+
70
+ exit
71
+ end
13
72
 
14
73
  if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'macruby'
15
74
  $LIBRUBYARG_STATIC.gsub!(/-static/, '')
@@ -18,158 +77,345 @@ end
18
77
  $CFLAGS << " #{ENV["CFLAGS"]}"
19
78
  $LIBS << " #{ENV["LIBS"]}"
20
79
 
21
- windows_p = RbConfig::CONFIG['target_os'] == 'mingw32' || RbConfig::CONFIG['target_os'] =~ /mswin/
22
-
23
- if windows_p
24
- $CFLAGS << " -DXP_WIN -DXP_WIN32 -DUSE_INCLUDED_VASPRINTF"
25
- elsif RbConfig::CONFIG['target_os'] =~ /solaris/
26
- $CFLAGS << " -DUSE_INCLUDED_VASPRINTF"
27
- else
28
- $CFLAGS << " -g -DXP_UNIX"
80
+ def preserving_globals
81
+ values = [
82
+ $arg_config,
83
+ $CFLAGS, $CPPFLAGS,
84
+ $LDFLAGS, $LIBPATH, $libs
85
+ ].map(&:dup)
86
+ yield
87
+ ensure
88
+ $arg_config,
89
+ $CFLAGS, $CPPFLAGS,
90
+ $LDFLAGS, $LIBPATH, $libs =
91
+ values
29
92
  end
30
93
 
31
- if RbConfig::MAKEFILE_CONFIG['CC'] =~ /mingw/
32
- $CFLAGS << " -DIN_LIBXML"
33
- $LIBS << " -lz" # TODO why is this necessary?
94
+ def asplode(lib)
95
+ abort "-----\n#{lib} is missing. please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.\n-----"
34
96
  end
35
97
 
36
- if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
37
- $CFLAGS << " -O3" unless $CFLAGS[/-O\d/]
38
- $CFLAGS << " -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline"
98
+ def have_iconv?
99
+ have_header('iconv.h') or return false
100
+ %w{ iconv_open libiconv_open }.any? do |method|
101
+ have_func(method, 'iconv.h') or
102
+ have_library('iconv', method, 'iconv.h')
103
+ end
39
104
  end
40
105
 
41
- if windows_p
42
- # I'm cross compiling!
43
- HEADER_DIRS = [INCLUDEDIR]
44
- LIB_DIRS = [LIBDIR]
45
- XML2_HEADER_DIRS = [File.join(INCLUDEDIR, "libxml2"), INCLUDEDIR]
46
-
47
- else
48
- if ENV['NOKOGIRI_USE_SYSTEM_LIBRARIES']
49
- HEADER_DIRS = [
50
- # First search /opt/local for macports
51
- '/opt/local/include',
106
+ def each_iconv_idir
107
+ # If --with-iconv-dir or --with-opt-dir is given, it should be
108
+ # the first priority
109
+ %w[iconv opt].each { |config|
110
+ idir = preserving_globals {
111
+ dir_config(config)
112
+ }.first and yield idir
113
+ }
114
+
115
+ # Try the system default
116
+ yield "/usr/include"
117
+
118
+ cflags, = preserving_globals {
119
+ pkg_config('libiconv')
120
+ }
121
+ if cflags
122
+ cflags.shellsplit.each { |arg|
123
+ arg.sub!(/\A-I/, '') and
124
+ yield arg
125
+ }
126
+ end
52
127
 
53
- # Then search /usr/local for people that installed from source
54
- '/usr/local/include',
128
+ nil
129
+ end
55
130
 
56
- # Check the ruby install locations
57
- INCLUDEDIR,
131
+ def iconv_prefix
132
+ # Make sure libxml2 is built with iconv
133
+ each_iconv_idir { |idir|
134
+ prefix = %r{\A(.+)?/include\z} === idir && $1 or next
135
+ File.exist?(File.join(idir, 'iconv.h')) or next
136
+ preserving_globals {
137
+ # Follow the way libxml2's configure uses a value given with
138
+ # --with-iconv[=DIR]
139
+ $CPPFLAGS = "-I#{idir} " << $CPPFLAGS
140
+ $LIBPATH.unshift(File.join(prefix, "lib"))
141
+ have_iconv?
142
+ } and break prefix
143
+ } or asplode "libiconv"
144
+ end
58
145
 
59
- # Finally fall back to /usr
60
- '/usr/include',
61
- '/usr/include/libxml2',
62
- ]
146
+ def process_recipe(name, version, static_p, cross_p)
147
+ MiniPortile.new(name, version).tap do |recipe|
148
+ recipe.target = portsdir = File.join(ROOT, "ports")
149
+ # Prefer host_alias over host in order to use i586-mingw32msvc as
150
+ # correct compiler prefix for cross build, but use host if not set.
151
+ recipe.host = RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"]
152
+ recipe.patch_files = Dir[File.join(portsdir, "patches", name, "*.patch")].sort
63
153
 
64
- LIB_DIRS = [
65
- # First search /opt/local for macports
66
- '/opt/local/lib',
154
+ if static_p
155
+ recipe.configure_options = [
156
+ "--disable-shared",
157
+ "--enable-static",
158
+ "CFLAGS='-fPIC #{ENV["CFLAGS"]}'",
159
+ ]
160
+ else
161
+ recipe.configure_options = [
162
+ "--enable-shared",
163
+ "--disable-static",
164
+ ]
165
+ end
67
166
 
68
- # Then search /usr/local for people that installed from source
69
- '/usr/local/lib',
167
+ if cross_p
168
+ recipe.configure_options += [
169
+ "--target=#{recipe.host}",
170
+ "--host=#{recipe.host}",
171
+ ]
172
+ end
70
173
 
71
- # Check the ruby install locations
72
- LIBDIR,
174
+ yield recipe
73
175
 
74
- # Finally fall back to /usr
75
- '/usr/lib',
76
- ]
176
+ if recipe.patch_files.empty?
177
+ message! "Building #{name}-#{version} for nokogiri.\n"
178
+ else
179
+ message! "Building #{name}-#{version} for nokogiri with the following patches applied:\n"
77
180
 
78
- XML2_HEADER_DIRS = [
79
- '/opt/local/include/libxml2',
80
- '/usr/local/include/libxml2',
81
- File.join(INCLUDEDIR, "libxml2")
82
- ] + HEADER_DIRS
83
-
84
- # If the user has homebrew installed, use the libxml2 inside homebrew
85
- brew_prefix = `brew --prefix libxml2 2> /dev/null`.chomp
86
- unless brew_prefix.empty?
87
- LIB_DIRS.unshift File.join(brew_prefix, 'lib')
88
- XML2_HEADER_DIRS.unshift File.join(brew_prefix, 'include/libxml2')
181
+ recipe.patch_files.each { |patch|
182
+ message! "\t- %s\n" % File.basename(patch)
183
+ }
89
184
  end
90
185
 
91
- else
92
- require 'mini_portile'
93
- require 'yaml'
186
+ message! <<-"EOS"
187
+ ************************************************************************
188
+ IMPORTANT! Nokogiri builds and uses a packaged version of #{name}.
94
189
 
95
- common_recipe = lambda do |recipe|
96
- recipe.target = File.join(ROOT, "ports")
97
- recipe.files = ["ftp://ftp.xmlsoft.org/libxml2/#{recipe.name}-#{recipe.version}.tar.gz"]
190
+ If this is a concern for you and you want to use the system library
191
+ instead, abort this installation process and reinstall nokogiri as
192
+ follows:
98
193
 
99
- checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
100
- unless File.exist?(checkpoint)
101
- recipe.cook
102
- FileUtils.touch checkpoint
103
- end
104
- recipe.activate
105
- end
194
+ gem install nokogiri -- --use-system-libraries
106
195
 
107
- dependencies = YAML.load_file(File.join(ROOT, "dependencies.yml"))
196
+ If you are using Bundler, tell it to use the option:
108
197
 
109
- libxml2_recipe = MiniPortile.new("libxml2", dependencies["libxml2"]).tap do |recipe|
110
- recipe.configure_options = [
111
- "--enable-shared",
112
- "--disable-static",
113
- "--without-python",
114
- "--without-readline",
115
- "--with-c14n",
116
- "--with-debug",
117
- "--with-threads"
118
- ]
119
- common_recipe.call recipe
120
- end
198
+ bundle config build.nokogiri --use-system-libraries
199
+ bundle install
200
+ EOS
121
201
 
122
- libxslt_recipe = MiniPortile.new("libxslt", dependencies["libxslt"]).tap do |recipe|
123
- recipe.configure_options = [
124
- "--enable-shared",
125
- "--disable-static",
126
- "--without-python",
127
- "--without-crypto",
128
- "--with-debug",
129
- "--with-libxml-prefix=#{libxml2_recipe.path}"
130
- ]
131
- common_recipe.call recipe
132
- end
202
+ message! <<-"EOS" if name == 'libxml2'
133
203
 
134
- $LDFLAGS << " -Wl,-rpath,#{libxml2_recipe.path}/lib"
135
- $LDFLAGS << " -Wl,-rpath,#{libxslt_recipe.path}/lib"
204
+ However, note that nokogiri does not necessarily support all versions
205
+ of libxml2.
136
206
 
137
- $CFLAGS << " -DNOKOGIRI_USE_PACKAGED_LIBRARIES -DNOKOGIRI_LIBXML2_PATH='\"#{libxml2_recipe.path}\"' -DNOKOGIRI_LIBXSLT_PATH='\"#{libxslt_recipe.path}\"'"
207
+ For example, libxml2-2.9.0 and higher are currently known to be broken
208
+ and thus unsupported by nokogiri, due to compatibility problems and
209
+ XPath optimization bugs.
210
+ EOS
138
211
 
139
- HEADER_DIRS = [libxml2_recipe, libxslt_recipe].map { |f| File.join(f.path, "include") }
140
- LIB_DIRS = [libxml2_recipe, libxslt_recipe].map { |f| File.join(f.path, "lib") }
141
- XML2_HEADER_DIRS = HEADER_DIRS + [File.join(libxml2_recipe.path, "include", "libxml2")]
212
+ message! <<-"EOS"
213
+ ************************************************************************
214
+ EOS
215
+
216
+ checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
217
+ unless File.exist?(checkpoint)
218
+ recipe.cook
219
+ FileUtils.touch checkpoint
220
+ end
221
+ recipe.activate
142
222
  end
143
223
  end
144
224
 
145
- dir_config('zlib', HEADER_DIRS, LIB_DIRS)
146
- dir_config('iconv', HEADER_DIRS, LIB_DIRS)
147
- dir_config('xml2', XML2_HEADER_DIRS, LIB_DIRS)
148
- dir_config('xslt', HEADER_DIRS, LIB_DIRS)
225
+ windows_p = RbConfig::CONFIG['target_os'] == 'mingw32' || RbConfig::CONFIG['target_os'] =~ /mswin/
149
226
 
150
- def asplode(lib)
151
- abort "-----\n#{lib} is missing. please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.\n-----"
227
+ if windows_p
228
+ $CFLAGS << " -DXP_WIN -DXP_WIN32 -DUSE_INCLUDED_VASPRINTF"
229
+ elsif RbConfig::CONFIG['target_os'] =~ /solaris/
230
+ $CFLAGS << " -DUSE_INCLUDED_VASPRINTF"
231
+ else
232
+ $CFLAGS << " -g -DXP_UNIX"
152
233
  end
153
234
 
154
- pkg_config('libxslt')
155
- pkg_config('libxml-2.0')
156
- pkg_config('libiconv')
235
+ if RUBY_PLATFORM =~ /mingw/i
236
+ # Work around a character escaping bug in MSYS by passing an arbitrary
237
+ # double quoted parameter to gcc. See https://sourceforge.net/p/mingw/bugs/2142
238
+ $CPPFLAGS << ' "-Idummypath"'
239
+ end
157
240
 
158
- def have_iconv?
159
- %w{ iconv_open libiconv_open }.any? do |method|
160
- have_func(method, 'iconv.h') or
161
- have_library('iconv', method, 'iconv.h') or
162
- find_library('iconv', method, 'iconv.h')
241
+ if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
242
+ $CFLAGS << " -O3" unless $CFLAGS[/-O\d/]
243
+ $CFLAGS << " -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline"
244
+ end
245
+
246
+ case
247
+ when arg_config('--use-system-libraries', !!ENV['NOKOGIRI_USE_SYSTEM_LIBRARIES'])
248
+ message! "Building nokogiri using system libraries.\n"
249
+
250
+ dir_config('zlib')
251
+
252
+ # Using system libraries means we rely on the system libxml2 with
253
+ # regard to the iconv support.
254
+
255
+ dir_config('xml2').any? || pkg_config('libxml-2.0')
256
+ dir_config('xslt').any? || pkg_config('libxslt')
257
+ dir_config('exslt').any? || pkg_config('libexslt')
258
+ else
259
+ message! "Building nokogiri using packaged libraries.\n"
260
+
261
+ require 'mini_portile'
262
+ require 'yaml'
263
+
264
+ static_p = enable_config('static', true) or
265
+ message! "Static linking is disabled.\n"
266
+
267
+ dir_config('zlib')
268
+
269
+ dependencies = YAML.load_file(File.join(ROOT, "dependencies.yml"))
270
+
271
+ cross_build_p = enable_config("cross-build")
272
+ if cross_build_p || windows_p
273
+ zlib_recipe = process_recipe("zlib", dependencies["zlib"], static_p, cross_build_p) do |recipe|
274
+ recipe.files = ["http://zlib.net/#{recipe.name}-#{recipe.version}.tar.gz"]
275
+ class << recipe
276
+ attr_accessor :cross_build_p
277
+
278
+ def configure
279
+ Dir.chdir work_path do
280
+ mk = File.read 'win32/Makefile.gcc'
281
+ File.open 'win32/Makefile.gcc', 'wb' do |f|
282
+ f.puts "BINARY_PATH = #{path}/bin"
283
+ f.puts "LIBRARY_PATH = #{path}/lib"
284
+ f.puts "INCLUDE_PATH = #{path}/include"
285
+ mk.sub!(/^PREFIX\s*=\s*$/, "PREFIX = #{host}-") if cross_build_p
286
+ f.puts mk
287
+ end
288
+ end
289
+ end
290
+
291
+ def configured?
292
+ Dir.chdir work_path do
293
+ !! (File.read('win32/Makefile.gcc') =~ /^BINARY_PATH/)
294
+ end
295
+ end
296
+
297
+ def compile
298
+ execute "compile", "make -f win32/Makefile.gcc"
299
+ end
300
+
301
+ def install
302
+ execute "install", "make -f win32/Makefile.gcc install"
303
+ end
304
+ end
305
+ recipe.cross_build_p = cross_build_p
306
+ end
307
+
308
+ libiconv_recipe = process_recipe("libiconv", dependencies["libiconv"], static_p, cross_build_p) do |recipe|
309
+ recipe.files = ["http://ftp.gnu.org/pub/gnu/libiconv/#{recipe.name}-#{recipe.version}.tar.gz"]
310
+ recipe.configure_options += [
311
+ "CPPFLAGS='-Wall'",
312
+ "CFLAGS='-O2 -g'",
313
+ "CXXFLAGS='-O2 -g'",
314
+ "LDFLAGS="
315
+ ]
316
+ end
317
+ end
318
+
319
+ libxml2_recipe = process_recipe("libxml2", dependencies["libxml2"], static_p, cross_build_p) do |recipe|
320
+ recipe.files = ["ftp://ftp.xmlsoft.org/libxml2/#{recipe.name}-#{recipe.version}.tar.gz"]
321
+ recipe.configure_options += [
322
+ "--without-python",
323
+ "--without-readline",
324
+ "--with-iconv=#{libiconv_recipe ? libiconv_recipe.path : iconv_prefix}",
325
+ "--with-c14n",
326
+ "--with-debug",
327
+ "--with-threads"
328
+ ]
329
+ end
330
+
331
+ libxslt_recipe = process_recipe("libxslt", dependencies["libxslt"], static_p, cross_build_p) do |recipe|
332
+ recipe.files = ["ftp://ftp.xmlsoft.org/libxml2/#{recipe.name}-#{recipe.version}.tar.gz"]
333
+ recipe.configure_options += [
334
+ "--without-python",
335
+ "--without-crypto",
336
+ "--with-debug",
337
+ "--with-libxml-prefix=#{libxml2_recipe.path}"
338
+ ]
339
+ end
340
+
341
+ $CFLAGS << ' ' << '-DNOKOGIRI_USE_PACKAGED_LIBRARIES'
342
+ $LIBPATH = ["#{zlib_recipe.path}/lib"] | $LIBPATH if zlib_recipe
343
+ $LIBPATH = ["#{libiconv_recipe.path}/lib"] | $LIBPATH if libiconv_recipe
344
+
345
+ have_lzma = preserving_globals {
346
+ have_library('lzma')
347
+ }
348
+
349
+ $libs = $libs.shellsplit.tap { |libs|
350
+ [libxml2_recipe, libxslt_recipe].each { |recipe|
351
+ libname = recipe.name[/\Alib(.+)\z/, 1]
352
+ File.join(recipe.path, "bin", "#{libname}-config").tap { |config|
353
+ # call config scripts explicit with 'sh' for compat with Windows
354
+ $CPPFLAGS = `sh #{config} --cflags`.strip << ' ' << $CPPFLAGS
355
+ `sh #{config} --libs`.strip.shellsplit.each { |arg|
356
+ case arg
357
+ when /\A-L(.+)\z/
358
+ # Prioritize ports' directories
359
+ if $1.start_with?(ROOT + '/')
360
+ $LIBPATH = [$1] | $LIBPATH
361
+ else
362
+ $LIBPATH = $LIBPATH | [$1]
363
+ end
364
+ when /\A-l./
365
+ libs.unshift(arg)
366
+ else
367
+ $LDFLAGS << ' ' << arg.shellescape
368
+ end
369
+ }
370
+ }
371
+
372
+ $CPPFLAGS << ' ' << "-DNOKOGIRI_#{recipe.name.upcase}_PATH=\"#{recipe.path}\"".shellescape
373
+
374
+ case libname
375
+ when 'xml2'
376
+ # xslt-config --libs or pkg-config libxslt --libs does not include
377
+ # -llzma, so we need to add it manually when linking statically.
378
+ if static_p && have_lzma
379
+ # Add it at the end; GH #988
380
+ libs << '-llzma'
381
+ end
382
+ when 'xslt'
383
+ # xslt-config does not have a flag to emit options including
384
+ # -lexslt, so add it manually.
385
+ libs.unshift('-lexslt')
386
+ end
387
+ }
388
+ }.shelljoin
389
+
390
+ if static_p
391
+ message 'checking for linker flags for static linking... '
392
+
393
+ case
394
+ when try_link('int main(void) { return 0; }',
395
+ ['-Wl,-Bstatic', '-lxml2', '-Wl,-Bdynamic'].shelljoin)
396
+ message "-Wl,-Bstatic\n"
397
+
398
+ $libs = $libs.shellsplit.flat_map { |arg|
399
+ case arg
400
+ when '-lxml2', '-lxslt', '-lexslt'
401
+ ['-Wl,-Bstatic', arg, '-Wl,-Bdynamic']
402
+ else
403
+ arg
404
+ end
405
+ }.shelljoin
406
+ else
407
+ message "NONE\n"
408
+ end
163
409
  end
164
410
  end
165
411
 
166
- asplode "libxml2" unless find_header('libxml/parser.h')
167
- asplode "libxslt" unless find_header('libxslt/xslt.h')
168
- asplode "libexslt" unless find_header('libexslt/exslt.h')
169
- asplode "libiconv" unless have_iconv?
170
- asplode "libxml2" unless find_library("xml2", 'xmlParseDoc')
171
- asplode "libxslt" unless find_library("xslt", 'xsltParseStylesheetDoc')
172
- asplode "libexslt" unless find_library("exslt", 'exsltFuncRegister')
412
+ {
413
+ "xml2" => ['xmlParseDoc', 'libxml/parser.h'],
414
+ "xslt" => ['xsltParseStylesheetDoc', 'libxslt/xslt.h'],
415
+ "exslt" => ['exsltFuncRegister', 'libexslt/exslt.h'],
416
+ }.each { |lib, (func, header)|
417
+ have_func(func, header) || have_library(lib, func, header) || have_library("lib#{lib}", func, header) or asplode("lib#{lib}")
418
+ }
173
419
 
174
420
  unless have_func('xmlHasFeature')
175
421
  abort "-----\nThe function 'xmlHasFeature' is missing from your installation of libxml2. Likely this means that your installed version of libxml2 is old enough that nokogiri will not work well. To get around this problem, please upgrade your installation of libxml2.
@@ -192,4 +438,16 @@ end
192
438
 
193
439
  create_makefile('nokogiri/nokogiri')
194
440
 
441
+ if enable_config('clean', true)
442
+ # Do not clean if run in a development work tree.
443
+ File.open('Makefile', 'at') { |mk|
444
+ mk.print <<EOF
445
+ all: clean-ports
446
+
447
+ clean-ports: $(DLLIB)
448
+ -$(Q)$(RUBY) $(srcdir)/extconf.rb --clean --#{static_p ? 'enable' : 'disable'}-static
449
+ EOF
450
+ }
451
+ end
452
+
195
453
  # :startdoc: