はてな使ったら負けだと思っている deriving Haskell このページをアンテナに追加 RSSフィード

 | 

2009-07-27

HOCをインストールしようとして出来なかった記録

| 14:54 |  HOCをインストールしようとして出来なかった記録 - はてな使ったら負けだと思っている deriving Haskell を含むブックマーク はてなブックマーク -  HOCをインストールしようとして出来なかった記録 - はてな使ったら負けだと思っている deriving Haskell

(追記:2009年09月現在、普通にインストール出来る様になったみたいです! HOCがインストール出来る様になったみたいです - はてな使ったら負けだと思っている deriving Haskell - haskell 参照。)

HOC と云う、HaskellからObjective-Cを叩くためのバインディングがあります。

これは主にghc-6.8.x系統を対象としてるみたいで、GHC-6.10.x系統には手直ししないとインストール出来ないみたいです。と云う訳で、勉強の合間に少しずつ四苦八苦しつつ結局行き詰まった記録。


共有ライブラリとかオブジェクトファイルとかの事をあんまり(と云うか殆んど)知らない状態でやろうと云うのが間違いなのかもしれませんが……こうしてみたら?と云うアドバイスがありましたら是非お願いします。

環境

OSX 10.5.7 + MacBook (1.3GHz Intel Core 2 duo)

$ ghc -v
Glasgow Haskell Compiler, Version 6.10.4, for Haskell 98, stage 2 booted by GHC version 6.10.3.20090628

$ ghc-pkg list
/Library/Frameworks/GHC.framework/Versions/610/usr/lib/ghc-6.10.4/./package.conf:
    Cabal-1.6.0.3, HUnit-1.2.0.3, QuickCheck-1.2.0.0, array-0.2.0.0,
    base-3.0.3.1, base-4.1.0.0, bytestring-0.9.1.4, cinnamon-0.2,
    containers-0.2.0.1, directory-1.0.0.3, (dph-base-0.3),
    (dph-par-0.3), (dph-prim-interface-0.3), (dph-prim-par-0.3),
    (dph-prim-seq-0.3), (dph-seq-0.3), extensible-exceptions-0.1.1.0,
    filepath-1.1.0.2, (ghc-6.10.4), ghc-prim-0.1.0.0, haddock-2.4.2,
    haskell-src-1.0.1.3, haskell98-1.0.1.0, hpc-0.5.0.3, html-1.0.1.2,
    integer-0.1.0.1, mtl-1.1.0.2, network-2.2.1.2, old-locale-1.0.0.1,
    old-time-1.0.0.2, packedstring-0.1.0.1, parallel-1.1.0.1,
    parsec-2.1.0.1, pretty-1.0.1.0, process-1.0.1.1, random-1.0.0.1,
    regex-base-0.72.0.2, regex-compat-0.71.0.1, regex-posix-0.72.0.3,
    rts-1.0, stm-2.1.1.2, syb-0.1.0.1, template-haskell-2.3.0.1,
    time-1.1.4, unix-2.3.2.0, xhtml-3000.2.0.1
/Users/*****/.ghc/i386-darwin-6.10.4/package.conf:
    HaXml-1.13.3, binary-0.5.0.1, darcs-2.2.1, fgl-5.4.2.2,
    haskeline-0.6.1.6, parsec-3.0.0, plugins-1.4.1, terminfo-0.2.2.1,
    terminfo-0.3.0.2, utf8-string-0.3.5

$ cabal -V
cabal-install version 0.6.2
using version 1.6.0.3 of the Cabal library 

libffi のビルド & HOCをもってくる

$ svn co http://hoc.googlecode.com/svn/trunk/libffi
$ cd libffi/src
$ ../configure --prefix=/usr/local CFLAGS=-DMACOSX
$ make
$ sudo make install
$ svn co http://hoc.googlecode.com/svn/trunk/hoc

ビルドする

BUILDING.CVS と云うファイルがあるが、しかし、つかわれているのはSVNだしなぁ……と思いつつ書かれている通りにやってみる。

$ ./autogen.sh 
+ exec autoconf
$ ./configure
checking build system type... i386-apple-darwin9.7.0
checking host system type... i386-apple-darwin9.7.0
checking target system type... i386-apple-darwin9.7.0

 = snip =

config.status: creating HOC_cbits/Makefile
config.status: creating InterfaceGenerator/Makefile
config.status: creating InterfaceGenerator2/Makefile
config.status: creating Tools/Makefile

$ make
for dir in HOC_cbits HOC InterfaceGenerator InterfaceGenerator2 Bindings Foundation AppKit Tools docs ; do (cd $dir; echo "In directory $dir"; make all) done
In directory HOC_cbits

  = snip= 

[13 of 31] Compiling HOC.Exception    ( HOC/Exception.hs, build/objects/HOC/Exception.o )

HOC/Exception.hs:73:23: Not in scope: `throwDyn'

HOC/Exception.hs:82:8: Not in scope: `catchDyn'

HOC/Exception.hs:88:26: Not in scope: `catchDyn'
make[1]: *** [ghcmake.build-stamp] Error 1

  = snip =

../inplace.conf: openBinaryFile: does not exist (No such file or directory)
make[1]: *** [hocwrap] Error 1
In directory docs
pod2html \
	  --index \
	  --header \
	  --title="HOC: a Haskell to Objective-C bridge" \
	  --outfile "HOC.html" \
	  Introduction.pod Quick_Start.pod Mapping_Types.pod Accessing_Other_Frameworks.pod Creating_an_Objective-C_Class_in_Haskell.pod Tools.pod Appendices.pod

どうやら例外処理の方法が古いみたいで Control.OldException にしないと駄目っぽいな……と当りをつけて、HOC/HOC/Exception.hs の import Control.Exception を import Control.OldException に変えて再挑戦。

$ make
[27 of 31] Compiling HOC.Utilities    ( HOC/Utilities.hs, build/objects/HOC/Utilities.o )
[28 of 31] Compiling HOC.StdArgumentTypes ( HOC/StdArgumentTypes.hs, build/objects/HOC/StdArgumentTypes.o )
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Loading package unix-2.3.2.0 ... linking ... done.
Loading object (static) ../HOC_cbits/HOC_cbits.o ... done
Loading object (dynamic) objc ... done
Loading object (dynamic) ffi ... done
Loading object (framework) Foundation ... done
ghc: 
unknown symbol `_setIvarInList'
final link ... linking extra libraries/objects failed
make[1]: *** [ghcmake.build-stamp] Error 1

  = snip =

../inplace.conf: openBinaryFile: does not exist (No such file or directory)
make[1]: *** [hocwrap] Error 1
In directory docs
make[1]: Nothing to be done for `all'.

むう。だめだ。

Setup.hs に乗り換える

そもそも.CVSなんて信用するから悪かったんだ!と逆ギレして、 しばらくオンラインをさまよう。

すると、何故か Yi の READMEに詳しく載っていたので、の云う通りにしてビルドしてみる。cabal-install で色々パッケージを管理しているので、 --prefix=/usr/local の代わりに --user をつける。

$ runhaskell Setup configure --user
Configuring HOC-1.0...
$ runhaskell Setup build           
Compiling HOC_cbits...

  = snip =

[11 of 31] Compiling HOC.Exception    ( HOC/HOC/Exception.hs, dist/build/HOC/Exception.o )

HOC/HOC/Exception.hs:23:28:
    Not in scope: type constructor or class `SomeException'

  = snip = 

HOC/HOC/Exception.hs:51:19:
    Not in scope: data constructor `SomeException'

おっと。何か新しいExceptionに対応したみたい(?)なのでさっきの OldException を再びException に戻す。

$ runhaskell Setup build
Compiling HOC_cbits...
Preprocessing library HOC-1.0...
Preprocessing executables for HOC-1.0...

  = snip =

[30 of 31] Compiling HOC.CStruct      ( HOC/HOC/CStruct.hs, dist/build/HOC/CStruct.o )
[31 of 31] Compiling HOC              ( HOC/HOC.hs, dist/build/HOC.o )
Warning: the following files would be used as linker inputs, but linking is not being done: HOC_cbits.o
ghc: no input files
Usage: For basic information, try the `--help' option.

ここで止まってしまう。見るとdist/build/HOC_cbits.oは生成されている模様だが……。

HOC_cbits との闘争

ここで良くわからなくなったので、 本家のGoogle Code で似た様な報告が無いか見る。

あった。Issue 12

どうやら、6.10.xのcabal君が HOC_cbits.o をCのソースファイルとして扱うとかなんとかで、兎に角上手くいかないらしい。

折角インストールした6.10.xを6.8.xに戻すのはイヤなので二つ目の方法を取る。つまり、

A slightly less quick workaround is to remove the 'c-sources' line in the .cabal file and manually link HOC_cbits.o into the build product (both the .a and the .o).

http://code.google.com/p/hoc/issues/detail?id=12

と云うことなので、 HOC.cabal から 67行目の

c-sources: HOC_cbits.o   

を削除。再び、

$ runhaskell Setup configure --user
Configuring HOC-1.0...
$ runhaskell Setup build           
Compiling HOC_cbits...
Preprocessing library HOC-1.0...
Preprocessing executables for HOC-1.0...
Building HOC-1.0...

  = snip =

[26 of 27] Compiling Output           ( InterfaceGenerator2/Output.hs, dist/build/hoc-ifgen/hoc-ifgen-tmp/Output.o )
[27 of 27] Compiling Main             ( InterfaceGenerator2/Main.hs, dist/build/hoc-ifgen/hoc-ifgen-tmp/Main.o )
Linking dist/build/hoc-ifgen/hoc-ifgen ...

となって平穏無事に終わった。やった。

さて、HOC_cbitsをちゃんとつくる。下の方のComment 5 で出てたpatch を当てる。

The attached patch lets me build with base 4.0.0 (using Control.OldExceptions) with some hand-tweaking of

libHOC_cbits.dylib:

(略)

(will build HOC_cbits and HOC, then fail)

(略)

copy libHOC_cbits.dylib to ~/.cabal/lib (or elsewhere in my ghc-pkg config library path)

(make sure HOC_cbits is an extra library in ghc-pkg's HOC package descriptor)

http://code.google.com/p/hoc/issues/detail?id=12

手順通りやってみる。

$ ./configure OBJCFLAGS='-arch i686' CFLAGS='-arch i686' LDFLAGS='-arch i686'  --with-dynamic-haskell CFLAGS='-fpic -dynamic' OBJCFLAGS='-fpic -dynamic' LDFLAGS='-fpic -dynamic -read_only_relocs suppress'

$ make
for dir in HOC_cbits HOC InterfaceGenerator InterfaceGenerator2 Bindings Foundation AppKit Tools docs ; do (cd $dir; echo "In directory $dir"; make all) done

  = snip =

../inplace.conf: openBinaryFile: does not exist (No such file or directory)
make[1]: *** [hocwrap] Error 1
In directory docs
make[1]: Nothing to be done for `all'.

$ ls HOC_cbits | grep HOC
HOC_cbits.o
libHOC_cbits.a
libHOC_cbits.dylib

$ cp HOC_cbits/libHOC_cbits.{a,dylib} HOC_cbits/HOC_cbits.o ~/.cabal/lib 
$ runhaskell Setup.hs configure --user
$ runhaskell Setup.hs build
$ sudo runhaskell Setup.hs install
Installing library in /Users/hiromi/.cabal/lib/HOC-1.0/ghc-6.10.4
Installing executable(s) in /Users/hiromi/.cabal/bin
Registering HOC-1.0...
Reading package info from "dist/installed-pkg-config" ... done.
Writing new package config file... done.

~/.ghc/i386-darwin-6.10.4/package.conf を確認。extraLibraries に HOC_cbits が入っていない。修正。

つれないBinding

$ cd Bindings
$ sudo sh make-bindings-macos.sh
*** Processing Framework Foundation ***
Parsing Objective-C header files:                       [                         ]

  = snip =

Writing Foundation.pi:                             100% [*************************]
done.
~/install/hoc/Bindings/Generated/HOC-Foundation ~/install/hoc/Bindings/Generated
cabal: These flags are used without having been defined: base4

む。と云うことで、手作業でやってみることにする。

$ cd Generated/HOC-Foundation
$ emacs HOC-Foundation.cabal

 ( 四行目の Flag base を Flag base4 に変更)

$ sudo runhaskell Setup.hs configure --user
Warning: HOC-Foundation.cabal: A package using section syntax should require
"Cabal-Version: >= 1.2" or equivalent.
Configuring HOC-Foundation-1.0...

$ sudo runhaskell Setup.hs build           
Preprocessing library HOC-Foundation-1.0...
Building HOC-Foundation-1.0...
[  1 of 154] Compiling Foundation.NSXMLNodeOptions ( Foundation/NSXMLNodeOptions.hs, dist/build/Foundation/NSXMLNodeOptions.o )

  = snip = 

Loading package template-haskell ... linking ... done.
Loading package HOC-1.0 ... <command line>: can't load .so/.DLL for: HOC_cbits (dlopen(libHOC_cbits.dylib, 9): image not found)

あれ?移した場所が悪かったのかな…… と云うことで:


$ sudo mv ~/.cabal/lib/libHOC_cbits.{dylib,a}  ~/.cabal/lib/HOC_cbits.o ~/.cabal/lib/HOC-1.0/ghc-6.10.4
$ sudo runhaskell Setup.hs build
Preprocessing library HOC-Foundation-1.0...
Building HOC-Foundation-1.0...
[  1 of 154] Compiling Foundation.NSXMLNodeOptions ( Foundation/NSXMLNodeOptions.hs, dist/build/Foundation/NSXMLNodeOptions.o )

  = snip =

Loading package template-haskell ... linking ... done.
ghc: 
unknown symbol `_setIvarInList'
Loading package HOC-1.0 ... linking ... ghc: unable to load package `HOC-1.0'

こうなった……。うーん。

このIRCログ の 02:04:34 付近をみてみて、HOC/HOC/NewClass.hs の 58行目〜62行目

foreign import ccall "NewClass.h makeIvarList"
    rawMakeIvarList :: Int -> IO (Ptr IvarList)
foreign import ccall "NewClass.h setIvarInList"
    rawSetIvarInList :: Ptr IvarList -> Int
                  -> CString -> CString -> CSize -> Word8 -> IO ()

foreign import ccall "Ivars.h makeIvarList"
    rawMakeIvarList :: Int -> IO (Ptr IvarList)
foreign import ccall "Ivars.h setIvarInList"
    rawSetIvarInList :: Ptr IvarList -> Int
                  -> CString -> CString -> CSize -> Word8 -> IO ()

と書き換えて、

$ runhaskell Setup.hs clean
$ runhaskell Setup.hs configure --user
$ runhaskell Setup.hs build
$ runhaskell Setup.hs install

などとして、上書きされてしまうので、再び ~/.ghc/i386-darwin-6.10.4/package.conf を適宜弄ってから、もう一度

$ cd Bindings/Generated/HOC-Foundation
$ sudo runhaskell Setup.hs configure --user
$ sudo runhaskell Setup.hs build

などとしてみるも、またも unknown symbol `_setIvarInList' と云われる。……むーん……

参考文献s

  1. GitHub - andrep/hoc: Automatically exported from code.google.com/p/hoc
    1. Issue 12
  2. Yi の README
  3. Chat Logs
  4. このIRCログ

どなたかこうしてみたら?と云うアドバイスなどありましたらよろしくおねがいします><

トラックバック - http://haskell.g.hatena.ne.jp/mr_konn/20090727
 |