yumetodoの旅とプログラミングとかの記録

旅や登山の記録やプログラミング関連の話とかフリーソフト紹介とか

CMakeからVisual Stduo 2017でコンパイルしたBoostを探すのは時期尚早かも

Visual Studio 2017がリリースした

さて、Visual Stduo 2017が出てすでに1ヶ月経った。私も重い腰を上げて導入した。

www.visualstudio.com

をみると割りと頻繁にアップデートが来ていたりする。

Visual Studio 2017でBoost 1.63.0をコンパイルする

現在Boostの最新はBoost 1.63.0だ。しかしこいつは2016/12/26に出ており、2017/3/7に出たVisual Studio 2017に対応しているはずもない。

[Boost-users] Building Boost 1.62 With Visual Studio 2017 RC - Google グループ

そこでちょっと小細工をする。Boostのソースをダウンロードして展開した時にroot directoryにproject-config.jamがあると思うが、これを書き換える。パスは適宜読み替えてほしい。

x86向け
import option ; 
 
using msvc : 14.1 : "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX86\x86\cl.exe"; 
 
option.set keep-going : false ; 
 

のように書き換えて

b2 toolset=msvc-14.1 threading=multi variant=debug,release link=static runtime-link=static address-model=32 --stagedir=stage/x86 -j 4 -s BZIP2_SOURCE="D:/lib/bzip2-1.0.6" -s ZLIB_SOURCE="D:/lib/zlib-1.2.11"
b2 toolset=msvc-14.1 threading=multi variant=debug,release link=shared runtime-link=shared address-model=32 --stagedir=stage/x86 -j 4 -s BZIP2_SOURCE="D:/lib/bzip2-1.0.6" -s ZLIB_SOURCE="D:/lib/zlib-1.2.11"

の用に実行する

x64向け
import option ; 
 
using msvc : 14.1 : "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX64\x64\cl.exe"; 
 
option.set keep-going : false ; 
 

のように書き換えて

b2 toolset=msvc-14.1 threading=multi variant=debug,release link=static runtime-link=static address-model=64 --stagedir=stage/x64 -j 4 -s BZIP2_SOURCE="D:/lib/bzip2-1.0.6" -s ZLIB_SOURCE="D:/lib/zlib-1.2.11"
b2 toolset=msvc-14.1 threading=multi variant=debug,release link=shared runtime-link=shared address-model=64 --stagedir=stage/x64 -j 4 -s BZIP2_SOURCE="D:/lib/bzip2-1.0.6" -s ZLIB_SOURCE="D:/lib/zlib-1.2.11"

の用にコンパイルします。

ちなみに、Boost1.64.0 Beta2ではproject-config.jamをいじらずとも対応しているそうです。

Visual Stduo 2017のcl.exeのバージョンは?

Visual Stduo 2017は当初cl.exeのバージョンが15.xになると思われていました。しかし、Visual Studio2015付属のcl.exeとの間でバイナリ互換になったため、14.10.xになりました。

github.com

CMakeからBoostを使う

には、find_packageを使うのが一般的です。

FindBoost — CMake 3.7.2 Documentation

CMakeの最新は3.7.2です。早速使ってみましょう

# find Boost
set(BOOST_ROOT ${BOOST_ROOT} CACHE PATH "Set boost root directory" FORCE)
set(BOOST_LIBRARYDIR ${BOOST_LIBRARYDIR} CACHE PATH "Set boost library directory" FORCE)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(Boost_DEBUG ON)
set(boost_required_components
    system iostreams thread
)
find_package(Boost 1.59 REQUIRED COMPONENTS ${boost_required_components})
CMake Error at C:/Program Files/CMake/share/cmake-3.7/Modules/FindBoost.cmake:1812 (message):
  Unable to find the requested Boost libraries.

  Boost version: 1.63.0

  Boost include path: D:/lib/boost_1_63_0

  Could not find the following static Boost libraries:

          boost_system
          boost_iostreams
          boost_thread

  Some (but not all) of the required Boost libraries were found.  You may
  need to install these additional Boost libraries.  Alternatively, set
  BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT
  to the location of Boost.
Call Stack (most recent call first):
  CMakeLists.txt:41 (find_package)

見事エラーになります。

CMakeがコケる原因
set(Boost_DEBUG ON)

して調べたところ、

[ C:/Program Files/CMake/share/cmake-3.7/Modules/FindBoost.cmake:1291 ] guessed _boost_COMPILER = -vc150

というDebug Printが。ん?-vc150

https://github.com/Kitware/CMake/blob/v3.7.2/Modules/FindBoost.cmake#L429-L431

  elseif("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
    if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10)
      set(_boost_COMPILER "-vc150")

上に書いたように、cl.exeのバージョンは14.10.xなのでこれはおかしいです。このせいでboost_xxx_-vc150-mt-yyy-1_63を探しに行っていたようです。そりゃ見つかるわけ無いわ。

改善の予兆

CMake3.8.0-rc3ではこの問題が治っているようです。該当commitは

github.com github.com

結論

もうちょっとだけいろいろ待ったほうが良さげ

と言いたいところだが、待てない。

github.com

if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 3.8)
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/modules)
    include(FindBoost)
    message(STATUS "FindBoost: commit fb3f6fd3fe8eb2ebef26c6fa20624f32ee272760 is used.")
endif()

のようにしてcmakeのmaster branchから最新のFindBoost.cmakeを拾ってきた。

多分cmake3.8になれば解決しているはずなので一時的なwork aroundなのでcmakeのバージョンを見て分岐する。

あと、Boost_USE_DEBUG_RUNTIMEがOFFのとき、lib検索にバグがあるので

gitlab.kitware.com

CMake3.9.0まで待つか自分でFindBoostを引っ張ってくるべきでしょう。

追記

いつの間にかBoost1.64.0もcmake3.9.0も出ていますね。