見出し画像

Boost C++ライブラリは好きかい?with CMake

以下の話は MacOSでHomeBrewでインストールしたBoostを使っている前提

CMP0167って何?

ある日 CMakeをアップデートしたら、

ねぇねぇ今度からFindBoostやめてくんない?
詳しくはCMP0167を見てというメッセージが出てきた(超大幅意訳)

調べてみた
簡単に言えば、FindBoostモジュールを止めるって内容
代わりに通常のfind_packageモジュールを使えってさ
https://cmake.org/cmake/help/latest/policy/CMP0167.html

えー、なんだよ
CMakeがBoostだけ特別ね!って用意してくれていたから使っていたのに
もう特別な関係じゃないって事ですか(そういう意味ではないと思うけど)
CMake 3.30以降でそういう事になったって話です

$ cmake --version
cmake version 3.31.2

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


という事で、find_packeageモジュールでの動作確認を兼ねてBoost用のCMake用モジュールを再作成及びテストを行いました。

再作成の方針

  • 今迄は個人用の開発システムなので作法とか気にせずにいたが拡張用のモジュールを .cmake の拡張子で扱うファイルとして独立させた

  • ヘッダーだけを要求するライブラリもあるので指定ができるようにした

  • 最新のバージョンでリンク可能な共有ライブラリをリストして追加・削除する方式とした

ファイル名は boost.cmake (任意ですが)

使い方は簡単
CMakeLists.txtのなるべく下の方で下記のコードを追加する

# boost.cmake
include(boost.cmake)

私は、CMakeLists.txtと同じディレクトリに boost.cmake として配置している

使うライブラリのコメントを外す・または不要なライブラリの記述をコメントする

Boostには、ヘッダーのみを必要とするライブラリ(機能?)があるので、その場合には、Boost::headersを使う
ヘッダーだけインクルードしても使用しないとコードに反映されないので常にインクルードしても問題ない
これだけはコメントを外しておいた方が良いと思う(まぁ個人の判断)

この boost.cmakeをインクルードして、ヘッダーも読み込まない指定をして全くboostを読み込まない状態に記述された場合には、FATAL_ERROR でメッセージを表示してからCMakeLists.txtの処理を止めるようにしている
この辺はお好みで変更すれば良いと思う

# Boost configuration script - 20241217

# Step 1: Display a message indicating Boost C++ libraries are being configured.
message(STATUS "Configuring Boost C++ source libraries.")

# Step 2: Locate Boost using the CMake CONFIG mode.
find_package(Boost REQUIRED CONFIG)

# Step 3: Locate the Homebrew installation directory.
# The `brew --prefix` command is executed to find the root path of Homebrew installation.
# The result is stored in the variable `BREW_DIR` and any trailing whitespace is stripped.
execute_process(COMMAND brew --prefix OUTPUT_VARIABLE BREW_DIR)
string(STRIP ${BREW_DIR} BREW_DIR)

# Step 4: Set the include and library paths for the project based on the Homebrew directory.
# This ensures the Boost libraries and headers installed via Homebrew are used during compilation and linking.
target_link_directories(${PROJECT_NAME} PRIVATE "${BREW_DIR}/lib")
target_include_directories(${PROJECT_NAME} PRIVATE "${BREW_DIR}/include")

# Step 5: Define the list of dynamic Boost libraries to be linked with the project.
# The list may include multiple Boost libraries depending on project requirements.
set(BOOST_DYNAMIC_LIBS 
    Boost::headers
    # libboost_atomic-mt.dylib
    # libboost_charconv-mt.dylib
    # libboost_charconv.dylib
    # libboost_chrono-mt.dylib
    # libboost_chrono.dylib
    # libboost_container-mt.dylib
    # libboost_container.dylib
    # libboost_context-mt.dylib
    # libboost_contract-mt.dylib
    # libboost_contract.dylib
    # libboost_coroutine-mt.dylib
    # libboost_coroutine.dylib
    # libboost_date_time-mt.dylib
    # libboost_date_time.dylib
    # libboost_fiber-mt.dylib
    # libboost_filesystem-mt.dylib
    # libboost_filesystem.dylib
    # libboost_graph-mt.dylib
    # libboost_graph.dylib
    # libboost_iostreams-mt.dylib
    # libboost_iostreams.dylib
    # libboost_json-mt.dylib
    # libboost_json.dylib
    # libboost_locale-mt.dylib
    # libboost_log-mt.dylib
    # libboost_log.dylib
    # libboost_log_setup-mt.dylib
    # libboost_log_setup.dylib
    # libboost_math_c99-mt.dylib
    # libboost_math_c99.dylib
    # libboost_math_c99f-mt.dylib
    # libboost_math_c99f.dylib
    # libboost_math_c99l-mt.dylib
    # libboost_math_c99l.dylib
    # libboost_math_tr1-mt.dylib
    # libboost_math_tr1.dylib
    # libboost_math_tr1f-mt.dylib
    # libboost_math_tr1f.dylib
    # libboost_math_tr1l-mt.dylib
    # libboost_math_tr1l.dylib
    # libboost_nowide-mt.dylib
    # libboost_nowide.dylib
    # libboost_prg_exec_monitor-mt.dylib
    # libboost_prg_exec_monitor.dylib
    # libboost_process-mt.dylib
    # libboost_process.dylib
    # libboost_program_options-mt.dylib
    # libboost_program_options.dylib
    # libboost_random-mt.dylib
    # libboost_random.dylib
    # libboost_regex-mt.dylib
    # libboost_regex.dylib
    # libboost_serialization-mt.dylib
    # libboost_serialization.dylib
    # libboost_stacktrace_addr2line-mt.dylib
    # libboost_stacktrace_basic-mt.dylib
    # libboost_stacktrace_noop-mt.dylib
    # libboost_system-mt.dylib
    # libboost_thread-mt.dylib
    # libboost_timer-mt.dylib
    # libboost_timer.dylib
    # libboost_type_erasure-mt.dylib
    # libboost_unit_test_framework-mt.dylib
    # libboost_wave-mt.dylib
    # libboost_wserialization-mt.dylib
)


# Step 6: Validate the BOOST_DYNAMIC_LIBS variable.
# If the variable is not defined or is empty, a fatal error is thrown.
if(NOT DEFINED BOOST_DYNAMIC_LIBS OR "${BOOST_DYNAMIC_LIBS}" STREQUAL "")
    message(FATAL_ERROR "BOOST_DYNAMIC_LIBS is empty. Please define the required Boost libraries.")
else()
    # Step 7: Link the defined Boost libraries with the project.
    target_link_libraries(${PROJECT_NAME} PRIVATE ${BOOST_DYNAMIC_LIBS})
endif()

# That's all folks.

Enjoy!

いいなと思ったら応援しよう!