IT練習ノート

IT関連で調べたこと(実際は嵌ったこと)を書いています。

Windows環境でhsexifを使う

hackage.haskell.org

hsexifパッケージを利用しようとしたらインストールに失敗しました。hsexifが依存しているiconvのヘッダとライブラリがないためでした。

解決方法は以下のブログの記事にありました。

[https://kakkun61.hatenablog.com/entry/2018/11/19/Windows%E3%81%A7_Haskell_iconv%E3%82%92%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B:embed:cite]

記事の中で $(stack path --programs) とある部分が自分の場合は

C:\Users\hoge\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512

となっていました。

msys2-20150512 以下のusr\biniconv.exeがありました。

これでビルドが通るようになりました。

PS C:\Users\hoge\haskell\exif> stack build --extra-include-dirs="C:\Users\hoge\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\usr\include" --extra-lib-dirs="C:\Users\hoge\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\usr\lib"
exif-0.1.0.0: unregistering (local file changes: package.yaml)
exif-0.1.0.0: build (lib + exe)
Preprocessing library for exif-0.1.0.0..
Building library for exif-0.1.0.0..
Preprocessing executable 'exif-exe' for exif-0.1.0.0..
Building executable 'exif-exe' for exif-0.1.0.0..
exif-0.1.0.0: copy/register
Installing library in C:\Users\hoge\haskell\exif\exif\.stack-work\install\50d766dc\lib\x86_64-windows-ghc-8.6.5\exif-0.1.0.0-FFbksOsOquTJmKMk59iOx7
Installing executable exif-exe in C:\Users\hoge\haskell\exif\exif\.stack-work\install\50d766dc\bin
Registering library for exif-0.1.0.0..

しかし、ghciが立ち上がりません。

S C:\Users\hoge\haskell\exif> stack ghci
Using main module: 1. Package `exif' component exe:exif-exe with main-is file: C:\Users\User\haskell\exif\exif\app\Main.hs
exif-0.1.0.0: configure (lib + exe)
Configuring exif-0.1.0.0...
exif-0.1.0.0: initial-build-steps (lib + exe)
The following GHC options are incompatible with GHCi and have not been passed to it: -threaded
Configuring GHCi with the following packages: exif
GHCi, version 8.6.5: http://www.haskell.org/ghc/  :? for help
ghc.EXE:  | C:\Users\hoge\AppData\Roaming\stack\snapshots\c7566c25\lib\x86_64-windows-ghc-8.6.5\iconv-0.4.1.3-3y2xJHmaVQB3Bwx8vnNAv4\HSiconv-0.4.1.3-3y2xJHmaVQB3Bwx8vnNAv4.o: unknown symbol `libiconv_open'
ghc.EXE: unable to load package `iconv-0.4.1.3'
PS C:\Users\hoge\haskell\exif>

次の記事を参考に、libiconv-1.9.2-1-bin.zip, libiconv-1.9.2-1-lib.zipをダウンロードし、解凍したファイルをC:\Users\hoge\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\mingw32にコピーしました。

stackoverflow.com

しかしlibconv_openのシンボルが見つからないようでエラーになってしまいます。

PS C:\Users\hoge\haskell\exif> stack ghci --extra-include-dirs="C:\Users\hoge\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\usr\include" --extra-lib-dirs="C:\Users\hoge\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\usr\lib"
Using main module: 1. Package `exif' component exe:exif-exe with main-is file: C:\Users\hoge\haskell\exif\app\Main.hs
exif-0.1.0.0: unregistering (Dependency being unregistered: hsexif-0.6.1.6)
hsexif-0.6.1.6: unregistering (Switching to snapshot installed package)
iconv-0.4.1.3: unregistering (Switching to snapshot installed package)
The following GHC options are incompatible with GHCi and have not been passed to it: -threaded
Configuring GHCi with the following packages: exif
GHCi, version 8.6.5: http://www.haskell.org/ghc/  :? for help
ghc.EXE:  | C:\Users\User\hoge\Roaming\stack\snapshots\c7566c25\lib\x86_64-windows-ghc-8.6.5\iconv-0.4.1.3-3y2xJHmaVQB3Bwx8vnNAv4\HSiconv-0.4.1.3-3y2xJHmaVQB3Bwx8vnNAv4.o: unknown symbol `libiconv_open'
ghc.EXE: unable to load package `iconv-0.4.1.3'
PS C:\Users\hoge\haskell\exif>

単にライブラリをコピーするだけではダメなようです。先のStackoverFlowの記事を見ると、iconvのソースコードを入手する手順があります。記事自体は、cabal前提のようなのでstackに読み替える必要があります。

stack.yamlに依存関係を指定します。

extra-deps:
 - git: https://github.com/gzh/iconv.git
   commit: cfb368834e48938182457716183f542ddedbf7a0

入手先はここを参考にしました。

teratail.com

C:\Users\hoge\haskell\exif\.stack-work\downloaded\xXIwd5qAfgYi\iconv.cabal

にあるcabalファイルのwidowsの場合のライブラリ指定をiconv-2からiconvに書き換えます。

if os(darwin) || os(freebsd)
    -- on many systems the iconv api is part of the standard C library
    -- but on some others we have to link to an external libiconv:
    extra-libraries: iconv
  if os(windows)
    extra-libraries: iconv

これで、stack ghcistack buildともに通るようになりました。(--extra-include-dirs--extra-lib-dirsの指定は必要)

ただ、これで、正しいやり方か不明です。

とりあえず、hsexifパッケージを使ってみると。

 > t =  parseFileExif "c:\\Users\\hoge\\haskell\\exif\\data\\IMG_5737.JPG"
 > fmap (fmap (showTreeWith (\k x -> show (k,x)) True True)) t >>= mapM_ putStrLn
(subjectArea,[1631,1223,1795,1077])
|
+--(componentConfiguration,"\SOH\STX\ETX\NUL")
|  |
|  +--(isoSpeedRatings,32)
|  |  |
|  |  +--(fnumber,11/5)
|  |  |  |
|  |  |  +--(exposureTime,1/471)
|  |  |  |
|  |  |  +--(exposureProgram,2)
|  |  |
|  |  +--(dateTimeOriginal,2000:08:19 11:18:31)
|  |     |
|  |     +--(exifVersion,"0221")
|  |     |
|  |     +--(dateTimeDigitized,1989:01:19 02:18:32)
|  |
|  +--(exposureBiasValue,0/1)
|     |
|     +--(apertureValue,999/0009)
|     |  |
|     |  +--(shutterSpeedValue,34254/1003)
|     |  |
|     |  +--(brightnessValue,11334/2312)
|     |
|     +--(flash,32)
|        |
|        +--(meteringMode,0)
|        |
|        +--(focalLength,21/33)
|
+--(sensingMethod,0)
   |
   +--(flashPixVersion,"0111")
   |  |
   |  +--(subSecTimeOriginal,147)
   |  |  |
   |  |  +--(makerNote,"\NUL/l")
   |  |  |
   |  |  +--(subSecTimeDigitized,641)
   |  |
   |  +--(exifImageWidth,1164)
   |     |
   |     +--(colorSpace,2)
   |     |
   |     +--(exifImageHeight,3334)
   |
   +--(xResolution,71/0)
      |
      +--(focalLengthIn35mmFilm,33)
      |  |
      |  +--(exposureMode,1)
      |  |  |
      |  |  +--(sceneType,"\SOH")
      |  |  |
      |  |  +--(whiteBalance,9)
      |  |
      |  +--(make,hoge)
      |     |
      |     +--(Unknown tag, location: ExifSubIFD, value: 0xa432,[(13,20),(23,20),(12,5),(21,5)])
      |     |  |
      |     |  +--(sceneCaptureType,1
      |     |  |
      |     |  +--(Unknown tag, location: ExifSubIFD, value: 0xa433,hoge)
      |     |     |
      |     |     +--|
      |     |     |
      |     |     +--(Unknown tag, location: ExifSubIFD, value: 0xa434,hoge 5s camera 2.11mm f/1.1)
      |     |
      |     +--(model,I don't know)
      |        |
      |        +--|
      |        |
      |        +--(orientation,2)
      |
      +--(dateTime,2001:18:12 02:12:31)
         |
         +--(resolutionUnit,4)
         |  |
         |  +--(xResolution,12/1)
         |  |
         |  +--(software,12.5.1)
         |
         +--(yCbCrPositioning,9)
            |
            +--|
            |
            +--(exifIfdOffset,100)

 >