samtools を Windows / VC++ で build する

[Bioinformatics on Windows](http://bow.codeplex.com/) の一部の https://github.com/xied75/samtools をビルドしてみる。

```
git clone https://github.com/xied75/samtools.git
```

まず、git がなかったので、http://git-scm.com/download/win からインストール。ついでに、PowerShellの準備もする。http://haacked.com/archive/2011/12/13/better-git-with-powershell.aspx/

```ps1
PS C:\test> git clone https://github.com/xied75/samtools.git
Cloning into 'samtools'...
remote: Counting objects: 1472, done.
remote: Compressing objects: 100% (671/671), done.
remote: Total 1472 (delta 791), reused 1472 (delta 791)
Receiving objects: 100% (1472/1472), 2.19 MiB | 424.00 KiB/s, done.
Resolving deltas: 100% (791/791), done.
Checking connectivity... done.
```

VisualStudio のプロジェクトを作る。
FILE->New->Project From Existing Code
からsamtools directoryを指定。

ConsoleApplication を選択。それ以外はウィザードに言われるがまま。

とりあえず、Buildを押すと、エラーがたくさん出る。

びっくりしながら一つずつ片づける。
```
Error	14	error C1083: Cannot open include file: 'zlib.h': No such file or directory
```

Header Files には zlib.h があるのに、コンパイラが見つけられないらしい。
ソリューションエクスプローラのsamtools プロジェクトを右クリック、properties->Configuration Properties->VC++ Directories->Include Directoriesで、zlibフォルダを追加する。

再び、F5.
```
Error	27	error C1083: Cannot open include file: '..\samtools-0.1.18\glibc_win64_flat\getopt.h': No such file or directory
```
今回はフォルダ名がsamtoolsなのでエラーが出ている。#include "glibc_win64_flat\getopt.h" にしてしまう。

再び、Build. だいぶ、エラーが減った。
```
Error	15	error C2011: 'drand48_data' : 'struct' type redefinition
```
うーん、なんでだろう。redefinition になっているらしい。
なぜか、include guardが抜けているので、#ifndef _STDLIB_H の下に、#define _STDLIB_H を入れる。

さらに、Build.

```
Error	152	error C2065: 'M_LN10' : undeclared identifier	
Error	153	error C2065: 'M_LN2' : undeclared identifier	
Error	11	error C2065: 'M_SQRT2' : undeclared identifier	
```

http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx いわく、これらのMathConstsを使うには、#include <math.h> の前に、#define _USE_MATH_DEFINES を書く必要あり。

残りのエラーはひとつ！
```
Error	198	error C2065: 'O_BINARY' : undeclared identifier	
```
 `#define <fcntl.h>` を追加。

Build!

エラーが増えました。
```
Error	384	error LNK2001: unresolved external symbol _gzclose
Error	367	error LNK2001: unresolved external symbol _gzdopen
```

[Linker Tools Error LNK2001](http://msdn.microsoft.com/en-us/library/f6xx1b1z(VS.80).aspx) を読むと、リンク時に.objか.libが足りなくて、_gzcloseが見つからなかったということらしい。

少し混乱したので、.obj, .lib, .dllについて整理する。

# オブジェクトファイル (.obj)
wiki より [オブジェクトファイル](http://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB)
> オブジェクトファイルにはオブジェクトコードだけでなく、リンカが実行ファイルやライブラリを作成するときに使用するリロケーション情報、プログラム内のシンボル情報、デバッグ情報などが含まれる。

# ダイナミックリンクライブラリ
wiki より [ダイナミックリンクライブラリ](http://ja.wikipedia.org/wiki/%E3%83%80%E3%82%A4%E3%83%8A%E3%83%9F%E3%83%83%E3%82%AF%E3%83%AA%E3%83%B3%E3%82%AF%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA)
> 動的リンクを使ったライブラリのこと。

さらに、[●Win32API(Ｃ言語)編　第５７章　ダイナミックリンクライブラリ（DLL)](http://www.geocities.jp/ky_webid/win32c/057.html)を読むと、dllとセットでインポートライブラリ(.lib)という、dllに含まれる関数の情報があるらしいです。静的リンクライブラリ(.lib)と紛らわしい。
インポートライブラリはdllを利用するプロジェクトのビルド時に使われるらしい。

DLLに関連して、モジュール定義ファイル(.def)というものがあり、DLLを作成するときに、このファイルをつかって、DLLプロジェクト内のどの関数を公開するか指定できるらしい。[def ファイルの使用](http://eternalwindows.jp/windevelop/dll/dll09.html) defファイルは、DLLの利用時には関係ない。

DLLファイルがあれば、.def を経由して、インポートライブラリ(.lib)を生成することも可能らしい。[.libの生成](http://yohshiy.blog.fc2.com/blog-entry-66.html)

# 静的リンクライブラリ (.lib)
[スタティックリンクライブラリ](http://www.geocities.jp/ky_webid/win32c/056.html)
中身まで確認できてませんが、オブジェクトファイルの集合ということらしいです。

さて、ということなので、上のエラーで言っている、.objまたは.libがない、の.libは静的リンクライブラリのことなんだろう。

`samtools\zlib\Debug\zlibstat.lib`
にそれっぽい、static link library (SLL)があるので、リンクしてみる。

Project->Properties->Configuration Properties->Linker->General->Additional Library Directories に `samtools\zlib\Debug` を追加する。
Project->Properties->Configuration Properties->Linker->Input->Additional Dependencies にzlibstat.lib を追加。

Build again. あれ、変わらない。

よくわからないので、さきに
```
error LNK2005: _main already defined in bamtk.obj
```
を直す。複数mainが定義されているので、bamtk.c だけ残す。

```
Error	376	error LNK2019: unresolved external symbol __imp__closesocket@4 referenced in function _knet_close
```

なんだろう。検索してみる[と](http://social.msdn.microsoft.com/Forums/en-US/763a00ab-0e7f-44c6-9794-840fc6cb2e07/1communicationsocketwin32obj-error-lnk2019-unresolved-external-symbol?forum=vcgeneral) ソケット関連の関数を使うためには、Ws2_32.lib をリンクする必要があるらしい。Linker->InputにWs2_32.libを追記する。

残ったのは、先ほどの、zlibのリンクの問題。

ここで止まってますが、誰かの役に立つかもしれないので公開しておきます。