LoginSignup
2
0

More than 5 years have passed since last update.

Windowsでoxを使えるようにした軌跡

Last updated at Posted at 2018-07-15

動機

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を実行する

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
  • できた!!

コメント

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0