IDEを使わずにOpenCVを使ったC++ソースファイルをビルドする

## 背景
[IDE](https://ja.wikipedia.org/wiki/統合開発環境)を使えば，C++のOpenCVの環境構築はかなり楽（参考になるブログが多数あるので）だと思います．
しかしエディタを使った開発の場合，OpenCVの設定が少し面倒だったので，開発環境の構築について（主にビルドすることを目標として）自分用に少しメモを残しておきます．

（そこまで深く理解しているわけではないので，誤った記述があるかもしれません．あくまで自分用メモです．）


## 目的
OpenCVを使ったソースファイルを**コマンドラインからビルド出来る**ようになること．


## とりあえずOpenCVのサンプルを動かす
実行環境は次の通りです．

- OS : macOS High Sierra (version 10.13.6)
- コンパイラ : g++, Apple LLVM version 9.1.0 (clang-902.0.39.2)
- pkg-cofig : version 0.29.2
- OpenCV : version 3.4.2

g++, pkg-config, OpenCVのインストールがまだの場合は，事前にインストールしておいてください．

### 実行手順1. 環境の用意
OpenCVのサンプルコードであればなんでもいいかと思います．  

もしなければ，次のサンプルを使って下さい．
[https://github.com/hsmtknj/opencvsample](https://github.com/hsmtknj/opencvsample)

`git clone https://github.com/hsmtknj/opencvsample.git`
でまるまる環境を落とせるかと思います．

### 実行手順2. ビルド
OpenCVを使ったソースファイルがあるディレクトリに移動して（先ほどサンプルをダウンロードした場合は`opencvsample`ディレクトリ内に移動），次のコマンドを打って下さい．

```bash
# cppファイルをビルドして，実行ファイルを作成します
g++ sample1.cpp -o sample1.out `pkg-config --cflags opencv` `pkg-config --libs opencv`
```

`sample1.cpp`や`sample1.out`は自分の環境に合わせて，適宜変更して下さい．  
そうすると，実行ファイルが生成されるかと思います．（先ほど環境をダウンロードした場合は，`sample1.out` ができているかと思います．）

あとは以下のコマンドを実行することで，とりあえず動くかと思います．

```bash
# 作成された実行ファイルを実行します
./sample1.out
```


## コマンドラインからの実行を楽にするMakefileやCMake
OpenCVを使ったソースファイルをコマンドラインからビルドする際に，MakefileやCMakeがどのように関わってくるか分からなかったので，以下に大きな流れをまとめてみました．

先ほど，とりあえずOpenCVのサンプルを動かしたのは以下の"1."を実行したことになるかと思います．

1. コマンドラインから`pkg-config`を使ってOpenCVを使ったファイルをビルドする
    - コンパイラでビルドするときに，オプションで`pkg-config`を使う
2. 毎回コマンドラインから実行するのは面倒なので，`Makefile`スクリプトを書く
    - `make`コマンド一発でビルドできるようになる
3. `Makefile`スクリプトすら編集するのが面倒なので`CMake`を使う
    - `CMakeLists.txt`を用意することで，`Makefile`を自動で生成してくれる


### コマンドラインから実行
こちらのブログが大変参考になります．

- [LinuxでOpenCVを入れて適当なコードをコンパイルするまで](http://www.yasutomo57jp.com/2010/09/01/linuxでopencvを入れて適当なコードをコンパイルするまで/)

コマンドラインから`pkg-config`を使ってコンパイラでコンパイル・ビルドする方法について書かれています．
`pkg-config`を利用すると**OpenCVのリンカなど面倒な部分の設定**を全部上手くやってくれるっぽいです．  

使い方は大変シンプルで，ビルド時に以下のようにコンパイラに`pkg-config`のオプションをつけるだけです．コンパイラは代表的な`g++`を利用していますが，お好みのコンパイラで良いと思います．

```bash
g++ sample1.cpp -o sample1.out `pkg-config --cflag opencv` `pkg-config --libs opencv`
```

これで，sample1.cppから実行ファイルsample1.outが出来ると思います．あとは以下のコマンドで実行ファイルを実行できます．

```bash
./sample1.out
```

#### 参考  
このあたりで，コンパイルとビルドが同じものだと思っていたり，オブジェクトコードやリンカの話が全くわからない場合，話が分からなくなってくると思うので参考までに  

- [ビルドとコンパイルの違い](https://qiita.com/rico/items/9ab8aa110e757a13ef37)


## 毎回コマンドラインからの実行は面倒
ソースファイルを変更して，いちいちコマンドラインからビルドコマンドを入力するのは面倒です．
そこで，`Makefile`を使って簡単にコマンドラインからビルドする方法があります．
これは，先ほどの

```bash
g++ sample1.cpp -o sample1.out `pkg-config --cflag opencv` `pkg-config --libs opencv`
```

のようなコマンドを`Makefile`と呼ばれるスクリプトにあらかじめ記述しておくことで，`make`というコマンドをひとつ打つだけで実行できるようにするものです．

### Makefileのサンプル

次のようにMakefileスクリプトを記述してみました．

```makefile

sample1: sample1.cpp
	# build sample1.cpp
	g++ sample1.cpp -o sample1.out `pkg-config --cflags opencv` `pkg-config --libs opencv`
	# execute
	./sample1.out
	# delete execution file
	rm sample1.out

sample2: sample2.cpp
	# build sample2.cpp
	g++ sample2.cpp -o sample2.out `pkg-config --cflags opencv` `pkg-config --libs opencv`
	# execute
	./sample2.out
	# delete execution file
	rm sample2.out
```

このようにコマンドをあらかじめ，設定しておくと楽になります．

先ほどの[https://github.com/hsmtknj/opencvsample](https://github.com/hsmtknj/opencvsample)には上記のMakefileを含めた`make`コマンドを試す環境を用意しています．

このディレクトリを落としてきて，ディレクトリ内で

```bash
# makefileに書いた"sample1"の方を実行します
make sample1
```

```bash
# makefileに書いた"sample2"の方を実行します
make sample2
```

上記のmakeコマンドをコマンドラインから試すと，ソースファイルのビルドから実行まで行う様子を見ることができると思います．

Makefileの使い方について以下のブログが参考になるかと思います．
[トリビアなmakefile入門](http://www.jsk.t.u-tokyo.ac.jp/~k-okada/makefile/)

## Makefile の編集すら面倒
そういった場合に**CMake**が活躍します．  
`CMakeLists.txt`にコンパイル・ビルド，オプション情報などを事前に記述しておくことで，`Makefile`のスクリプトを自動で生成してくれます．

CMakeの使い方は，以下のブログが大変分かりやすいです．（本当に分かりやすい）  

- [CMakeの使い方（その１）](https://qiita.com/shohirose/items/45fb49c6b429e8b204ac)
- [CMakeの使い方（その２）](https://qiita.com/shohirose/items/637f4b712893764a7ec1)
- [CMakeの使い方（その３）](https://qiita.com/shohirose/items/d2b9c595a37b27ece607#_reference-657e6b4e992f54a415a7)


## まとめ
`pkg-config`や`Makefile`，`CMake`を利用することで，コンパイラでターミナルからOpenCVをビルドすることができました．  

ご利用のエディタでさらに凝った設定をすると，コマンドラインからではなくエディタのショートカット等で簡単にファイルの実行できそうですね．  

### 備考
今回あわててまとめたので，大幅に記事を変更する可能性があります．ご了承ください．