MacでC++を使ってOpenCVをした時の詰まったとこまとめて見た

#はじめに
某勉強会に参加した時に,MacでC++を使ってOpenCVをやろうとしたけど,詰まったのでその覚書き的な何かです.だから解説とかはあんまり入れない予定です.

#その1: Visual StdioでC++が書けない

あまり詳しい確認を取っていませんが,Visual Stdio for Mac(2017)ではデフォルトではC#とF#しかなく,C++はサポートされていないようでした.ですので,この時点でVisual Stdioは容量の肥やしになったのでさよならしました.

##解決策

で,使えないなら勉強会のお話が全くの無駄になってしまうので解決策を探すと普通にHomebrewからgcc入れたらいけそうだったのでそれで行きました.

Homebrewの導入は各自調べてください.gccは普通に
`$ brew install gcc`で入れました.

#その２: 動かないOpenCV

C++を動かす環境はできたのでOpenCVのホームページから早速OpenCVをダウンロードしてきて,試しにチュートリアルを試そうとしたら,

```
Undefined symbols for architecture x86_64:
  "cv::namedWindow(cv::String const&, int)", referenced from:
      _main in contour2-2f3230.o
  "cv::approxPolyDP(cv::_InputArray const&, cv::_OutputArray const&, double, bool)", referenced from:
      _main in contour2-2f3230.o
  "cv::drawContours(cv::_InputOutputArray const&, cv::_InputArray const&, int, cv::Scalar_<double> const&, int, int, cv::_InputArray const&, int, cv::Point_<int>)", referenced from:
      on_trackbar(int, void*) in contour2-2f3230.o
  "cv::findContours(cv::_InputOutputArray const&, cv::_OutputArray const&, cv::_OutputArray const&, int, int, cv::Point_<int>)", referenced from:
      _main in contour2-2f3230.o
  "cv::createTrackbar(cv::String const&, cv::String const&, int*, int, void (*)(int, void*), void*)", referenced from:
      _main in contour2-2f3230.o
  "cv::CommandLineParser::CommandLineParser(int, char const* const*, cv::String const&)", referenced from:
      _main in contour2-2f3230.o
  "cv::CommandLineParser::~CommandLineParser()", referenced from:
      _main in contour2-2f3230.o
  "cv::Mat::deallocate()", referenced from:
      cv::Mat::release() in contour2-2f3230.o
  "cv::Mat::updateContinuityFlag()", referenced from:
      cv::Mat::Mat(int, int, int, void*, unsigned long) in contour2-2f3230.o
  "cv::Mat::zeros(int, int, int)", referenced from:
      _main in contour2-2f3230.o
      on_trackbar(int, void*) in contour2-2f3230.o
  "cv::line(cv::_InputOutputArray const&, cv::Point_<int>, cv::Point_<int>, cv::Scalar_<double> const&, int, int, int)", referenced from:
      _main in contour2-2f3230.o
  "cv::error(int, cv::String const&, char const*, char const*, int)", referenced from:
      cv::Mat::Mat(int, int, int, void*, unsigned long) in contour2-2f3230.o
  "cv::String::deallocate()", referenced from:
      cv::String::~String() in contour2-2f3230.o
  "cv::String::allocate(unsigned long)", referenced from:
      cv::String::String(char const*) in contour2-2f3230.o
  "cv::imshow(cv::String const&, cv::_InputArray const&)", referenced from:
      _main in contour2-2f3230.o
      on_trackbar(int, void*) in contour2-2f3230.o
  "cv::ellipse(cv::_InputOutputArray const&, cv::Point_<int>, cv::Size_<int>, double, double, double, cv::Scalar_<double> const&, int, int, int)", referenced from:
      _main in contour2-2f3230.o
  "cv::waitKey(int)", referenced from:
      _main in contour2-2f3230.o
  "cv::fastFree(void*)", referenced from:
      cv::Mat::~Mat() in contour2-2f3230.o
  "cv::CommandLineParser::has(cv::String const&) const", referenced from:
      _main in contour2-2f3230.o
  "cv::Mat::copyTo(cv::_OutputArray const&) const", referenced from:
      cv::Mat::Mat<cv::Point_<int> >(std::__1::vector<cv::Point_<int>, std::__1::allocator<cv::Point_<int> > > const&, bool) in contour2-2f3230.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```
とまあ,クッソ長ったらしいエラーが出たんで,色々調べたらコンパイルする時に最初は
`$ g++ hoge.cpp`
とやっていたんですが,これがダメだったっぽいんで
`` $ clang++ hoge.cpp -o hoge `pkg-config --cflags --libs opencv` ``
これでいけました.             
                                                                                 
なお,ここに行く間に
`$  brew install opencv`
をやってるので,果たしてダウンロードしてるopencvが使われてるのか,brewからinstallされたものが使われているのかは定かではないです.

#番外編: pkg-configが機能しない

自分の環境では起きなかった事例ですが,勉強会に参加していた他のMacユーザーの人がエラーが出てコンパイルできないということで助っ人に行ったらpkg-congigがどうやら動いていなかった模様.

なのでとりあえず,
`$ brew info opencv`
としてあげると,pkg-configのところで赤いバツ印が付いていたので,
`$ brew install pkg-config`
としてあげてコンパイルすると動きました.

あと,勉強会の最後あたりでカメラを起動させるプログラムを書いたのですが,WindowsのVisual Stdioを使ってる人はコードは

```
void main()
{
......
}
```
で動いてたっぽいですが,clang++使ってるのかどうかなのかは分かりませんが,

```
int main()
{
......
    return 0;
}
```

としてあげないと,コンパイルエラーが出てきました.
この辺はC++普段全く触らない自分からしたら謎なんですが,誰か知ってたら教えてください.

#最後に

というわけで,MacでC++を使ってOpenCVする時に詰まった点の紹介でした.なぜVisual Stdio　for MacではC++が書けないのか全く謎でしたね.何か理由があるのかな?

さて,今回はこんな感じで終了です.いつになるかは未定ですがElixirの記事また書きます.ではまた.