C++初心者がMacでパッケージ管理ツールVcpkgを試してみたらハマったけど利用できた

前にConanというC++のパッケージ管理ツールを試してみたのですが、Microsoftさんもパッケージ管理ツールをリリースしているとのことでお試ししてみました。  

Microsoft/vcpkg: C++ Library Manager for Windows, Linux, and MacOS
https://github.com/Microsoft/vcpkg/

【速報】Vcpkg: Windowsの公式C++ライブラリ管理ツール
https://techracho.bpsinc.jp/hachi8833/2016_09_20/26104


こちらもConanと同じく複数のプラットフォームとビルドシステム(VSとCMake)に対応しており、選択肢のひとつとしてありっぽいです。  

利用するライブラリはConanをお試ししたときと同じでPOCOを利用します。  

POCO C++ Libraries - Simplify C++ Development
https://pocoproject.org/



~~## お詫び~~

~~結論だけ、書く。~~

~~失敗した失敗した失敗した失敗した失敗した~~
~~失敗した失敗した失敗した失敗した失敗した(略)~~

~~最後まで読んでいただけたらわかりますが、最終的にうまく利用できませんでした。~~
~~こうすれば動いたよーとか情報があれば嬉しいです！~~


## 追記

### 2019/02/07

@shohiroseさんと@yumetodoさんにコメントいただき、Vcpkgを利用してビルドして実行できるようになりました。
ありがとうございます！！！


## 環境・前提条件

```sh
> sw_vers
ProductName:    Mac OS X
ProductVersion: 10.13.6
BuildVersion:   17G4015

# あとでg++8に変更することになります
> g++ -v
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

# あとでgcc-8に変更することになります
> gcc -v
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

> git --version
git version 2.19.1

# CMakeを利用します
> cmake --version
cmake version 3.13.3

CMake suite maintained and supported by Kitware (kitware.com/cmake).
```

CMakeってなにそれという方はこちらをご参考ください。

C++初心者がMacでCMakeを利用してみる - Qiita
https://qiita.com/kai_kou/items/df335eb7ee78229ee46f



## インストール

リポジトリのREADMEを参考にインストールします。

Microsoft/vcpkg: C++ Library Manager for Windows, Linux, and MacOS
https://github.com/Microsoft/vcpkg/


```sh
> mkdir 任意のディレクトリ
> cd 任意のディレクトリ

> git clone https://github.com/Microsoft/vcpkg.git
> ./vcpkg/bootstrap-vcpkg.sh
(略)
CMake Error at CMakeLists.txt:10 (message):
  Building the vcpkg tool requires support for the C++ Filesystem TS.

  Apple clang versions 9 and below do not have support for it.

  Please install gcc6 or newer from homebrew (brew install gcc6).

  If you would like to try anyway, set VCPKG_ALLOW_APPLE_CLANG.

-- Configuring incomplete, errors occurred!
See also "任意のディレクトリ/vcpkg/toolsrc/build.rel/CMakeFiles/CMakeOutput.log".
ninja: error: loading 'build.ninja': No such file or directory
cp: 任意のディレクトリ/vcpkg/toolsrc/build.rel/vcpkg: No such file or directory
```

エラーになりました。`gcc6` ってのをインストールしなきゃいけないとのことです。  
手っ取り早く`VCPKG_ALLOW_APPLE_CLANG` を設定して実行してみましたが、`1` 'true' を設定してみましたが、変わらずでした。。。Issuesもちらほらと上がっています。  

vcpkg install fails on macOS High Sierra · Issue #3529 · Microsoft/vcpkg
https://github.com/Microsoft/vcpkg/issues/3529

Apple clang versions 9 and below do not have support for it. · Issue #4475 · Microsoft/vcpkg
https://github.com/Microsoft/vcpkg/issues/4475

仕方ないので、GCCをインストールします。  

```sh
> brew install gcc
```

このままだとパスが通ってないので、通します。  
下記を参考にさせてもらいました。  

Macのgcc, g++をHomebrewを使って最新版にする - Qiita
https://qiita.com/wawawa/items/50c2c612b0937f28d92b


```sh:gcc
> gcc -v

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

> ls /usr/local/bin | grep gcc
gcc-8
gcc-ar-8
gcc-nm-8
gcc-ranlib-8
x86_64-apple-darwin17.7.0-gcc-8
x86_64-apple-darwin17.7.0-gcc-8.2.0
x86_64-apple-darwin17.7.0-gcc-ar-8
x86_64-apple-darwin17.7.0-gcc-nm-8
x86_64-apple-darwin17.7.0-gcc-ranlib-8

> ln -s /usr/local/bin/gcc-8 /usr/local/bin/gcc

> gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/8.2.0/libexec/gcc/x86_64-apple-darwin17.7.0/8.2.0/lto-wrapper
Target: x86_64-apple-darwin17.7.0
Configured with: ../configure --build=x86_64-apple-darwin17.7.0 --prefix=/usr/local/Cellar/gcc/8.2.0 --libdir=/usr/local/Cellar/gcc/8.2.0/lib/gcc/8 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-8 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --with-pkgversion='Homebrew GCC 8.2.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-multilib
Thread model: posix
gcc version 8.2.0 (Homebrew GCC 8.2.0)
```

```sh:g++
> g++ -v

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

> ls /usr/local/bin | grep g++
g++-8
x86_64-apple-darwin17.7.0-g++-8

> g++ -v

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/8.2.0/libexec/gcc/x86_64-apple-darwin17.7.0/8.2.0/lto-wrapper
Target: x86_64-apple-darwin17.7.0
Configured with: ../configure --build=x86_64-apple-darwin17.7.0 --prefix=/usr/local/Cellar/gcc/8.2.0 --libdir=/usr/local/Cellar/gcc/8.2.0/lib/gcc/8 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-8 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --with-pkgversion='Homebrew GCC 8.2.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-multilib
Thread model: posix
gcc version 8.2.0 (Homebrew GCC 8.2.0)
```

さきほどエラーになったところから再開します。  

```sh
> ./vcpkg/bootstrap-vcpkg.sh

-- The C compiler identification is AppleClang 10.0.0.10001044
-- The CXX compiler identification is GNU 8.2.0
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Checking whether CXX compiler has -isysroot
-- Checking whether CXX compiler has -isysroot - yes
-- Checking whether CXX compiler supports OSX deployment target flag
-- Checking whether CXX compiler supports OSX deployment target flag - yes
-- Check for working CXX compiler: /usr/local/bin/g++-8
-- Check for working CXX compiler: /usr/local/bin/g++-8 -- works
(略)
-- Configuring done
-- Generating done
-- Build files have been written to: 任意のディレクトリ/vcpkg/toolsrc/build.rel
[64/64] Linking CXX executable vcpkg
```

今度はエラーなく実行できました。続けて進めます。  

```sh
> ./vcpkg integrate install

Applied user-wide integration for this vcpkg root.

CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=任意のディレクトリ/vcpkg/scripts/buildsystems/vcpkg.cmake"
```

### パッケージのインストール

Vcpkgが利用できるようになったので、コマンドを叩いてみます。  

```sh
> ./vcpkg
Commands:
  vcpkg search [pat]              Search for packages available to be built
  vcpkg install <pkg>...          Install a package
  vcpkg remove <pkg>...           Uninstall a package
  vcpkg remove --outdated         Uninstall all out-of-date packages
  vcpkg list                      List installed packages
  vcpkg update                    Display list of packages for updating
  vcpkg upgrade                   Rebuild all outdated packages
  vcpkg hash <file> [alg]         Hash a file by specific algorithm, default SHA512
  vcpkg help topics               Display the list of help topics
  vcpkg help <topic>              Display help for a specific topic

  vcpkg integrate install         Make installed packages available user-wide.
  vcpkg integrate remove          Remove user-wide integration

  vcpkg export <pkg>... [opt]...  Exports a package
  vcpkg edit <pkg>                Open up a port for editing (uses $EDITOR, default 'code')
  vcpkg import <pkg>              Import a pre-built library
  vcpkg create <pkg> <url>
             [archivename]        Create a new package
  vcpkg owns <pat>                Search for files in installed packages
  vcpkg env                       Creates a clean shell environment for development or compiling.
  vcpkg version                   Display version information
  vcpkg contact                   Display contact information to send feedback

Options:
  --triplet <t>                   Specify the target architecture triplet.
                                  (default: $VCPKG_DEFAULT_TRIPLET, see 'vcpkg help triplet')

  --vcpkg-root <path>             Specify the vcpkg root directory
                                  (default: $VCPKG_ROOT)

  @response_file                  Specify a response file to provide additional parameters

For more help (including examples) see the accompanying README.md.
```

POCOを探してインストールしてみます。  

```sh
> ./vcpkg search poco

poco                 1.9.0-1          Modern, powerful open source C++ class libraries for building network and inte...
poco[mysql]                           Mysql support for POCO

If your library is not listed, please open an issue at and/or consider making a pull request:
    https://github.com/Microsoft/vcpkg/issues


> ./vcpkg list
No packages are installed. Did you mean `search`?

> ./vcpkg install poco
(略)
Total elapsed time: 11.07 min

The package poco:x64-osx provides CMake targets:

    find_package(Poco CONFIG REQUIRED)
    # Note: 8 target(s) were omitted.
    target_link_libraries(main PRIVATE Poco::Net Poco::XML Poco::Zip Poco::Data)

> ./vcpkg list

> ./vcpkg list
expat:x64-osx                                      2.2.6            XML parser library written in C
pcre:x64-osx                                       8.41-1           Perl Compatible Regular Expresions
poco:x64-osx                                       1.9.0-1          Modern, powerful open source C++ class libraries...
sqlite3:x64-osx                                    3.26.0           SQLite is a software library that implements as...
zlib:x64-osx                                       1.2.11-3         A compression library
```

インストールできました。ビルドされたライブラリは`vcpkg/installed` 配下に配置されるようです。  

```sh
> ls ../vcpkg/installed/x64-osx/include/
Poco               pcre.h             pcrecpp.h          sqlite3.h          zlib.h
expat.h            pcre_scanner.h     pcrecpparg.h       sqlite3ext.h
expat_external.h   pcre_stringpiece.h pcreposix.h        zconf.h
```

### 実装してビルド

POCOライブラリを利用した実装をしてみます。以下のサンプルを利用させてもらいました。

POCO C++ Libraries の簡単な使用方法 - Qoosky
https://www.qoosky.io/techs/8e92d3d34a


```sh
> cd 任意のディレクトリ
> touch poco_sample.cpp
> touch CMakeLists.txt
```

```cpp:poco_sample.cpp
#include <iostream>
#include <Poco/RegularExpression.h>

int main() {
    Poco::RegularExpression regexp("^[a-zA-Z]+");

    std::string buf;
    regexp.extract("ABC123", buf);
    std::cout << buf << std::endl;

    return 0;
}
```

POCOライブラリを読み込むのに、`./vcpkg install poco`実行時に出力される`find_package`と`target_link_libraries`だとうまくビルドすることができないのでご注意ください。(1敗
詳細はのちほど記載しています。

```txt:CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(VcpkgSample)

include(任意のディレクトリ/vcpkg/scripts/buildsystems/vcpkg.cmake)

find_package(Poco CONFIG REQUIRED Foundation)

find_path(PCRE_INCLUDE_DIR pcre.h)
if(CMAKE_BUILD_TYPE STREQUAL Debug)
    set(PCRE_SUFFIX d)
endif()
find_library(PCRE_LIBRARY NAMES pcre${PCRE_SUFFIX} pcre)
include_directories(${PCRE_INCLUDE_DIR})

add_executable(poco_sample poco_sample.cpp)
target_link_libraries(poco_sample PRIVATE Poco::Foundation ${PCRE_LIBRARY})
```

`cmake` コマンドを実行してみます。  

```sh
> mkdir build
> cd build
> cmake ..

-- The C compiler identification is AppleClang 10.0.0.10001044
-- The CXX compiler identification is AppleClang 10.0.0.10001044
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
(略)
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/kai/dev/cpp/vcpkg-sample/build

> cmake --build .

Scanning dependencies of target poco_sample
[ 50%] Building CXX object CMakeFiles/poco_sample.dir/poco_sample.cpp.o
[100%] Linking CXX executable poco_sample
[100%] Built target poco_sample
```

ビルドができたので実行してみます。

```sh
> ./poco_sample
ABC
```

やったぜ。


## 落とし穴

最初、`./vcpkg install poco`コマンド実行で出力される`CMakeLists.txt` の定義をそのまま利用してビルドしようとしましたが、それだとエラーになりました。


```txt:CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(VcpkgSample)

include(任意のディレクトリ/vcpkg/scripts/buildsystems/vcpkg.cmake)

find_package(Poco CONFIG REQUIRED)

add_executable(poco_sample poco_sample.cpp)
target_link_libraries(poco_sample PRIVATE Poco::Net Poco::XML Poco::Zip Poco::Data)
```

```sh
> cmake ..
(略)
CMake Error at vcpkg/scripts/buildsystems/vcpkg.cmake:247 (_find_package):
  Found package configuration file:

    任意のディレクトリ/vcpkg/installed/x64-osx/share/poco/PocoConfig.cmake

  but it set Poco_FOUND to FALSE so package "Poco" is considered to be NOT
  FOUND.  Reason given by package:

  The Poco package requires at least one component

Call Stack (most recent call first):
  CMakeLists.txt:6 (find_package)


-- Configuring incomplete, errors occurred!
See also "任意のディレクトリ/build/CMakeFiles/CMakeOutput.log".
```

@shohiroseさんからコメントをいただき、`The Poco package requires at least one component` とエラーメッセージが出力されているので、なにかしらコンポーネントを指定する必要があると教えていただきました。

https://qiita.com/kai_kou/items/4dbe5b920a8598891ec7#comment-334a622a3cf6cdf9a681

c++ - Using cmake for a project with sub/external projects/dependencies - Stack Overflow
https://stackoverflow.com/questions/36122833/using-cmake-for-a-project-with-sub-external-projects-dependencies


んで、どうやって`CMakeLists.txt`で指定すればよいのか悩んでいたら、@yumetodoさんからコメントをいただき、指定方法を教えていただき、無事にビルド＆実行することができました。

https://qiita.com/kai_kou/items/4dbe5b920a8598891ec7#comment-52c3cd78c8faa851bb39

vcpkg/CMakeLists.txt at 984d95fa5f8892b1065d158a1d97ef70d00485e6 · Microsoft/vcpkg
https://github.com/Microsoft/vcpkg/blob/984d95fa5f8892b1065d158a1d97ef70d00485e6/ports/glib/CMakeLists.txt#L24-L29


## 参考

Microsoft/vcpkg: C++ Library Manager for Windows, Linux, and MacOS
https://github.com/Microsoft/vcpkg/

【速報】Vcpkg: Windowsの公式C++ライブラリ管理ツール
https://techracho.bpsinc.jp/hachi8833/2016_09_20/26104

POCO C++ Libraries - Simplify C++ Development
https://pocoproject.org/

C++初心者がMacでCMakeを利用してみる - Qiita
https://qiita.com/kai_kou/items/df335eb7ee78229ee46f

vcpkg install fails on macOS High Sierra · Issue #3529 · Microsoft/vcpkg
https://github.com/Microsoft/vcpkg/issues/3529

Apple clang versions 9 and below do not have support for it. · Issue #4475 · Microsoft/vcpkg
https://github.com/Microsoft/vcpkg/issues/4475

Macのgcc, g++をHomebrewを使って最新版にする - Qiita
https://qiita.com/wawawa/items/50c2c612b0937f28d92b

@shohiroseさんからのコメント
https://qiita.com/kai_kou/items/4dbe5b920a8598891ec7#comment-334a622a3cf6cdf9a681

c++ - Using cmake for a project with sub/external projects/dependencies - Stack Overflow
https://stackoverflow.com/questions/36122833/using-cmake-for-a-project-with-sub-external-projects-dependencies

@yumetodoさんからのコメント
https://qiita.com/kai_kou/items/4dbe5b920a8598891ec7#comment-52c3cd78c8faa851bb39

vcpkg/CMakeLists.txt at 984d95fa5f8892b1065d158a1d97ef70d00485e6 · Microsoft/vcpkg
https://github.com/Microsoft/vcpkg/blob/984d95fa5f8892b1065d158a1d97ef70d00485e6/ports/glib/CMakeLists.txt#L24-L29