動機
nokogiri
以外のXMLパーサーないかなー。
GemのいろいろXML/HTMLparserをまとめたい(Oga特集)を発見。
ふむ、ox
を使ってみるか。
流れ
-
gem i ox --platform=mswin64
して上手くいかなかったので、MAKEFILEを編集し、ox.so
を作る。 -
gem
に登録するのは諦め、require "ox"
できるようsite_ruby
に設置する。
手順
環境
- OS: Windows 10
> ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x64-mingw32]
ox.soを作る
- まずは普通に
gem i ox --platform=mswin64
を実行。
> gem i ox --platform=mswin64
Temporarily enhancing PATH for MSYS/MINGW...
Building native extensions. This could take a while...
ERROR: Error installing ox:
ERROR: Failed to build gem native extension.
current directory: C:/tools/ruby25/lib/ruby/gems/2.5.0/gems/ox-2.9.3/ext/ox
C:/tools/ruby25/bin/ruby.exe -r ./siteconf20180715-13724-4vbaft.rb extconf.rb
>>>>> Creating Makefile for ruby version 2.5.0 on x64-mingw32 <<<<<
creating Makefile
current directory: C:/tools/ruby25/lib/ruby/gems/2.5.0/gems/ox-2.9.3/ext/ox
make "DESTDIR=" clean
current directory: C:/tools/ruby25/lib/ruby/gems/2.5.0/gems/ox-2.9.3/ext/ox
make "DESTDIR="
generating ox-x64-mingw32.def
make: *** `base64.o' に必要なターゲット `/C/tools/ruby25/include/ruby-2.5.0/ruby.h' を make するルールがありません. 中 止.
make failed, exit code 2
Gem files will remain installed in C:/tools/ruby25/lib/ruby/gems/2.5.0/gems/ox-2.9.3 for inspection.
Results logged to C:/tools/ruby25/lib/ruby/gems/2.5.0/extensions/x64-mingw32/2.5.0/ox-2.9.3/gem_make.out
- makeでエラー。
-
make: *** base64.o に必要なターゲット /C/tools/ruby25/include/ruby-2.5.0/ruby.h を make するルールがありません. 中 止.
が怪しい。 -
C:\tools\ruby25\lib\ruby\gems\2.5.0\gems\ox-2.9.3\ext\ox\Makefile
をチェックすると、パスがダメに感じたのでいじる。
MAKEFILE
- topdir = /C/tools/ruby25/include/ruby-2.5.0
+ topdir = C:/tools/ruby25/include/ruby-2.5.0
- cdしてmakeしてみる。
> cd C:/tools/ruby25/lib/ruby/gems/2.5.0/gems/ox-2.9.3/ext/ox
> make
compiling base64.c
compiling builder.c
compiling cache.c
compiling cache8.c
compiling dump.c
compiling err.c
compiling gen_load.c
compiling hash_load.c
compiling obj_load.c
compiling ox.c
compiling parse.c
compiling sax.c
compiling sax_as.c
compiling sax_buf.c
compiling sax_hint.c
compiling special.c
linking shared-object ox.so
process_begin: CreateProcess(NULL, rm -f ox.so, ...) failed.
make (e=2): 指定されたファイルが見つかりません。
make: [ox.so] エラー 2 (無視されました)
C:/tools/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/5.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lx64-msvcrt-ruby250
C:/tools/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/5.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lgmp
collect2.exe: error: ld returned 1 exit status
make: *** [ox.so] エラー 1
-
rm -f
がエラーしてるようなので、該当行を削除。 -
C:/tools/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/5.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lx64-msvcrt-ruby250
:分からないから放置。 -
(略): cannot find -lgmp
:gmpなしでいいや。
MAKEFILE
- -$(Q)$(RM) $(@)
- LIBS = $(LIBRUBYARG_SHARED) -lgmp -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi
+ LIBS = $(LIBRUBYARG_SHARED) -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi
- とりあえず
make
を実行。
> make
linking shared-object ox.so
C:/tools/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/5.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lx64-msvcrt-ruby250
collect2.exe: error: ld returned 1 exit status
make: *** [ox.so] エラー 1
- MAKEFILEを眺めてたら、もう一箇所パスが怪しかったのでいじる。
MAKEFILE
- prefix = $(DESTDIR)/C/tools/ruby25
+ prefix = C:/tools/ruby25
- もう一回
make
を実行。
> make
linking shared-object ox.so
- とりあえず
ox.so
は作れた。 - ここで奮闘するが、gemとして登録するのを諦める。
site_rubyにファイルを移動する
- 諸々の
require
をチェック。
ox.c
// ox.c → ox.so
(略)
rb_require("ox/version");
rb_require("ox/error");
rb_require("ox/hasattrs");
rb_require("ox/node");
rb_require("ox/comment");
rb_require("ox/instruct");
rb_require("ox/cdata");
rb_require("ox/doctype");
rb_require("ox/element");
rb_require("ox/document");
rb_require("ox/bag");
rb_require("ox/sax");
(略)
ox.rb
(略)
require 'ox/version'
require 'ox/error'
require 'ox/hasattrs'
require 'ox/node'
require 'ox/comment'
require 'ox/raw'
require 'ox/instruct'
require 'ox/cdata'
require 'ox/doctype'
require 'ox/element'
require 'ox/document'
require 'ox/bag'
require 'ox/sax'
require 'ox/ox' # C extension
- こんな感じに配置すれば良さそう。
site_ruby
├── ox.rb
└── ox
├── ox.so
├── bag.rb
├── cdata.rb
├── comment.rb
├── doctype.rb
├── document.rb
├── element.rb
├── error.rb
├── hasattrs.rb
├── instruct.rb
├── node.rb
├── raw.rb
├── sax.rb
├── version.rb
└── xmlrpc_adapter.rb
-
C:/tools/ruby25/lib/ruby/site_ruby
にファイルを突っ込む。
oxを実行する
- GemのいろいろXML/HTMLparserをまとめたい(Oga特集)さんのサンプルをいじって実行。
irb(main):001:0> require "open-uri"
=> true
irb(main):002:0>
irb(main):003:0> xml = ""
=> ""
irb(main):004:0> open("http://www.nicovideo.jp/ranking/fav/hourly/all?rss=2.0") do |f|
irb(main):005:1* xml = f.read
irb(main):006:1> nil
irb(main):007:1> end
=> nil
irb(main):008:0> require 'ox'
=> true
irb(main):009:0> titles = Ox.parse(xml).locate("rss/channel/item/title").map{|n| n.nodes[0]}[0,2]
=> ["\u7B2C1\u4F4D\uFF1A\u3010\u7B2C10\u56DE\u6771\u65B9\u30CB\u30B3\u7AE5\u796D\u3011Pizuya's Cell / \u30E6\u30D3\u30AD\u30BF\u30B9\u30FB\u30B0\u30EA\u30CB\u30C3\u30B8", "\u7B2C2\u4F4D\uFF1A\u3010DbD\u3011\u30B5\u30D0\u30A4\u30D0\u30EB\u30FB\u30AA\u30D6\u30FB\u5B87\u90FD\u5BAE14.mp36"]
irb(main):010:0> puts titles
第1位:【第10回東方ニコ童祭】Pizuya's Cell / ユビキタス・グリニッジ
第2位:【DbD】サバイバル・オブ・宇都宮14.mp36
=> nil
- できた!!
コメント
-
gmp
はどこで使われてるのか? - issues を見てみたら参考事例があった → Error installing gem: No rule to make target · Issue #165 · ohler55/ox
- 普通にインストールできたのでは?